diff --git a/Cargo.lock b/Cargo.lock
index dca41144e8ef5f990c93b8c0096d513a77fdfd91..0f727d0e138e9a6f60d29f44e3c5998cd7a22254 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,9 +2,9 @@
 # It is not intended for manual editing.
 [[package]]
 name = "addr2line"
-version = "0.13.0"
+version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072"
+checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423"
 dependencies = [
  "gimli",
 ]
@@ -17,93 +17,39 @@ checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
 
 [[package]]
 name = "ahash"
-version = "0.3.8"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217"
+checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
 
 [[package]]
 name = "aho-corasick"
-version = "0.7.13"
+version = "0.7.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "043164d8ba5c4c3035fec9bbee8647c0261d788f3474306f93bb65901cae0e86"
+checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
 dependencies = [
  "memchr",
 ]
 
 [[package]]
-name = "arrayvec"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
-
-[[package]]
-name = "async-attributes"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "efd3d156917d94862e779f356c5acae312b08fd3121e792c857d7928c8088423"
-dependencies = [
- "quote 1.0.7",
- "syn 1.0.37",
-]
-
-[[package]]
-name = "async-channel"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43de69555a39d52918e2bc33a408d3c0a86c829b212d898f4ca25d21a6387478"
-dependencies = [
- "concurrent-queue",
- "event-listener",
- "futures-core",
-]
-
-[[package]]
-name = "async-std"
-version = "1.6.2"
+name = "async-trait"
+version = "0.1.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00d68a33ebc8b57800847d00787307f84a562224a14db069b0acefe4c2abbf5d"
+checksum = "8d3a45e77e34375a7923b1e8febb049bb011f064714a8e17a1a616fef01da13d"
 dependencies = [
- "async-attributes",
- "async-task",
- "crossbeam-utils",
- "futures-channel",
- "futures-core",
- "futures-io",
- "kv-log-macro",
- "log 0.4.11",
- "memchr",
- "num_cpus",
- "once_cell",
- "pin-project-lite",
- "pin-utils",
- "slab",
- "smol",
- "wasm-bindgen-futures",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
 ]
 
 [[package]]
-name = "async-task"
-version = "3.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c17772156ef2829aadc587461c7753af20b7e8db1529bc66855add962a3b35d3"
-
-[[package]]
-name = "async-trait"
-version = "0.1.36"
+name = "atomic"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a265e3abeffdce30b2e26b7a11b222fe37c6067404001b434101457d0385eb92"
+checksum = "c3410529e8288c463bedb5930f82833bc0c90e5d2fe639a56582a4d09220b281"
 dependencies = [
- "proc-macro2 1.0.19",
- "quote 1.0.7",
- "syn 1.0.37",
+ "autocfg 1.0.1",
 ]
 
-[[package]]
-name = "atomic-waker"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a"
-
 [[package]]
 name = "atty"
 version = "0.2.14"
@@ -123,18 +69,18 @@ checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
 
 [[package]]
 name = "autocfg"
-version = "1.0.0"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
+checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
 
 [[package]]
 name = "backtrace"
-version = "0.3.50"
+version = "0.3.55"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46254cf2fdcdf1badb5934448c1bcbe046a56537b3987d96c51a7afc5d03f293"
+checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598"
 dependencies = [
  "addr2line",
- "cfg-if",
+ "cfg-if 1.0.0",
  "libc",
  "miniz_oxide",
  "object",
@@ -143,19 +89,9 @@ dependencies = [
 
 [[package]]
 name = "base-x"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b20b618342cf9891c292c4f5ac2cde7287cc5c87e87e9c769d617793607dec1"
-
-[[package]]
-name = "base64"
-version = "0.9.3"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
-dependencies = [
- "byteorder",
- "safemem",
-]
+checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b"
 
 [[package]]
 name = "base64"
@@ -169,6 +105,12 @@ version = "0.12.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
 
+[[package]]
+name = "base64"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
+
 [[package]]
 name = "bcrypt"
 version = "0.8.2"
@@ -181,6 +123,12 @@ dependencies = [
  "getrandom",
 ]
 
+[[package]]
+name = "binascii"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72"
+
 [[package]]
 name = "bitfield"
 version = "0.13.2"
@@ -193,6 +141,18 @@ version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
 
+[[package]]
+name = "bitvec"
+version = "0.19.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7ba35e9565969edb811639dbebfe34edc0368e472c5018474c8eb2543397f81"
+dependencies = [
+ "funty",
+ "radium",
+ "tap",
+ "wyz",
+]
+
 [[package]]
 name = "block-buffer"
 version = "0.7.3"
@@ -223,20 +183,6 @@ dependencies = [
  "byte-tools",
 ]
 
-[[package]]
-name = "blocking"
-version = "0.4.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2468ff7bf85066b4a3678fede6fe66db31846d753ff0adfbfab2c6a6e81612b"
-dependencies = [
- "async-channel",
- "atomic-waker",
- "futures-lite",
- "once_cell",
- "parking",
- "waker-fn",
-]
-
 [[package]]
 name = "blowfish"
 version = "0.6.0"
@@ -264,12 +210,6 @@ dependencies = [
  "serde_json",
 ]
 
-[[package]]
-name = "bufstream"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8"
-
 [[package]]
 name = "bumpalo"
 version = "3.4.0"
@@ -304,17 +244,11 @@ version = "0.5.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
 
-[[package]]
-name = "cache-padded"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
-
 [[package]]
 name = "cc"
-version = "1.0.58"
+version = "1.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518"
+checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
 
 [[package]]
 name = "cfg-if"
@@ -322,17 +256,25 @@ version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
 
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
 [[package]]
 name = "chrono"
-version = "0.4.15"
+version = "0.4.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b"
+checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
 dependencies = [
  "js-sys",
+ "libc",
  "num-integer",
  "num-traits",
- "time 0.1.43",
+ "time 0.1.44",
  "wasm-bindgen",
+ "winapi 0.3.9",
 ]
 
 [[package]]
@@ -345,68 +287,80 @@ dependencies = [
 ]
 
 [[package]]
-name = "cloudabi"
-version = "0.1.0"
+name = "const_fn"
+version = "0.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467"
+checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826"
+
+[[package]]
+name = "cookie"
+version = "0.15.0-dev"
+source = "git+https://github.com/SergioBenitez/cookie-rs.git?rev=1c3ca83#1c3ca838543b60a4448d279dc4b903cc7a2bc22a"
 dependencies = [
- "bitflags",
+ "percent-encoding",
+ "time 0.2.23",
+ "version_check",
 ]
 
 [[package]]
-name = "concurrent-queue"
-version = "1.2.0"
+name = "core-foundation"
+version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e296417c8154304ac70aceda41f05318f986f7c0c767bcb0a2366fbb890e78e1"
+checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62"
 dependencies = [
- "cache-padded",
+ "core-foundation-sys",
+ "libc",
 ]
 
 [[package]]
-name = "cookie"
-version = "0.11.3"
+name = "core-foundation-sys"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5795cda0897252e34380a27baf884c53aa7ad9990329cdad96d4c5d027015d44"
-dependencies = [
- "percent-encoding 2.1.0",
- "time 0.1.43",
-]
+checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b"
 
 [[package]]
-name = "core-foundation"
+name = "crypto-mac"
 version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171"
+checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
 dependencies = [
- "core-foundation-sys",
- "libc",
+ "generic-array 0.12.3",
+ "subtle",
 ]
 
 [[package]]
-name = "core-foundation-sys"
-version = "0.7.0"
+name = "darling"
+version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
+checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
 
 [[package]]
-name = "crossbeam-utils"
-version = "0.7.2"
+name = "darling_core"
+version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
+checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b"
 dependencies = [
- "autocfg 1.0.0",
- "cfg-if",
- "lazy_static",
+ "fnv",
+ "ident_case",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "strsim 0.9.3",
+ "syn 1.0.56",
 ]
 
 [[package]]
-name = "crypto-mac"
-version = "0.7.0"
+name = "darling_macro"
+version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
+checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72"
 dependencies = [
- "generic-array 0.12.3",
- "subtle",
+ "darling_core",
+ "quote 1.0.8",
+ "syn 1.0.56",
 ]
 
 [[package]]
@@ -415,16 +369,15 @@ version = "2.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cb582b60359da160a9477ee80f15c8d784c477e69c217ef2cdd4169c24ea380f"
 dependencies = [
- "proc-macro2 1.0.19",
- "quote 1.0.7",
- "syn 1.0.37",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
 ]
 
 [[package]]
 name = "devise"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74e04ba2d03c5fa0d954c061fc8c9c288badadffc272ebb87679a89846de3ed3"
+version = "0.3.0"
+source = "git+https://github.com/SergioBenitez/Devise.git?rev=3648468#3648468a9ede9ca896cd35bc1eb818c7a9fb3047"
 dependencies = [
  "devise_codegen",
  "devise_core",
@@ -432,24 +385,23 @@ dependencies = [
 
 [[package]]
 name = "devise_codegen"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "066ceb7928ca93a9bedc6d0e612a8a0424048b0ab1f75971b203d01420c055d7"
+version = "0.3.0"
+source = "git+https://github.com/SergioBenitez/Devise.git?rev=3648468#3648468a9ede9ca896cd35bc1eb818c7a9fb3047"
 dependencies = [
  "devise_core",
- "quote 0.6.13",
+ "quote 1.0.8",
 ]
 
 [[package]]
 name = "devise_core"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf41c59b22b5e3ec0ea55c7847e5f358d340f3a8d6d53a5cf4f1564967f96487"
+version = "0.3.0"
+source = "git+https://github.com/SergioBenitez/Devise.git?rev=3648468#3648468a9ede9ca896cd35bc1eb818c7a9fb3047"
 dependencies = [
  "bitflags",
- "proc-macro2 0.4.30",
- "quote 0.6.13",
- "syn 0.15.44",
+ "proc-macro2 1.0.24",
+ "proc-macro2-diagnostics",
+ "quote 1.0.8",
+ "syn 1.0.56",
 ]
 
 [[package]]
@@ -474,30 +426,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
 
 [[package]]
-name = "dtoa"
-version = "0.4.6"
+name = "either"
+version = "1.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
+checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
 
 [[package]]
 name = "encoding_rs"
-version = "0.8.23"
+version = "0.8.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8ac63f94732332f44fe654443c46f6375d1939684c17b0afb6cb56b0456e171"
+checksum = "801bbab217d7f79c0062f4f7205b5d4427c6d1a7bd7aafdd1475f7c59d62b283"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
 ]
 
 [[package]]
 name = "enum-as-inner"
-version = "0.3.2"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc4bfcfacb61d231109d1d55202c1f33263319668b168843e02ad4652725ec9c"
+checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595"
 dependencies = [
  "heck",
- "proc-macro2 1.0.19",
- "quote 1.0.7",
- "syn 1.0.37",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
 ]
 
 [[package]]
@@ -508,7 +460,7 @@ checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
 dependencies = [
  "atty",
  "humantime",
- "log 0.4.11",
+ "log",
  "regex",
  "termcolor",
 ]
@@ -520,19 +472,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "22deed3a8124cff5fa835713fa105621e43bbdc46690c3a6b68328a012d350d4"
 dependencies = [
  "proc-macro-error",
- "proc-macro2 1.0.19",
- "quote 1.0.7",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
  "rustversion",
- "syn 1.0.37",
+ "syn 1.0.56",
  "synstructure",
 ]
 
-[[package]]
-name = "event-listener"
-version = "2.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "298f00c3b04c1d9b4cb86aefaaa35348af0957d98b30a5306fc635f8e718923d"
-
 [[package]]
 name = "fake-simd"
 version = "0.1.2"
@@ -540,21 +486,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
 
 [[package]]
-name = "fastrand"
-version = "1.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36a9cb09840f81cd211e435d00a4e487edd263dc3c8ff815c32dd76ad668ebed"
-
-[[package]]
-name = "filetime"
-version = "0.2.12"
+name = "figment"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ed85775dcc68644b5c950ac06a2b23768d3bc9390464151aaf27136998dcf9e"
+checksum = "f273b2f81f067bb5553f562feb98794d6c704f049d333f920d69211965a30448"
 dependencies = [
- "cfg-if",
- "libc",
- "redox_syscall",
- "winapi 0.3.9",
+ "pear",
+ "serde",
+ "toml",
+ "uncased",
+ "version_check",
 ]
 
 [[package]]
@@ -579,22 +520,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
 
 [[package]]
-name = "fsevent"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6"
-dependencies = [
- "bitflags",
- "fsevent-sys",
-]
-
-[[package]]
-name = "fsevent-sys"
-version = "2.0.1"
+name = "form_urlencoded"
+version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0"
+checksum = "ece68d15c92e84fa4f19d3780f1294e5ca82a78a6d515f1efaabcc144688be00"
 dependencies = [
- "libc",
+ "matches",
+ "percent-encoding",
 ]
 
 [[package]]
@@ -619,11 +551,17 @@ version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 
+[[package]]
+name = "funty"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
+
 [[package]]
 name = "futures"
-version = "0.3.5"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613"
+checksum = "9b3b0c040a1fe6529d30b3c5944b280c7f0dcb2930d2c3062bca967b602583d0"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -636,9 +574,9 @@ dependencies = [
 
 [[package]]
 name = "futures-channel"
-version = "0.3.5"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5"
+checksum = "4b7109687aa4e177ef6fe84553af6280ef2778bdb7783ba44c9dc3399110fe64"
 dependencies = [
  "futures-core",
  "futures-sink",
@@ -646,15 +584,15 @@ dependencies = [
 
 [[package]]
 name = "futures-core"
-version = "0.3.5"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399"
+checksum = "847ce131b72ffb13b6109a221da9ad97a64cbe48feb1028356b836b47b8f1748"
 
 [[package]]
 name = "futures-executor"
-version = "0.3.5"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314"
+checksum = "4caa2b2b68b880003057c1dd49f1ed937e38f22fcf6c212188a121f08cf40a65"
 dependencies = [
  "futures-core",
  "futures-task",
@@ -674,57 +612,42 @@ dependencies = [
 
 [[package]]
 name = "futures-io"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
-
-[[package]]
-name = "futures-lite"
-version = "0.1.10"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbe71459749b2e8e66fb95df721b22fa08661ad384a0c5b519e11d3893b4692a"
-dependencies = [
- "fastrand",
- "futures-core",
- "futures-io",
- "memchr",
- "parking",
- "pin-project-lite",
- "waker-fn",
-]
+checksum = "611834ce18aaa1bd13c4b374f5d653e1027cf99b6b502584ff8c9a64413b30bb"
 
 [[package]]
 name = "futures-macro"
-version = "0.3.5"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39"
+checksum = "77408a692f1f97bcc61dc001d752e00643408fbc922e4d634c655df50d595556"
 dependencies = [
  "proc-macro-hack",
- "proc-macro2 1.0.19",
- "quote 1.0.7",
- "syn 1.0.37",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
 ]
 
 [[package]]
 name = "futures-sink"
-version = "0.3.5"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc"
+checksum = "f878195a49cee50e006b02b93cf7e0a95a38ac7b776b4c4d9cc1207cd20fcb3d"
 
 [[package]]
 name = "futures-task"
-version = "0.3.5"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626"
+checksum = "7c554eb5bf48b2426c4771ab68c6b14468b6e76cc90996f528c3338d761a4d0d"
 dependencies = [
  "once_cell",
 ]
 
 [[package]]
 name = "futures-util"
-version = "0.3.5"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
+checksum = "d304cff4a7b99cfb7986f7d43fbe93d175e72e704a8860787cc95e9ffd85cbd2"
 dependencies = [
  "futures-channel",
  "futures-core",
@@ -733,7 +656,7 @@ dependencies = [
  "futures-sink",
  "futures-task",
  "memchr",
- "pin-project",
+ "pin-project 1.0.2",
  "pin-utils",
  "proc-macro-hack",
  "proc-macro-nested",
@@ -756,25 +679,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
 dependencies = [
  "typenum",
- "version_check 0.9.2",
+ "version_check",
 ]
 
 [[package]]
 name = "getrandom"
-version = "0.1.14"
+version = "0.1.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
+checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
 dependencies = [
- "cfg-if",
+ "cfg-if 0.1.10",
  "libc",
- "wasi",
+ "wasi 0.9.0+wasi-snapshot-preview1",
 ]
 
 [[package]]
 name = "gimli"
-version = "0.22.0"
+version = "0.23.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
+checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
 
 [[package]]
 name = "glob"
@@ -784,9 +707,9 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
 
 [[package]]
 name = "h2"
-version = "0.2.6"
+version = "0.2.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "993f9e0baeed60001cf565546b0d3dbe6a6ad23f2bd31644a133c641eccf6d53"
+checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535"
 dependencies = [
  "bytes 0.5.6",
  "fnv",
@@ -799,32 +722,32 @@ dependencies = [
  "tokio",
  "tokio-util",
  "tracing",
+ "tracing-futures",
 ]
 
 [[package]]
 name = "hashbrown"
-version = "0.8.2"
+version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25"
+checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
 dependencies = [
  "ahash",
- "autocfg 1.0.0",
 ]
 
 [[package]]
 name = "heck"
-version = "0.3.1"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
+checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac"
 dependencies = [
  "unicode-segmentation",
 ]
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.15"
+version = "0.1.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9"
+checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8"
 dependencies = [
  "libc",
 ]
@@ -837,10 +760,11 @@ checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
 
 [[package]]
 name = "hive_pubsub"
-version = "0.3.1"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2b08d5028b638db3f5eb475dc7c5e5aad1b0a5b4f737b2c394883034330853e"
+checksum = "10a9804dd748a82752283c672f906611ae273b59386d67dd349decf1b382fdb4"
 dependencies = [
+ "futures",
  "many-to-many",
  "mongodb",
  "serde",
@@ -871,9 +795,9 @@ dependencies = [
 
 [[package]]
 name = "http"
-version = "0.2.1"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9"
+checksum = "84129d298a6d57d246960ff8eb831ca4af3f96d29e2e28848dae275408658e26"
 dependencies = [
  "bytes 0.5.6",
  "fnv",
@@ -896,6 +820,12 @@ version = "1.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
 
+[[package]]
+name = "httpdate"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47"
+
 [[package]]
 name = "humantime"
 version = "1.3.0"
@@ -907,28 +837,9 @@ dependencies = [
 
 [[package]]
 name = "hyper"
-version = "0.10.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273"
-dependencies = [
- "base64 0.9.3",
- "httparse",
- "language-tags",
- "log 0.3.9",
- "mime 0.2.6",
- "num_cpus",
- "time 0.1.43",
- "traitobject",
- "typeable",
- "unicase 1.4.2",
- "url 1.7.2",
-]
-
-[[package]]
-name = "hyper"
-version = "0.13.7"
+version = "0.13.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e68a8dd9716185d9e64ea473ea6ef63529252e3e27623295a0378a19665d5eb"
+checksum = "f6ad767baac13b44d4529fcf58ba2cd0995e36e7b435bc5b039de6f47e880dbf"
 dependencies = [
  "bytes 0.5.6",
  "futures-channel",
@@ -938,16 +849,32 @@ dependencies = [
  "http",
  "http-body",
  "httparse",
+ "httpdate",
  "itoa",
- "pin-project",
+ "pin-project 1.0.2",
  "socket2",
- "time 0.1.43",
  "tokio",
  "tower-service",
  "tracing",
  "want",
 ]
 
+[[package]]
+name = "hyper-rustls"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "37743cc83e8ee85eacfce90f2f4102030d9ff0a95244098d781e9bee4a90abb6"
+dependencies = [
+ "bytes 0.5.6",
+ "futures-util",
+ "hyper",
+ "log",
+ "rustls 0.18.1",
+ "tokio",
+ "tokio-rustls 0.14.1",
+ "webpki",
+]
+
 [[package]]
 name = "hyper-tls"
 version = "0.4.3"
@@ -955,7 +882,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d979acc56dcb5b8dddba3917601745e877576475aa046df3226eabdecef78eed"
 dependencies = [
  "bytes 0.5.6",
- "hyper 0.13.7",
+ "hyper",
  "native-tls",
  "tokio",
  "tokio-tls",
@@ -963,32 +890,27 @@ dependencies = [
 
 [[package]]
 name = "hyperx"
-version = "1.1.0"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9eae1ec4abdc4530fb001ebf585fd14e52ed17f0aacd3e13de497b71ed451750"
+checksum = "2adce67e2c21cd95288ae3d9f2bbb2762cf17c03744628d49679f315ed1e2e58"
 dependencies = [
- "base64 0.12.3",
+ "base64 0.13.0",
  "bytes 0.5.6",
  "http",
  "httparse",
+ "httpdate",
  "language-tags",
- "log 0.4.11",
- "mime 0.3.16",
- "percent-encoding 2.1.0",
- "time 0.1.43",
- "unicase 2.6.0",
+ "log",
+ "mime",
+ "percent-encoding",
+ "unicase",
 ]
 
 [[package]]
-name = "idna"
-version = "0.1.5"
+name = "ident_case"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
-dependencies = [
- "matches",
- "unicode-bidi",
- "unicode-normalization",
-]
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
 
 [[package]]
 name = "idna"
@@ -1003,40 +925,29 @@ dependencies = [
 
 [[package]]
 name = "indexmap"
-version = "1.5.0"
+version = "1.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b88cd59ee5f71fea89a62248fc8f387d44400cefe05ef548466d61ced9029a7"
+checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b"
 dependencies = [
- "autocfg 1.0.0",
+ "autocfg 1.0.1",
  "hashbrown",
 ]
 
 [[package]]
-name = "inotify"
-version = "0.7.1"
+name = "inlinable_string"
+version = "0.1.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f"
-dependencies = [
- "bitflags",
- "inotify-sys",
- "libc",
-]
+checksum = "3094308123a0e9fd59659ce45e22de9f53fc1d2ac6e1feb9fef988e4f76cad77"
 
 [[package]]
-name = "inotify-sys"
-version = "0.1.3"
+name = "instant"
+version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0"
+checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
 dependencies = [
- "libc",
+ "cfg-if 1.0.0",
 ]
 
-[[package]]
-name = "instant"
-version = "0.1.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b141fdc7836c525d4d594027d318c84161ca17aaf8113ab1f81ab93ae897485"
-
 [[package]]
 name = "iovec"
 version = "0.1.4"
@@ -1072,9 +983,9 @@ checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
 
 [[package]]
 name = "js-sys"
-version = "0.3.44"
+version = "0.3.46"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85a7e2c92a4804dd459b86c339278d0fe87cf93757fae222c3fa3ae75458bc73"
+checksum = "cf3d7383929f7c9c7c2d0fa596f325832df98c3704f2c60553080f7127a58175"
 dependencies = [
  "wasm-bindgen",
 ]
@@ -1089,15 +1000,6 @@ dependencies = [
  "winapi-build",
 ]
 
-[[package]]
-name = "kv-log-macro"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
-dependencies = [
- "log 0.4.11",
-]
-
 [[package]]
 name = "language-tags"
 version = "0.2.2"
@@ -1112,64 +1014,38 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
 name = "lazycell"
-version = "1.2.1"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
+checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
 
 [[package]]
 name = "lettre"
-version = "0.10.0-alpha.1"
+version = "0.10.0-alpha.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "deaf9b74d40fcb52d0f762eb08e45d5152b4db59d29bb73edd4cac7fe796862c"
+checksum = "dc8c2fc7873920aca23647e5e86d44ff3f40bbc5a5efaab445c9eb0e001c9f71"
 dependencies = [
- "base64 0.12.3",
- "bufstream",
+ "base64 0.13.0",
  "hostname",
  "hyperx",
- "idna 0.2.0",
- "line-wrap",
- "mime 0.3.16",
+ "idna",
+ "mime",
+ "native-tls",
  "nom",
  "once_cell",
  "quoted_printable",
  "r2d2",
+ "rand 0.7.3",
  "regex",
- "rustls",
  "serde",
  "serde_json",
- "textnonce",
  "uuid",
- "webpki",
- "webpki-roots 0.19.0",
-]
-
-[[package]]
-name = "lexical-core"
-version = "0.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db65c6da02e61f55dae90a0ae427b2a5f6b3e8db09f58d10efab23af92592616"
-dependencies = [
- "arrayvec",
- "bitflags",
- "cfg-if",
- "ryu",
- "static_assertions",
 ]
 
 [[package]]
 name = "libc"
-version = "0.2.74"
+version = "0.2.81"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10"
-
-[[package]]
-name = "line-wrap"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f30344350a2a51da54c1d53be93fade8a237e545dbcc4bdbe635413f2117cab9"
-dependencies = [
- "safemem",
-]
+checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
 
 [[package]]
 name = "linked-hash-map"
@@ -1188,36 +1064,27 @@ dependencies = [
 
 [[package]]
 name = "lock_api"
-version = "0.4.1"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c"
+checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312"
 dependencies = [
  "scopeguard",
 ]
 
-[[package]]
-name = "log"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
-dependencies = [
- "log 0.4.11",
-]
-
 [[package]]
 name = "log"
 version = "0.4.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
 dependencies = [
- "cfg-if",
+ "cfg-if 0.1.10",
 ]
 
 [[package]]
 name = "lru"
-version = "0.6.0"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "111b945ac72ec09eb7bc62a0fbdc3cc6e80555a7245f52a69d3921a75b53b153"
+checksum = "3aae342b73d57ad0b8b364bd12584819f2c1fe9114285dfcf8b0722607671635"
 dependencies = [
  "hashbrown",
 ]
@@ -1233,9 +1100,9 @@ dependencies = [
 
 [[package]]
 name = "many-to-many"
-version = "0.1.2"
+version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28806b11671f3ae32bfcacf1948d77af5bddf1aa4ac518207615f11abe31df19"
+checksum = "ff2806c88ab7215e5077fbaaf21a9baaab9caa2abd7adf6c0f63b535ad747547"
 
 [[package]]
 name = "match_cfg"
@@ -1262,18 +1129,9 @@ dependencies = [
 
 [[package]]
 name = "memchr"
-version = "2.3.3"
+version = "2.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
-
-[[package]]
-name = "mime"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0"
-dependencies = [
- "log 0.3.9",
-]
+checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
 
 [[package]]
 name = "mime"
@@ -1287,32 +1145,33 @@ version = "2.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212"
 dependencies = [
- "mime 0.3.16",
- "unicase 2.6.0",
+ "mime",
+ "unicase",
 ]
 
 [[package]]
 name = "miniz_oxide"
-version = "0.4.0"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be0f75932c1f6cfae3c04000e40114adf955636e19040f9c0a2c380702aa1c7f"
+checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
 dependencies = [
  "adler",
+ "autocfg 1.0.1",
 ]
 
 [[package]]
 name = "mio"
-version = "0.6.22"
+version = "0.6.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430"
+checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4"
 dependencies = [
- "cfg-if",
+ "cfg-if 0.1.10",
  "fuchsia-zircon",
  "fuchsia-zircon-sys",
  "iovec",
  "kernel32-sys",
  "libc",
- "log 0.4.11",
+ "log",
  "miow",
  "net2",
  "slab",
@@ -1326,16 +1185,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
 dependencies = [
  "lazycell",
- "log 0.4.11",
+ "log",
  "mio",
  "slab",
 ]
 
+[[package]]
+name = "mio-uds"
+version = "0.6.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
+dependencies = [
+ "iovec",
+ "libc",
+ "mio",
+]
+
 [[package]]
 name = "miow"
-version = "0.2.1"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
+checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d"
 dependencies = [
  "kernel32-sys",
  "net2",
@@ -1349,7 +1219,6 @@ version = "1.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a726495d7418c4579ecc9465b53ddade8187c0299e5db0e7250672b67d196913"
 dependencies = [
- "async-std",
  "async-trait",
  "base64 0.11.0",
  "bitflags",
@@ -1365,38 +1234,40 @@ dependencies = [
  "md-5",
  "os_info",
  "pbkdf2",
- "percent-encoding 2.1.0",
+ "percent-encoding",
  "rand 0.7.3",
- "rustls",
+ "reqwest",
+ "rustls 0.17.0",
  "serde",
+ "serde_bytes",
  "serde_with",
  "sha-1",
  "sha2",
  "socket2",
  "stringprep",
- "strsim",
+ "strsim 0.10.0",
  "take_mut",
- "time 0.1.43",
+ "time 0.1.44",
  "tokio",
- "tokio-rustls",
+ "tokio-rustls 0.13.1",
  "trust-dns-proto",
  "trust-dns-resolver",
  "typed-builder",
  "uuid",
- "version_check 0.9.2",
+ "version_check",
  "webpki",
  "webpki-roots 0.18.0",
 ]
 
 [[package]]
 name = "native-tls"
-version = "0.2.4"
+version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b0d88c06fe90d5ee94048ba40409ef1d9315d86f6f38c2efdaad4fb50c58b2d"
+checksum = "6fcc7939b5edc4e4f86b1b4a04bb1498afaaf871b1a6691838ed06fcb48d3a3f"
 dependencies = [
  "lazy_static",
  "libc",
- "log 0.4.11",
+ "log",
  "openssl",
  "openssl-probe",
  "openssl-sys",
@@ -1408,61 +1279,43 @@ dependencies = [
 
 [[package]]
 name = "net2"
-version = "0.2.34"
+version = "0.2.37"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7"
+checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae"
 dependencies = [
- "cfg-if",
+ "cfg-if 0.1.10",
  "libc",
  "winapi 0.3.9",
 ]
 
 [[package]]
 name = "nom"
-version = "5.1.2"
+version = "6.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
+checksum = "88034cfd6b4a0d54dd14f4a507eceee36c0b70e5a02236c4e4df571102be17f0"
 dependencies = [
- "lexical-core",
+ "bitvec",
  "memchr",
- "version_check 0.9.2",
-]
-
-[[package]]
-name = "notify"
-version = "4.0.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd"
-dependencies = [
- "bitflags",
- "filetime",
- "fsevent",
- "fsevent-sys",
- "inotify",
- "libc",
- "mio",
- "mio-extras",
- "walkdir",
- "winapi 0.3.9",
+ "version_check",
 ]
 
 [[package]]
 name = "num-integer"
-version = "0.1.43"
+version = "0.1.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
+checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
 dependencies = [
- "autocfg 1.0.0",
+ "autocfg 1.0.1",
  "num-traits",
 ]
 
 [[package]]
 name = "num-traits"
-version = "0.2.12"
+version = "0.2.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
+checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
 dependencies = [
- "autocfg 1.0.0",
+ "autocfg 1.0.1",
 ]
 
 [[package]]
@@ -1492,22 +1345,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1c0fd9eba1d5db0994a239e09c1be402d35622277e35468ba891aa5e3188ce7e"
 dependencies = [
  "proc-macro-crate",
- "proc-macro2 1.0.19",
- "quote 1.0.7",
- "syn 1.0.37",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
 ]
 
 [[package]]
 name = "object"
-version = "0.20.0"
+version = "0.22.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5"
+checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
 
 [[package]]
 name = "once_cell"
-version = "1.4.1"
+version = "1.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad"
+checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
 
 [[package]]
 name = "opaque-debug"
@@ -1523,12 +1376,12 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
 
 [[package]]
 name = "openssl"
-version = "0.10.30"
+version = "0.10.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4"
+checksum = "038d43985d1ddca7a9900630d8cd031b56e4794eecc2e9ea39dd17aa04399a70"
 dependencies = [
  "bitflags",
- "cfg-if",
+ "cfg-if 1.0.0",
  "foreign-types",
  "lazy_static",
  "libc",
@@ -1543,11 +1396,11 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
 
 [[package]]
 name = "openssl-sys"
-version = "0.9.58"
+version = "0.9.60"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de"
+checksum = "921fc71883267538946025deffb622905ecad223c28efbfdef9bb59a0175f3e6"
 dependencies = [
- "autocfg 1.0.0",
+ "autocfg 1.0.1",
  "cc",
  "libc",
  "pkg-config",
@@ -1556,20 +1409,14 @@ dependencies = [
 
 [[package]]
 name = "os_info"
-version = "2.0.7"
+version = "2.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0b045a2b6649afa9234ff4f40f84b2ea6e9bdc1a370ad9c03830c597b435953"
+checksum = "d2cc1b4330bb29087e791ae2a5cf56be64fb8946a4ff5aec2ba11c6ca51f5d60"
 dependencies = [
- "log 0.4.11",
+ "log",
  "winapi 0.3.9",
 ]
 
-[[package]]
-name = "parking"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6cb300f271742d4a2a66c01b6b2fa0c83dfebd2e0bf11addb879a3547b4ed87c"
-
 [[package]]
 name = "parking_lot"
 version = "0.10.2"
@@ -1582,13 +1429,13 @@ dependencies = [
 
 [[package]]
 name = "parking_lot"
-version = "0.11.0"
+version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733"
+checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
 dependencies = [
  "instant",
- "lock_api 0.4.1",
- "parking_lot_core 0.8.0",
+ "lock_api 0.4.2",
+ "parking_lot_core 0.8.2",
 ]
 
 [[package]]
@@ -1597,8 +1444,8 @@ version = "0.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3"
 dependencies = [
- "cfg-if",
- "cloudabi 0.0.3",
+ "cfg-if 0.1.10",
+ "cloudabi",
  "libc",
  "redox_syscall",
  "smallvec",
@@ -1607,12 +1454,11 @@ dependencies = [
 
 [[package]]
 name = "parking_lot_core"
-version = "0.8.0"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b"
+checksum = "9ccb628cad4f84851442432c60ad8e1f607e29752d0bf072cbd0baf28aa34272"
 dependencies = [
- "cfg-if",
- "cloudabi 0.1.0",
+ "cfg-if 1.0.0",
  "instant",
  "libc",
  "redox_syscall",
@@ -1632,63 +1478,84 @@ dependencies = [
 
 [[package]]
 name = "pear"
-version = "0.1.4"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5320f212db967792b67cfe12bd469d08afd6318a249bd917d5c19bc92200ab8a"
+checksum = "09f612cbd0f9dd03f5dd28a191c48e4148c3b027e41207b32eee130373c6c941"
 dependencies = [
+ "inlinable_string",
  "pear_codegen",
+ "yansi",
 ]
 
 [[package]]
 name = "pear_codegen"
-version = "0.1.4"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfc1c836fdc3d1ef87c348b237b5b5c4dff922156fb2d968f57734f9669768ca"
+checksum = "602cf1780ee9bbca663ea75769e05643e16fe87d7c8ac9f4f385a2ed8940a75c"
 dependencies = [
- "proc-macro2 0.4.30",
- "quote 0.6.13",
- "syn 0.15.44",
- "version_check 0.9.2",
- "yansi",
+ "proc-macro2 1.0.24",
+ "proc-macro2-diagnostics",
+ "quote 1.0.8",
+ "syn 1.0.56",
 ]
 
 [[package]]
 name = "percent-encoding"
-version = "1.0.1"
+version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
+checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
 
 [[package]]
-name = "percent-encoding"
-version = "2.1.0"
+name = "pin-project"
+version = "0.4.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2ffbc8e94b38ea3d2d8ba92aea2983b503cd75d0888d75b86bb37970b5698e15"
+dependencies = [
+ "pin-project-internal 0.4.27",
+]
+
+[[package]]
+name = "pin-project"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
+checksum = "9ccc2237c2c489783abd8c4c80e5450fc0e98644555b1364da68cc29aa151ca7"
+dependencies = [
+ "pin-project-internal 1.0.2",
+]
 
 [[package]]
-name = "pin-project"
-version = "0.4.23"
+name = "pin-project-internal"
+version = "0.4.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca4433fff2ae79342e497d9f8ee990d174071408f28f726d6d83af93e58e48aa"
+checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895"
 dependencies = [
- "pin-project-internal",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
 ]
 
 [[package]]
 name = "pin-project-internal"
-version = "0.4.23"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c0e815c3ee9a031fdf5af21c10aa17c573c9c6a566328d99e3936c34e36461f"
+checksum = "f8e8d2bf0b23038a4424865103a4df472855692821aab4e4f5c3312d461d9e5f"
 dependencies = [
- "proc-macro2 1.0.19",
- "quote 1.0.7",
- "syn 1.0.37",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
 ]
 
 [[package]]
 name = "pin-project-lite"
-version = "0.1.7"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b"
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715"
+checksum = "6b063f57ec186e6140e2b8b6921e5f1bd89c7356dda5b33acc5401203ca6131c"
 
 [[package]]
 name = "pin-utils"
@@ -1698,15 +1565,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
 [[package]]
 name = "pkg-config"
-version = "0.3.18"
+version = "0.3.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d36492546b6af1463394d46f0c834346f31548646f6ba10849802c9c9a27ac33"
+checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
 
 [[package]]
 name = "ppv-lite86"
-version = "0.2.8"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea"
+checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
 
 [[package]]
 name = "proc-macro-crate"
@@ -1714,7 +1581,7 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785"
 dependencies = [
- "toml 0.5.6",
+ "toml",
 ]
 
 [[package]]
@@ -1724,10 +1591,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
 dependencies = [
  "proc-macro-error-attr",
- "proc-macro2 1.0.19",
- "quote 1.0.7",
- "syn 1.0.37",
- "version_check 0.9.2",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
+ "version_check",
 ]
 
 [[package]]
@@ -1736,16 +1603,16 @@ version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
 dependencies = [
- "proc-macro2 1.0.19",
- "quote 1.0.7",
- "version_check 0.9.2",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "version_check",
 ]
 
 [[package]]
 name = "proc-macro-hack"
-version = "0.5.18"
+version = "0.5.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598"
+checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
 
 [[package]]
 name = "proc-macro-nested"
@@ -1764,13 +1631,26 @@ dependencies = [
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.19"
+version = "1.0.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
+checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
 dependencies = [
  "unicode-xid 0.2.1",
 ]
 
+[[package]]
+name = "proc-macro2-diagnostics"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada"
+dependencies = [
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
+ "version_check",
+ "yansi",
+]
+
 [[package]]
 name = "quick-error"
 version = "1.2.3"
@@ -1788,11 +1668,11 @@ dependencies = [
 
 [[package]]
 name = "quote"
-version = "1.0.7"
+version = "1.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
+checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
 dependencies = [
- "proc-macro2 1.0.19",
+ "proc-macro2 1.0.24",
 ]
 
 [[package]]
@@ -1807,11 +1687,17 @@ version = "0.8.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "545c5bc2b880973c9c10e4067418407a0ccaa3091781d1671d46eb35107cb26f"
 dependencies = [
- "log 0.4.11",
- "parking_lot 0.11.0",
+ "log",
+ "parking_lot 0.11.1",
  "scheduled-thread-pool",
 ]
 
+[[package]]
+name = "radium"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
+
 [[package]]
 name = "rand"
 version = "0.6.5"
@@ -1932,7 +1818,7 @@ version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
 dependencies = [
- "cloudabi 0.0.3",
+ "cloudabi",
  "fuchsia-cprng",
  "libc",
  "rand_core 0.4.2",
@@ -1975,11 +1861,31 @@ version = "0.1.57"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
 
+[[package]]
+name = "ref-cast"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e17626b2f4bcf35b84bf379072a66e28cfe5c3c6ae58b38e4914bb8891dabece"
+dependencies = [
+ "ref-cast-impl",
+]
+
+[[package]]
+name = "ref-cast-impl"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c523ccaed8ac4b0288948849a350b37d3035827413c458b6a40ddb614bb4f72"
+dependencies = [
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
+]
+
 [[package]]
 name = "regex"
-version = "1.3.9"
+version = "1.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c3780fcf44b193bc4d09f36d2a3c87b251da4a046c87795a0d35f4f927ad8e6"
+checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -1989,9 +1895,9 @@ dependencies = [
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.18"
+version = "0.6.21"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
+checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
 
 [[package]]
 name = "remove_dir_all"
@@ -2004,45 +1910,49 @@ dependencies = [
 
 [[package]]
 name = "reqwest"
-version = "0.10.8"
+version = "0.10.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9eaa17ac5d7b838b7503d118fa16ad88f440498bf9ffe5424e621f93190d61e"
+checksum = "0718f81a8e14c4dbb3b34cf23dc6aaf9ab8a0dfec160c534b3dbca1aaa21f47c"
 dependencies = [
- "base64 0.12.3",
+ "base64 0.13.0",
  "bytes 0.5.6",
  "encoding_rs",
  "futures-core",
  "futures-util",
  "http",
  "http-body",
- "hyper 0.13.7",
+ "hyper",
+ "hyper-rustls",
  "hyper-tls",
  "ipnet",
  "js-sys",
  "lazy_static",
- "log 0.4.11",
- "mime 0.3.16",
+ "log",
+ "mime",
  "mime_guess",
  "native-tls",
- "percent-encoding 2.1.0",
- "pin-project-lite",
+ "percent-encoding",
+ "pin-project-lite 0.2.0",
+ "rustls 0.18.1",
  "serde",
  "serde_json",
  "serde_urlencoded",
  "tokio",
+ "tokio-rustls 0.14.1",
  "tokio-tls",
- "url 2.1.1",
+ "url",
  "wasm-bindgen",
  "wasm-bindgen-futures",
  "web-sys",
+ "webpki-roots 0.20.0",
  "winreg 0.7.0",
 ]
 
 [[package]]
 name = "resolv-conf"
-version = "0.6.3"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11834e137f3b14e309437a8276714eed3a80d1ef894869e510f2c0c0b98b9f4a"
+checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00"
 dependencies = [
  "hostname",
  "quick-error",
@@ -2057,11 +1967,10 @@ dependencies = [
  "chrono",
  "dotenv",
  "env_logger",
- "hashbrown",
  "hive_pubsub",
  "lazy_static",
  "lettre",
- "log 0.4.11",
+ "log",
  "lru",
  "many-to-many",
  "mongodb",
@@ -2074,7 +1983,8 @@ dependencies = [
  "rocket_cors",
  "serde",
  "serde_json",
- "time 0.2.16",
+ "time 0.2.23",
+ "tokio",
  "ulid",
  "validator",
  "ws",
@@ -2082,9 +1992,9 @@ dependencies = [
 
 [[package]]
 name = "ring"
-version = "0.16.15"
+version = "0.16.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "952cd6b98c85bbc30efa1ba5783b8abf12fec8b3287ffa52605b9432313e34e4"
+checksum = "024a1e66fea74c66c66624ee5622a7ff0e4b73a13b4f5c326ddb50c708944226"
 dependencies = [
  "cc",
  "libc",
@@ -2097,91 +2007,102 @@ dependencies = [
 
 [[package]]
 name = "rocket"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6130967b369cfb8411b0b73e96fcba1229c32a9cc6f295d144f879bfced13c6e"
+version = "0.5.0-dev"
+source = "git+https://github.com/SergioBenitez/Rocket#9671115796e42865eaebd020ac27542802027b02"
 dependencies = [
+ "async-trait",
+ "atomic",
  "atty",
- "base64 0.12.3",
- "log 0.4.11",
+ "binascii",
+ "either",
+ "figment",
+ "futures",
+ "log",
  "memchr",
  "num_cpus",
- "pear",
+ "parking_lot 0.11.1",
+ "rand 0.7.3",
+ "ref-cast",
  "rocket_codegen",
  "rocket_http",
+ "serde",
  "state",
- "time 0.1.43",
- "toml 0.4.10",
- "version_check 0.9.2",
+ "time 0.2.23",
+ "tokio",
+ "ubyte",
+ "version_check",
  "yansi",
 ]
 
 [[package]]
 name = "rocket_codegen"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb852e6da168fb948a8f2b798ba2e2f0e4fc860eae0efa9cf2bf0f5466bb0425"
+version = "0.5.0-dev"
+source = "git+https://github.com/SergioBenitez/Rocket#9671115796e42865eaebd020ac27542802027b02"
 dependencies = [
  "devise",
  "glob",
  "indexmap",
- "quote 0.6.13",
+ "quote 1.0.8",
  "rocket_http",
- "version_check 0.9.2",
- "yansi",
 ]
 
 [[package]]
 name = "rocket_contrib"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3946ca815127041d8f64455561031d058c22ae1b135251502c5ea523cf9e14b"
+version = "0.5.0-dev"
+source = "git+https://github.com/SergioBenitez/Rocket#9671115796e42865eaebd020ac27542802027b02"
 dependencies = [
- "log 0.4.11",
- "notify",
+ "log",
  "rocket",
  "serde",
  "serde_json",
+ "tokio",
 ]
 
 [[package]]
 name = "rocket_cors"
 version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea20696dc46308d0ca06222905fe38e02b8e46c087af9c82ea85cdc386271076"
+source = "git+https://github.com/lawliet89/rocket_cors#305971023d0edf29d10bf5af1d385481b0b5245f"
 dependencies = [
- "log 0.4.11",
+ "log",
  "regex",
  "rocket",
  "serde",
  "serde_derive",
- "unicase 2.6.0",
+ "unicase",
  "unicase_serde",
- "url 2.1.1",
+ "url",
 ]
 
 [[package]]
 name = "rocket_http"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1aff5a5480175f2f553a876b251e9350c74196128806d176da3a51c82aab5428"
+version = "0.5.0-dev"
+source = "git+https://github.com/SergioBenitez/Rocket#9671115796e42865eaebd020ac27542802027b02"
 dependencies = [
  "cookie",
- "hyper 0.10.16",
+ "either",
+ "http",
+ "hyper",
  "indexmap",
+ "log",
+ "mime",
+ "parking_lot 0.11.1",
  "pear",
- "percent-encoding 1.0.1",
+ "percent-encoding",
+ "ref-cast",
  "smallvec",
  "state",
- "time 0.1.43",
- "unicode-xid 0.1.0",
+ "time 0.2.23",
+ "tokio",
+ "uncased",
+ "unicode-xid 0.2.1",
+ "version_check",
 ]
 
 [[package]]
 name = "rustc-demangle"
-version = "0.1.16"
+version = "0.1.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
+checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
 
 [[package]]
 name = "rustc_version"
@@ -2199,43 +2120,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c0d4a31f5d68413404705d6982529b0e11a9aacd4839d1d6222ee3b8cb4015e1"
 dependencies = [
  "base64 0.11.0",
- "log 0.4.11",
+ "log",
  "ring",
  "sct",
  "webpki",
 ]
 
 [[package]]
-name = "rustversion"
-version = "1.0.3"
+name = "rustls"
+version = "0.18.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9bdc5e856e51e685846fb6c13a1f5e5432946c2c90501bdc76a1319f19e29da"
+checksum = "5d1126dcf58e93cee7d098dbda643b5f92ed724f1f6a63007c1116eed6700c81"
 dependencies = [
- "proc-macro2 1.0.19",
- "quote 1.0.7",
- "syn 1.0.37",
+ "base64 0.12.3",
+ "log",
+ "ring",
+ "sct",
+ "webpki",
 ]
 
 [[package]]
-name = "ryu"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
-
-[[package]]
-name = "safemem"
-version = "0.3.3"
+name = "rustversion"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
+checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd"
 
 [[package]]
-name = "same-file"
-version = "1.0.6"
+name = "ryu"
+version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
-dependencies = [
- "winapi-util",
-]
+checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
 
 [[package]]
 name = "schannel"
@@ -2253,15 +2167,9 @@ version = "0.2.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dc6f74fd1204073fa02d5d5d68bec8021be4c38690b61264b2fdb48083d0e7d7"
 dependencies = [
- "parking_lot 0.11.0",
+ "parking_lot 0.11.1",
 ]
 
-[[package]]
-name = "scoped-tls"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
-
 [[package]]
 name = "scopeguard"
 version = "1.1.0"
@@ -2280,9 +2188,9 @@ dependencies = [
 
 [[package]]
 name = "security-framework"
-version = "0.4.4"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535"
+checksum = "c1759c2e3c8580017a484a7ac56d3abc5a6c1feadf88db2f3633f12ae4268c69"
 dependencies = [
  "bitflags",
  "core-foundation",
@@ -2293,9 +2201,9 @@ dependencies = [
 
 [[package]]
 name = "security-framework-sys"
-version = "0.4.3"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405"
+checksum = "f99b9d5e26d2a71633cc4f2ebae7cc9f874044e0c351a27e17892d76dce5678b"
 dependencies = [
  "core-foundation-sys",
  "libc",
@@ -2318,29 +2226,38 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
 
 [[package]]
 name = "serde"
-version = "1.0.115"
+version = "1.0.118"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5"
+checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800"
 dependencies = [
  "serde_derive",
 ]
 
+[[package]]
+name = "serde_bytes"
+version = "0.11.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9"
+dependencies = [
+ "serde",
+]
+
 [[package]]
 name = "serde_derive"
-version = "1.0.115"
+version = "1.0.118"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48"
+checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df"
 dependencies = [
- "proc-macro2 1.0.19",
- "quote 1.0.7",
- "syn 1.0.37",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
 ]
 
 [[package]]
 name = "serde_json"
-version = "1.0.57"
+version = "1.0.60"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c"
+checksum = "1500e84d27fe482ed1dc791a56eddc2f230046a040fa908c08bda1d9fb615779"
 dependencies = [
  "indexmap",
  "itoa",
@@ -2350,21 +2267,21 @@ dependencies = [
 
 [[package]]
 name = "serde_urlencoded"
-version = "0.6.1"
+version = "0.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
+checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
 dependencies = [
- "dtoa",
+ "form_urlencoded",
  "itoa",
+ "ryu",
  "serde",
- "url 2.1.1",
 ]
 
 [[package]]
 name = "serde_with"
-version = "1.4.0"
+version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89d3d595d64120bbbc70b7f6d5ae63298b62a3d9f373ec2f56acf5365ca8a444"
+checksum = "15f6201e064705553ece353a736a64be975680bd244908cf63e8fa71e478a51a"
 dependencies = [
  "serde",
  "serde_with_macros",
@@ -2372,13 +2289,14 @@ dependencies = [
 
 [[package]]
 name = "serde_with_macros"
-version = "1.1.0"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4070d2c9b9d258465ad1d82aabb985b84cd9a3afa94da25ece5a9938ba5f1606"
+checksum = "1197ff7de45494f290c1e3e1a6f80e108974681984c87a3e480991ef3d0f1950"
 dependencies = [
- "proc-macro2 1.0.19",
- "quote 1.0.7",
- "syn 1.0.37",
+ "darling",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
 ]
 
 [[package]]
@@ -2411,6 +2329,15 @@ dependencies = [
  "opaque-debug 0.2.3",
 ]
 
+[[package]]
+name = "signal-hook-registry"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "slab"
 version = "0.4.2"
@@ -2419,40 +2346,18 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
 
 [[package]]
 name = "smallvec"
-version = "1.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3757cb9d89161a2f24e1cf78efa0c1fcff485d18e3f55e0aa3480824ddaa0f3f"
-
-[[package]]
-name = "smol"
-version = "0.1.18"
+version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "620cbb3c6e34da57d3a248cda0cd01cd5848164dc062e764e65d06fe3ea7aed5"
-dependencies = [
- "async-task",
- "blocking",
- "concurrent-queue",
- "fastrand",
- "futures-io",
- "futures-util",
- "libc",
- "once_cell",
- "scoped-tls",
- "slab",
- "socket2",
- "wepoll-sys-stjepang",
- "winapi 0.3.9",
-]
+checksum = "ae524f056d7d770e174287294f562e95044c68e88dec909a00d2094805db9d75"
 
 [[package]]
 name = "socket2"
-version = "0.3.12"
+version = "0.3.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918"
+checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "libc",
- "redox_syscall",
  "winapi 0.3.9",
 ]
 
@@ -2464,24 +2369,18 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
 
 [[package]]
 name = "standback"
-version = "0.2.9"
+version = "0.2.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0437cfb83762844799a60e1e3b489d5ceb6a650fbacb86437badc1b6d87b246"
+checksum = "cf906c8b8fc3f6ecd1046e01da1d8ddec83e48c8b08b84dcc02b585a6bedf5a8"
 dependencies = [
- "version_check 0.9.2",
+ "version_check",
 ]
 
 [[package]]
 name = "state"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7345c971d1ef21ffdbd103a75990a15eb03604fc8b8852ca8cb418ee1a099028"
-
-[[package]]
-name = "static_assertions"
-version = "1.1.0"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+checksum = "3015a7d0a5fd5105c91c3710d42f9ccf0abfb287d62206484dcc67f9569a6483"
 
 [[package]]
 name = "stdweb"
@@ -2503,11 +2402,11 @@ version = "0.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
 dependencies = [
- "proc-macro2 1.0.19",
- "quote 1.0.7",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
  "serde",
  "serde_derive",
- "syn 1.0.37",
+ "syn 1.0.56",
 ]
 
 [[package]]
@@ -2517,13 +2416,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11"
 dependencies = [
  "base-x",
- "proc-macro2 1.0.19",
- "quote 1.0.7",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
  "serde",
  "serde_derive",
  "serde_json",
  "sha1",
- "syn 1.0.37",
+ "syn 1.0.56",
 ]
 
 [[package]]
@@ -2542,6 +2441,12 @@ dependencies = [
  "unicode-normalization",
 ]
 
+[[package]]
+name = "strsim"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
+
 [[package]]
 name = "strsim"
 version = "0.10.0"
@@ -2567,12 +2472,12 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "1.0.37"
+version = "1.0.56"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "239f255b9e3429350f188c27b807fc9920a15eb9145230ff1a7d054c08fec319"
+checksum = "a9802ddde94170d186eeee5005b798d9c159fa970403f1be19976d0cfb939b72"
 dependencies = [
- "proc-macro2 1.0.19",
- "quote 1.0.7",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
  "unicode-xid 0.2.1",
 ]
 
@@ -2582,9 +2487,9 @@ version = "0.12.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
 dependencies = [
- "proc-macro2 1.0.19",
- "quote 1.0.7",
- "syn 1.0.37",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
  "unicode-xid 0.2.1",
 ]
 
@@ -2594,13 +2499,19 @@ version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60"
 
+[[package]]
+name = "tap"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "36474e732d1affd3a6ed582781b3683df3d0563714c59c39591e8ff707cf078e"
+
 [[package]]
 name = "tempfile"
 version = "3.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
 dependencies = [
- "cfg-if",
+ "cfg-if 0.1.10",
  "libc",
  "rand 0.7.3",
  "redox_syscall",
@@ -2610,44 +2521,31 @@ dependencies = [
 
 [[package]]
 name = "termcolor"
-version = "1.1.0"
+version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
+checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
 dependencies = [
  "winapi-util",
 ]
 
-[[package]]
-name = "textnonce"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acc659075a12c12c07bbb384862c352506707f6597f5b495f65427d08519b617"
-dependencies = [
- "base64 0.12.3",
- "byteorder",
- "chrono",
- "rand 0.7.3",
- "serde",
-]
-
 [[package]]
 name = "thiserror"
-version = "1.0.20"
+version = "1.0.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08"
+checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e"
 dependencies = [
  "thiserror-impl",
 ]
 
 [[package]]
 name = "thiserror-impl"
-version = "1.0.20"
+version = "1.0.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
+checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56"
 dependencies = [
- "proc-macro2 1.0.19",
- "quote 1.0.7",
- "syn 1.0.37",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
 ]
 
 [[package]]
@@ -2661,34 +2559,35 @@ dependencies = [
 
 [[package]]
 name = "time"
-version = "0.1.43"
+version = "0.1.44"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
+checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
 dependencies = [
  "libc",
+ "wasi 0.10.0+wasi-snapshot-preview1",
  "winapi 0.3.9",
 ]
 
 [[package]]
 name = "time"
-version = "0.2.16"
+version = "0.2.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a51cadc5b1eec673a685ff7c33192ff7b7603d0b75446fb354939ee615acb15"
+checksum = "bcdaeea317915d59b2b4cd3b5efcd156c309108664277793f5351700c02ce98b"
 dependencies = [
- "cfg-if",
+ "const_fn",
  "libc",
  "standback",
  "stdweb",
  "time-macros",
- "version_check 0.9.2",
+ "version_check",
  "winapi 0.3.9",
 ]
 
 [[package]]
 name = "time-macros"
-version = "0.1.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ae9b6e9f095bc105e183e3cd493d72579be3181ad4004fceb01adbe9eecab2d"
+checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1"
 dependencies = [
  "proc-macro-hack",
  "time-macros-impl",
@@ -2701,34 +2600,59 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e5c3be1edfad6027c69f5491cf4cb310d1a71ecd6af742788c6ff8bced86b8fa"
 dependencies = [
  "proc-macro-hack",
- "proc-macro2 1.0.19",
- "quote 1.0.7",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
  "standback",
- "syn 1.0.37",
+ "syn 1.0.56",
 ]
 
 [[package]]
 name = "tinyvec"
-version = "0.3.3"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccf8dbc19eb42fba10e8feaaec282fb50e2c14b2726d6301dbfeed0f73306a6f"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed"
+checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
 
 [[package]]
 name = "tokio"
-version = "0.2.22"
+version = "0.2.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd"
+checksum = "099837d3464c16a808060bb3f02263b412f6fafcb5d01c533d309985fbeebe48"
 dependencies = [
  "bytes 0.5.6",
  "fnv",
  "futures-core",
  "iovec",
  "lazy_static",
+ "libc",
  "memchr",
  "mio",
+ "mio-uds",
  "num_cpus",
- "pin-project-lite",
+ "pin-project-lite 0.1.11",
+ "signal-hook-registry",
  "slab",
+ "tokio-macros",
+ "winapi 0.3.9",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a"
+dependencies = [
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
 ]
 
 [[package]]
@@ -2738,7 +2662,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "15cb62a0d2770787abc96e99c1cd98fcf17f94959f3af63ca85bdfb203f051b4"
 dependencies = [
  "futures-core",
- "rustls",
+ "rustls 0.17.0",
+ "tokio",
+ "webpki",
+]
+
+[[package]]
+name = "tokio-rustls"
+version = "0.14.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e12831b255bcfa39dc0436b01e19fea231a37db570686c06ee72c423479f889a"
+dependencies = [
+ "futures-core",
+ "rustls 0.18.1",
  "tokio",
  "webpki",
 ]
@@ -2762,25 +2698,16 @@ dependencies = [
  "bytes 0.5.6",
  "futures-core",
  "futures-sink",
- "log 0.4.11",
- "pin-project-lite",
+ "log",
+ "pin-project-lite 0.1.11",
  "tokio",
 ]
 
 [[package]]
 name = "toml"
-version = "0.4.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "toml"
-version = "0.5.6"
+version = "0.5.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
+checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
 dependencies = [
  "serde",
 ]
@@ -2793,62 +2720,67 @@ checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860"
 
 [[package]]
 name = "tracing"
-version = "0.1.19"
+version = "0.1.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d79ca061b032d6ce30c660fded31189ca0b9922bf483cd70759f13a2d86786c"
+checksum = "9f47026cdc4080c07e49b37087de021820269d996f581aac150ef9e5583eefe3"
 dependencies = [
- "cfg-if",
- "log 0.4.11",
+ "cfg-if 1.0.0",
+ "log",
+ "pin-project-lite 0.2.0",
  "tracing-core",
 ]
 
 [[package]]
 name = "tracing-core"
-version = "0.1.14"
+version = "0.1.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db63662723c316b43ca36d833707cc93dff82a02ba3d7e354f342682cc8b3545"
+checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f"
 dependencies = [
  "lazy_static",
 ]
 
 [[package]]
-name = "traitobject"
-version = "0.1.0"
+name = "tracing-futures"
+version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
+checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c"
+dependencies = [
+ "pin-project 0.4.27",
+ "tracing",
+]
 
 [[package]]
 name = "trust-dns-proto"
-version = "0.19.5"
+version = "0.19.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdd7061ba6f4d4d9721afedffbfd403f20f39a4301fee1b70d6fcd09cca69f28"
+checksum = "53861fcb288a166aae4c508ae558ed18b53838db728d4d310aad08270a7d4c2b"
 dependencies = [
  "async-trait",
  "backtrace",
  "enum-as-inner",
  "futures",
- "idna 0.2.0",
+ "idna",
  "lazy_static",
- "log 0.4.11",
+ "log",
  "rand 0.7.3",
  "smallvec",
  "thiserror",
  "tokio",
- "url 2.1.1",
+ "url",
 ]
 
 [[package]]
 name = "trust-dns-resolver"
-version = "0.19.5"
+version = "0.19.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f23cdfdc3d8300b3c50c9e84302d3bd6d860fb9529af84ace6cf9665f181b77"
+checksum = "6759e8efc40465547b0dfce9500d733c65f969a4cbbfbe3ccf68daaa46ef179e"
 dependencies = [
  "backtrace",
- "cfg-if",
+ "cfg-if 0.1.10",
  "futures",
  "ipconfig",
  "lazy_static",
- "log 0.4.11",
+ "log",
  "lru-cache",
  "resolv-conf",
  "smallvec",
@@ -2863,12 +2795,6 @@ version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
 
-[[package]]
-name = "typeable"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887"
-
 [[package]]
 name = "typed-builder"
 version = "0.3.0"
@@ -2886,11 +2812,20 @@ version = "1.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33"
 
+[[package]]
+name = "ubyte"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42756bb9e708855de2f8a98195643dff31a97f0485d90d8467b39dc24be9e8fe"
+dependencies = [
+ "serde",
+]
+
 [[package]]
 name = "ulid"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cacfb60872052779608509dcb3dbc8b9d955f5686d71e7ad3173029dc482d07d"
+checksum = "b7e95a59b292ca0cf9b45be2e52294d1ca6cb24eb11b08ef4376f73f1a00c549"
 dependencies = [
  "chrono",
  "lazy_static",
@@ -2898,12 +2833,12 @@ dependencies = [
 ]
 
 [[package]]
-name = "unicase"
-version = "1.4.2"
+name = "uncased"
+version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33"
+checksum = "369fa7fd7969c5373541d3c9a40dc1b76ce676fc87aba30d87c0ad3b97fad179"
 dependencies = [
- "version_check 0.1.5",
+ "version_check",
 ]
 
 [[package]]
@@ -2912,7 +2847,7 @@ version = "2.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
 dependencies = [
- "version_check 0.9.2",
+ "version_check",
 ]
 
 [[package]]
@@ -2922,7 +2857,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6ef53697679d874d69f3160af80bc28de12730a985d57bdf2b47456ccb8b11f1"
 dependencies = [
  "serde",
- "unicase 2.6.0",
+ "unicase",
 ]
 
 [[package]]
@@ -2936,18 +2871,18 @@ dependencies = [
 
 [[package]]
 name = "unicode-normalization"
-version = "0.1.13"
+version = "0.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977"
+checksum = "a13e63ab62dbe32aeee58d1c5408d35c36c392bba5d9d3142287219721afe606"
 dependencies = [
  "tinyvec",
 ]
 
 [[package]]
 name = "unicode-segmentation"
-version = "1.6.0"
+version = "1.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
+checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
 
 [[package]]
 name = "unicode-xid"
@@ -2969,24 +2904,14 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
 
 [[package]]
 name = "url"
-version = "1.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
-dependencies = [
- "idna 0.1.5",
- "matches",
- "percent-encoding 1.0.1",
-]
-
-[[package]]
-name = "url"
-version = "2.1.1"
+version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb"
+checksum = "5909f2b0817350449ed73e8bcd81c8c3c8d9a7a5d8acba4b27db277f1868976e"
 dependencies = [
- "idna 0.2.0",
+ "form_urlencoded",
+ "idna",
  "matches",
- "percent-encoding 2.1.0",
+ "percent-encoding",
 ]
 
 [[package]]
@@ -3004,26 +2929,20 @@ version = "0.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e60fadf92c22236de4028ceb0b8af50ed3430d41ad43d7a7d63b6bd1a8f47c38"
 dependencies = [
- "idna 0.2.0",
+ "idna",
  "lazy_static",
  "regex",
  "serde",
  "serde_derive",
  "serde_json",
- "url 2.1.1",
+ "url",
 ]
 
 [[package]]
 name = "vcpkg"
-version = "0.2.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c"
-
-[[package]]
-name = "version_check"
-version = "0.1.5"
+version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
+checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb"
 
 [[package]]
 name = "version_check"
@@ -3031,30 +2950,13 @@ version = "0.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
 
-[[package]]
-name = "waker-fn"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9571542c2ce85ce642e6b58b3364da2fb53526360dfb7c211add4f5c23105ff7"
-
-[[package]]
-name = "walkdir"
-version = "2.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d"
-dependencies = [
- "same-file",
- "winapi 0.3.9",
- "winapi-util",
-]
-
 [[package]]
 name = "want"
 version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
 dependencies = [
- "log 0.4.11",
+ "log",
  "try-lock",
 ]
 
@@ -3064,13 +2966,19 @@ version = "0.9.0+wasi-snapshot-preview1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
 
+[[package]]
+name = "wasi"
+version = "0.10.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
+
 [[package]]
 name = "wasm-bindgen"
-version = "0.2.67"
+version = "0.2.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0563a9a4b071746dd5aedbc3a28c6fe9be4586fb3fbadb67c400d4f53c6b16c"
+checksum = "3cd364751395ca0f68cafb17666eee36b63077fb5ecd972bbcd74c90c4bf736e"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "serde",
  "serde_json",
  "wasm-bindgen-macro",
@@ -3078,26 +2986,26 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-backend"
-version = "0.2.67"
+version = "0.2.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bc71e4c5efa60fb9e74160e89b93353bc24059999c0ae0fb03affc39770310b0"
+checksum = "1114f89ab1f4106e5b55e688b828c0ab0ea593a1ea7c094b141b14cbaaec2d62"
 dependencies = [
  "bumpalo",
  "lazy_static",
- "log 0.4.11",
- "proc-macro2 1.0.19",
- "quote 1.0.7",
- "syn 1.0.37",
+ "log",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-futures"
-version = "0.4.17"
+version = "0.4.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95f8d235a77f880bcef268d379810ea6c0af2eacfa90b1ad5af731776e0c4699"
+checksum = "1fe9756085a84584ee9457a002b7cdfe0bfff169f45d2591d8be1345a6780e35"
 dependencies = [
- "cfg-if",
+ "cfg-if 1.0.0",
  "js-sys",
  "wasm-bindgen",
  "web-sys",
@@ -3105,38 +3013,38 @@ dependencies = [
 
 [[package]]
 name = "wasm-bindgen-macro"
-version = "0.2.67"
+version = "0.2.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97c57cefa5fa80e2ba15641578b44d36e7a64279bc5ed43c6dbaf329457a2ed2"
+checksum = "7a6ac8995ead1f084a8dea1e65f194d0973800c7f571f6edd70adf06ecf77084"
 dependencies = [
- "quote 1.0.7",
+ "quote 1.0.8",
  "wasm-bindgen-macro-support",
 ]
 
 [[package]]
 name = "wasm-bindgen-macro-support"
-version = "0.2.67"
+version = "0.2.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "841a6d1c35c6f596ccea1f82504a192a60378f64b3bb0261904ad8f2f5657556"
+checksum = "b5a48c72f299d80557c7c62e37e7225369ecc0c963964059509fbafe917c7549"
 dependencies = [
- "proc-macro2 1.0.19",
- "quote 1.0.7",
- "syn 1.0.37",
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.56",
  "wasm-bindgen-backend",
  "wasm-bindgen-shared",
 ]
 
 [[package]]
 name = "wasm-bindgen-shared"
-version = "0.2.67"
+version = "0.2.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93b162580e34310e5931c4b792560108b10fd14d64915d7fff8ff00180e70092"
+checksum = "7e7811dd7f9398f14cc76efd356f98f03aa30419dea46aa810d71e819fc97158"
 
 [[package]]
 name = "web-sys"
-version = "0.3.44"
+version = "0.3.46"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dda38f4e5ca63eda02c059d243aa25b5f35ab98451e518c51612cd0f1bd19a47"
+checksum = "222b1ef9334f92a21d3fb53dc3fd80f30836959a90f9274a626d7e06315ba3c3"
 dependencies = [
  "js-sys",
  "wasm-bindgen",
@@ -3144,9 +3052,9 @@ dependencies = [
 
 [[package]]
 name = "webpki"
-version = "0.21.3"
+version = "0.21.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab146130f5f790d45f82aeeb09e55a256573373ec64409fc19a6fb82fb1032ae"
+checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea"
 dependencies = [
  "ring",
  "untrusted",
@@ -3163,27 +3071,18 @@ dependencies = [
 
 [[package]]
 name = "webpki-roots"
-version = "0.19.0"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8eff4b7516a57307f9349c64bf34caa34b940b66fed4b2fb3136cb7386e5739"
+checksum = "0f20dea7535251981a9670857150d571846545088359b28e4951d350bdaf179f"
 dependencies = [
  "webpki",
 ]
 
-[[package]]
-name = "wepoll-sys-stjepang"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fd319e971980166b53e17b1026812ad66c6b54063be879eb182342b55284694"
-dependencies = [
- "cc",
-]
-
 [[package]]
 name = "widestring"
-version = "0.4.2"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a763e303c0e0f23b0da40888724762e802a8ffefbc22de4127ef42493c2ea68c"
+checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c"
 
 [[package]]
 name = "winapi"
@@ -3255,13 +3154,13 @@ dependencies = [
  "byteorder",
  "bytes 0.4.12",
  "httparse",
- "log 0.4.11",
+ "log",
  "mio",
  "mio-extras",
  "rand 0.7.3",
  "sha-1",
  "slab",
- "url 2.1.1",
+ "url",
 ]
 
 [[package]]
@@ -3274,6 +3173,12 @@ dependencies = [
  "winapi-build",
 ]
 
+[[package]]
+name = "wyz"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
+
 [[package]]
 name = "yansi"
 version = "0.5.0"
diff --git a/Cargo.toml b/Cargo.toml
index 5016d6a6de26b22b2216cfaa775e55d11c1e78fb..79285f04a3e545236b8097f38d770a645f0c7909 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,29 +7,35 @@ edition = "2018"
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
 [dependencies]
-mongodb = { version = "1.1.1", default-features = false, features = ["sync"] } # FIXME: rewrite database with async API
-rocket = { version = "0.4.5", default-features = false }
+tokio = "0.2.22"
+many-to-many = "0.1.2"
+#rauth = { git = "https://gitlab.insrt.uk/insert/rauth" }
+
+hive_pubsub = { version = "0.4.1", features = ["mongo"] }
+rocket_cors = { git = "https://github.com/lawliet89/rocket_cors" }
+rocket_contrib = { git = "https://github.com/SergioBenitez/Rocket" }
+rocket = { git = "https://github.com/SergioBenitez/Rocket", default-features = false }
+mongodb = { version = "1.1.1", features = ["tokio-runtime"], default-features = false }
+
 once_cell = "1.4.1"
 dotenv = "0.15.0"
-ulid = "0.4.0"
+ulid = "0.4.1"
+
 serde = { version = "1.0.115", features = ["derive"] }
-rocket_contrib = "0.4.5"
+serde_json = "1.0.57"
 validator = "0.10.1"
-bcrypt = "0.8.2"
+bitfield = "0.13.2"
+
+reqwest = { version = "0.10.8", features = ["json"] }
+lazy_static = "1.4.0"
+num_enum = "0.5.1"
 chrono = "0.4.15"
-rand = "0.7.3"
+bcrypt = "0.8.2"
 time = "0.2.16"
-reqwest = { version = "0.10.8", features = ["blocking", "json"] }
-num_enum = "0.5.1"
-ws = "0.9.1"
-hashbrown = "0.8.2"
-serde_json = "1.0.57"
-rocket_cors = "0.5.2"
-bitfield = "0.13.2"
+rand = "0.7.3"
 lru = "0.6.0"
-lazy_static = "1.4.0"
-log = "0.4.11"
-env_logger = "0.7.1"
+ws = "0.9.1"
+
 lettre = "0.10.0-alpha.1"
-hive_pubsub = { version = "0.3.1", features = ["mongo"] }
-many-to-many = "0.1.2"
+env_logger = "0.7.1"
+log = "0.4.11"
diff --git a/src/database/channel.rs b/src/database/channel.rs
index bc696b5c046ac1ff1ca9590100bc17ab31b2404c..a1bfaa157c17dd7aed11c4951e2e9cb45eafb424 100644
--- a/src/database/channel.rs
+++ b/src/database/channel.rs
@@ -7,6 +7,7 @@ use rocket::request::FromParam;
 use rocket_contrib::json::JsonValue;
 use serde::{Deserialize, Serialize};
 use std::sync::{Arc, Mutex};
+use rocket::futures::StreamExt;
 
 #[derive(Serialize, Deserialize, Debug, Clone)]
 pub struct LastMessage {
@@ -76,7 +77,7 @@ lazy_static! {
         Arc::new(Mutex::new(LruCache::new(4_000_000)));
 }
 
-pub fn fetch_channel(id: &str) -> Result<Option<Channel>, String> {
+pub async fn fetch_channel(id: &str) -> Result<Option<Channel>, String> {
     {
         if let Ok(mut cache) = CACHE.lock() {
             let existing = cache.get(&id.to_string());
@@ -90,7 +91,7 @@ pub fn fetch_channel(id: &str) -> Result<Option<Channel>, String> {
     }
 
     let col = get_collection("channels");
-    if let Ok(result) = col.find_one(doc! { "_id": id }, None) {
+    if let Ok(result) = col.find_one(doc! { "_id": id }, None).await {
         if let Some(doc) = result {
             if let Ok(channel) = from_bson(Bson::Document(doc)) as Result<Channel, _> {
                 let mut cache = CACHE.lock().unwrap();
@@ -108,7 +109,7 @@ pub fn fetch_channel(id: &str) -> Result<Option<Channel>, String> {
     }
 }
 
-pub fn fetch_channels(ids: &Vec<String>) -> Result<Vec<Channel>, String> {
+pub async fn fetch_channels(ids: &Vec<String>) -> Result<Vec<Channel>, String> {
     let mut missing = vec![];
     let mut channels = vec![];
 
@@ -133,8 +134,8 @@ pub fn fetch_channels(ids: &Vec<String>) -> Result<Vec<Channel>, String> {
     }
 
     let col = get_collection("channels");
-    if let Ok(result) = col.find(doc! { "_id": { "$in": missing } }, None) {
-        for item in result {
+    if let Ok(mut result) = col.find(doc! { "_id": { "$in": missing } }, None).await {
+        while let Some(item) = result.next().await {
             let mut cache = CACHE.lock().unwrap();
             if let Ok(doc) = item {
                 if let Ok(channel) = from_bson(Bson::Document(doc)) as Result<Channel, _> {
@@ -158,7 +159,8 @@ impl<'r> FromParam<'r> for Channel {
     type Error = &'r RawStr;
 
     fn from_param(param: &'r RawStr) -> Result<Self, Self::Error> {
-        if let Ok(result) = fetch_channel(param) {
+        Err(param)
+        /*if let Ok(result) = fetch_channel(param).await {
             if let Some(channel) = result {
                 Ok(channel)
             } else {
@@ -166,7 +168,7 @@ impl<'r> FromParam<'r> for Channel {
             }
         } else {
             Err(param)
-        }
+        }*/
     }
 }
 
diff --git a/src/database/guild.rs b/src/database/guild.rs
index 1b48f5254dd65f4c073a48247a8708dbdfccd023..b8243f38dd3b8e92a80994f6bc8f00b960180f24 100644
--- a/src/database/guild.rs
+++ b/src/database/guild.rs
@@ -2,6 +2,7 @@ use super::channel::fetch_channels;
 use super::get_collection;
 
 use lru::LruCache;
+use rocket::futures::StreamExt;
 use mongodb::bson::{doc, from_bson, Bson};
 use rocket::http::RawStr;
 use rocket::request::FromParam;
@@ -61,13 +62,14 @@ impl Guild {
         })
     }
 
-    pub fn fetch_channels(&self) -> Result<Vec<super::channel::Channel>, String> {
-        super::channel::fetch_channels(&self.channels)
+    pub async fn fetch_channels(&self) -> Result<Vec<super::channel::Channel>, String> {
+        super::channel::fetch_channels(&self.channels).await
     }
 
-    pub fn seralise_with_channels(self) -> Result<JsonValue, String> {
+    pub async fn seralise_with_channels(self) -> Result<JsonValue, String> {
         let channels = self
-            .fetch_channels()?
+            .fetch_channels()
+            .await?
             .into_iter()
             .map(|x| x.serialise())
             .collect();
@@ -91,7 +93,7 @@ lazy_static! {
         Arc::new(Mutex::new(LruCache::new(4_000_000)));
 }
 
-pub fn fetch_guild(id: &str) -> Result<Option<Guild>, String> {
+pub async fn fetch_guild(id: &str) -> Result<Option<Guild>, String> {
     {
         if let Ok(mut cache) = CACHE.lock() {
             let existing = cache.get(&id.to_string());
@@ -105,7 +107,7 @@ pub fn fetch_guild(id: &str) -> Result<Option<Guild>, String> {
     }
 
     let col = get_collection("guilds");
-    if let Ok(result) = col.find_one(doc! { "_id": id }, None) {
+    if let Ok(result) = col.find_one(doc! { "_id": id }, None).await {
         if let Some(doc) = result {
             dbg!(doc.to_string());
             if let Ok(guild) = from_bson(Bson::Document(doc)) as Result<Guild, _> {
@@ -124,7 +126,7 @@ pub fn fetch_guild(id: &str) -> Result<Option<Guild>, String> {
     }
 }
 
-pub fn fetch_guilds(ids: &Vec<String>) -> Result<Vec<Guild>, String> {
+pub async fn fetch_guilds(ids: &Vec<String>) -> Result<Vec<Guild>, String> {
     let mut missing = vec![];
     let mut guilds = vec![];
 
@@ -149,8 +151,8 @@ pub fn fetch_guilds(ids: &Vec<String>) -> Result<Vec<Guild>, String> {
     }
 
     let col = get_collection("guilds");
-    if let Ok(result) = col.find(doc! { "_id": { "$in": missing } }, None) {
-        for item in result {
+    if let Ok(mut result) = col.find(doc! { "_id": { "$in": missing } }, None).await {
+        if let Some(item) = result.next().await {
             let mut cache = CACHE.lock().unwrap();
             if let Ok(doc) = item {
                 dbg!(doc.to_string());
@@ -171,11 +173,11 @@ pub fn fetch_guilds(ids: &Vec<String>) -> Result<Vec<Guild>, String> {
     }
 }
 
-pub fn serialise_guilds_with_channels(ids: &Vec<String>) -> Result<Vec<JsonValue>, String> {
-    let guilds = fetch_guilds(&ids)?;
+pub async fn serialise_guilds_with_channels(ids: &Vec<String>) -> Result<Vec<JsonValue>, String> {
+    let guilds = fetch_guilds(&ids).await?;
     let cids: Vec<String> = guilds.iter().flat_map(|x| x.channels.clone()).collect();
 
-    let channels = fetch_channels(&cids)?;
+    let channels = fetch_channels(&cids).await?;
     Ok(guilds
         .into_iter()
         .map(|x| {
@@ -194,7 +196,7 @@ pub fn serialise_guilds_with_channels(ids: &Vec<String>) -> Result<Vec<JsonValue
         .collect())
 }
 
-pub fn fetch_member(key: MemberKey) -> Result<Option<Member>, String> {
+pub async fn fetch_member(key: MemberKey) -> Result<Option<Member>, String> {
     {
         if let Ok(mut cache) = MEMBER_CACHE.lock() {
             let existing = cache.get(&key);
@@ -214,7 +216,7 @@ pub fn fetch_member(key: MemberKey) -> Result<Option<Member>, String> {
             "_id.user": &key.1,
         },
         None,
-    ) {
+    ).await {
         if let Some(doc) = result {
             if let Ok(member) = from_bson(Bson::Document(doc)) as Result<Member, _> {
                 let mut cache = MEMBER_CACHE.lock().unwrap();
@@ -236,7 +238,8 @@ impl<'r> FromParam<'r> for Guild {
     type Error = &'r RawStr;
 
     fn from_param(param: &'r RawStr) -> Result<Self, Self::Error> {
-        if let Ok(result) = fetch_guild(param) {
+        Err(param)
+        /*if let Ok(result) = fetch_guild(param) {
             if let Some(channel) = result {
                 Ok(channel)
             } else {
@@ -244,11 +247,11 @@ impl<'r> FromParam<'r> for Guild {
             }
         } else {
             Err(param)
-        }
+        }*/
     }
 }
 
-pub fn get_invite<U: Into<Option<String>>>(
+pub async fn get_invite<U: Into<Option<String>>>(
     code: &String,
     user: U,
 ) -> Option<(String, String, Invite)> {
@@ -282,7 +285,7 @@ pub fn get_invite<U: Into<Option<String>>>(
                 "invites.$": 1,
             })
             .build(),
-    ) {
+    ).await {
         if let Some(doc) = result {
             let invite = doc
                 .get_array("invites")
diff --git a/src/database/message.rs b/src/database/message.rs
index 06a704cfa27e523afec4603211599bf1d1c2ef4b..f03e7478f8b20eb9d3cbe97ab04a264c756e16eb 100644
--- a/src/database/message.rs
+++ b/src/database/message.rs
@@ -3,8 +3,10 @@ use crate::database::channel::Channel;
 use crate::pubsub::hive;
 use crate::routes::channel::ChannelType;
 
-use mongodb::bson::from_bson;
-use mongodb::bson::{doc, to_bson, Bson, DateTime};
+//use mongodb::bson::from_bson;
+//use rocket::futures::StreamExt;
+//use mongodb::bson::{doc, to_bson, Bson, DateTime};
+use mongodb::bson::{doc, to_bson, DateTime};
 use rocket::http::RawStr;
 use rocket::request::FromParam;
 use serde::{Deserialize, Serialize};
@@ -35,22 +37,12 @@ pub struct Message {
 // ? pub fn send_message();
 // ? handle websockets?
 impl Message {
-    pub fn send(&self, target: &Channel) -> bool {
+    pub async fn send(&self, target: &Channel) -> bool {
         if get_collection("messages")
             .insert_one(to_bson(&self).unwrap().as_document().unwrap().clone(), None)
+            .await
             .is_ok()
         {
-            /*notifications::send_message_given_channel(
-                Notification::message_create(Create {
-                    id: self.id.clone(),
-                    nonce: self.nonce.clone(),
-                    channel: self.channel.clone(),
-                    author: self.author.clone(),
-                    content: self.content.clone(),
-                }),
-                &target,
-            );*/
-
             if hive::publish(
                 &target.id,
                 crate::pubsub::events::Notification::message_create(
@@ -93,6 +85,7 @@ impl Message {
 
                 if get_collection("channels")
                     .update_one(doc! { "_id": &target.id }, update, None)
+                    .await
                     .is_ok()
                 {
                     true
@@ -112,7 +105,8 @@ impl<'r> FromParam<'r> for Message {
     type Error = &'r RawStr;
 
     fn from_param(param: &'r RawStr) -> Result<Self, Self::Error> {
-        let col = get_collection("messages");
+        Err(param)
+        /*let col = get_collection("messages");
         let result = col
             .find_one(doc! { "_id": param.to_string() }, None)
             .unwrap();
@@ -121,6 +115,6 @@ impl<'r> FromParam<'r> for Message {
             Ok(from_bson(Bson::Document(message)).expect("Failed to unwrap message."))
         } else {
             Err(param)
-        }
+        }*/
     }
 }
diff --git a/src/database/migrations/init.rs b/src/database/migrations/init.rs
index 35170fbdd9aff0a2db80621286757d203ff8fc21..8d561a6c6a767de49cf504838f37ef2a55e7f56c 100644
--- a/src/database/migrations/init.rs
+++ b/src/database/migrations/init.rs
@@ -5,21 +5,32 @@ use log::info;
 use mongodb::bson::doc;
 use mongodb::options::CreateCollectionOptions;
 
-pub fn create_database() {
+pub async fn create_database() {
     info!("Creating database.");
     let db = get_db();
 
     db.create_collection("users", None)
+        .await
         .expect("Failed to create users collection.");
+    
     db.create_collection("channels", None)
+        .await
         .expect("Failed to create channels collection.");
+    
     db.create_collection("guilds", None)
+        .await
         .expect("Failed to create guilds collection.");
+    
     db.create_collection("members", None)
+        .await
         .expect("Failed to create members collection.");
+    
     db.create_collection("messages", None)
+        .await
         .expect("Failed to create messages collection.");
+    
     db.create_collection("migrations", None)
+        .await
         .expect("Failed to create migrations collection.");
 
     db.create_collection(
@@ -29,7 +40,8 @@ pub fn create_database() {
             .size(1_000_000)
             .build(),
     )
-    .expect("Failed to create pubsub collection.");
+        .await
+        .expect("Failed to create pubsub collection.");
 
     db.collection("migrations")
         .insert_one(
@@ -39,6 +51,7 @@ pub fn create_database() {
             },
             None,
         )
+        .await
         .expect("Failed to save migration info.");
 
     info!("Created database.");
diff --git a/src/database/migrations/mod.rs b/src/database/migrations/mod.rs
index 33cbdf5458ff2e27e2f99460c19fa1df1c1edce2..0067518b6308df84eacf24ee1c08342b42b7583e 100644
--- a/src/database/migrations/mod.rs
+++ b/src/database/migrations/mod.rs
@@ -3,16 +3,17 @@ use super::get_connection;
 pub mod init;
 pub mod scripts;
 
-pub fn run_migrations() {
+pub async fn run_migrations() {
     let client = get_connection();
 
     let list = client
         .list_database_names(None, None)
+        .await
         .expect("Failed to fetch database names.");
 
     if list.iter().position(|x| x == "revolt").is_none() {
-        init::create_database();
+        init::create_database().await;
     } else {
-        scripts::migrate_database();
+        scripts::migrate_database().await;
     }
 }
diff --git a/src/database/migrations/scripts.rs b/src/database/migrations/scripts.rs
index 81fdf4e91877e100d68ce415eda7b17e2888d7c6..a90b83faa51fbfa6c0de4beab0f130e3351e8d59 100644
--- a/src/database/migrations/scripts.rs
+++ b/src/database/migrations/scripts.rs
@@ -1,9 +1,10 @@
 use super::super::get_collection;
 
 use log::info;
-use mongodb::bson::{doc, from_bson, Bson};
 use mongodb::options::FindOptions;
 use serde::{Deserialize, Serialize};
+use crate::rocket::futures::StreamExt;
+use mongodb::bson::{doc, from_bson, Bson};
 
 #[derive(Serialize, Deserialize)]
 struct MigrationInfo {
@@ -13,17 +14,18 @@ struct MigrationInfo {
 
 pub const LATEST_REVISION: i32 = 2;
 
-pub fn migrate_database() {
+pub async fn migrate_database() {
     let migrations = get_collection("migrations");
     let data = migrations
         .find_one(None, None)
+        .await
         .expect("Failed to fetch migration data.");
 
     if let Some(doc) = data {
         let info: MigrationInfo =
             from_bson(Bson::Document(doc)).expect("Failed to read migration information.");
 
-        let revision = run_migrations(info.revision);
+        let revision = run_migrations(info.revision).await;
 
         migrations
             .update_one(
@@ -37,6 +39,7 @@ pub fn migrate_database() {
                 },
                 None,
             )
+            .await
             .expect("Failed to commit migration information.");
 
         info!("Migration complete. Currently at revision {}.", revision);
@@ -45,7 +48,7 @@ pub fn migrate_database() {
     }
 }
 
-pub fn run_migrations(revision: i32) -> i32 {
+pub async fn run_migrations(revision: i32) -> i32 {
     info!("Starting database migration.");
 
     if revision <= 0 {
@@ -56,14 +59,15 @@ pub fn run_migrations(revision: i32) -> i32 {
         info!("Running migration [revision 1]: Add channels to guild object.");
 
         let col = get_collection("guilds");
-        let guilds = col
+        let mut guilds = col
             .find(
                 None,
                 FindOptions::builder().projection(doc! { "_id": 1 }).build(),
             )
+            .await
             .expect("Failed to fetch guilds.");
 
-        let result = get_collection("channels")
+        let mut result = get_collection("channels")
             .find(
                 doc! {
                     "type": 2
@@ -72,15 +76,17 @@ pub fn run_migrations(revision: i32) -> i32 {
                     .projection(doc! { "_id": 1, "guild": 1 })
                     .build(),
             )
+            .await
             .expect("Failed to fetch channels.");
 
         let mut channels = vec![];
-        for doc in result {
+        while let Some(doc) = result.next().await {
             let channel = doc.expect("Failed to fetch channel.");
             let id = channel
                 .get_str("_id")
                 .expect("Failed to get channel id.")
                 .to_string();
+            
             let gid = channel
                 .get_str("guild")
                 .expect("Failed to get guild id.")
@@ -89,7 +95,7 @@ pub fn run_migrations(revision: i32) -> i32 {
             channels.push((id, gid));
         }
 
-        for doc in guilds {
+        while let Some(doc) = guilds.next().await {
             let guild = doc.expect("Failed to fetch guild.");
             let id = guild.get_str("_id").expect("Failed to get guild id.");
 
@@ -110,6 +116,7 @@ pub fn run_migrations(revision: i32) -> i32 {
                 },
                 None,
             )
+            .await
             .expect("Failed to update guild.");
         }
     }
diff --git a/src/database/mod.rs b/src/database/mod.rs
index 1219f5b7654463ed642f2d546f0ffa6f9bd78c0a..d894cbd1a45e45849580b21f85db54de852d81d7 100644
--- a/src/database/mod.rs
+++ b/src/database/mod.rs
@@ -1,15 +1,17 @@
 use crate::util::variables::MONGO_URI;
 
-use mongodb::sync::{Client, Collection, Database};
+use mongodb::{Client, Collection, Database};
 use once_cell::sync::OnceCell;
 
 static DBCONN: OnceCell<Client> = OnceCell::new();
 
-pub fn connect() {
-    let client = Client::with_uri_str(&MONGO_URI).expect("Failed to init db connection.");
+pub async fn connect() {
+    let client = Client::with_uri_str(&MONGO_URI)
+        .await
+        .expect("Failed to init db connection.");
 
     DBCONN.set(client).unwrap();
-    migrations::run_migrations();
+    migrations::run_migrations().await;
 }
 
 pub fn get_connection() -> &'static Client {
diff --git a/src/database/mutual.rs b/src/database/mutual.rs
index 5d0a5fe4c57306cacfcb95b4d88fd0a042f8444b..13048405d2f9bb3e5b6f9af00a9c0a76e29fdf77 100644
--- a/src/database/mutual.rs
+++ b/src/database/mutual.rs
@@ -1,11 +1,12 @@
 use super::{get_collection, MemberPermissions};
 
-use mongodb::bson::doc;
+use mongodb::bson::{doc, Document};
 use mongodb::options::FindOptions;
+use rocket::futures::StreamExt;
 
-pub fn find_mutual_guilds(user_id: &str, target_id: &str) -> Vec<String> {
+pub async fn find_mutual_guilds(user_id: &str, target_id: &str) -> Vec<String> {
     let col = get_collection("members");
-    if let Ok(result) = col.find(
+    if let Ok(mut result) = col.find(
         doc! {
             "$and": [
                 { "id": user_id   },
@@ -13,10 +14,10 @@ pub fn find_mutual_guilds(user_id: &str, target_id: &str) -> Vec<String> {
             ]
         },
         FindOptions::builder().projection(doc! { "_id": 1 }).build(),
-    ) {
+    ).await {
         let mut results = vec![];
 
-        for doc in result {
+        while let Some(doc) = result.next().await {
             if let Ok(guild) = doc {
                 results.push(guild.get_str("_id").unwrap().to_string());
             }
@@ -28,9 +29,9 @@ pub fn find_mutual_guilds(user_id: &str, target_id: &str) -> Vec<String> {
     }
 }
 
-pub fn find_mutual_friends(user_id: &str, target_id: &str) -> Vec<String> {
+pub async fn find_mutual_friends(user_id: &str, target_id: &str) -> Vec<String> {
     let col = get_collection("users");
-    if let Ok(result) = col.find(
+    if let Ok(mut result) = col.find(
         doc! {
             "$and": [
                 { "relations": { "$elemMatch": { "id": user_id,   "status": 0 } } },
@@ -38,10 +39,10 @@ pub fn find_mutual_friends(user_id: &str, target_id: &str) -> Vec<String> {
             ]
         },
         FindOptions::builder().projection(doc! { "_id": 1 }).build(),
-    ) {
+    ).await {
         let mut results = vec![];
 
-        for doc in result {
+        while let Some(doc) = result.next().await {
             if let Ok(user) = doc {
                 results.push(user.get_str("_id").unwrap().to_string());
             }
@@ -53,9 +54,9 @@ pub fn find_mutual_friends(user_id: &str, target_id: &str) -> Vec<String> {
     }
 }
 
-pub fn find_mutual_groups(user_id: &str, target_id: &str) -> Vec<String> {
+pub async fn find_mutual_groups(user_id: &str, target_id: &str) -> Vec<String> {
     let col = get_collection("channels");
-    if let Ok(result) = col.find(
+    if let Ok(mut result) = col.find(
         doc! {
             "type": 1,
             "$and": [
@@ -64,10 +65,10 @@ pub fn find_mutual_groups(user_id: &str, target_id: &str) -> Vec<String> {
             ]
         },
         FindOptions::builder().projection(doc! { "_id": 1 }).build(),
-    ) {
+    ).await {
         let mut results = vec![];
 
-        for doc in result {
+        while let Some(doc) = result.next().await {
             if let Ok(group) = doc {
                 results.push(group.get_str("_id").unwrap().to_string());
             }
@@ -79,7 +80,7 @@ pub fn find_mutual_groups(user_id: &str, target_id: &str) -> Vec<String> {
     }
 }
 
-pub fn has_mutual_connection(user_id: &str, target_id: &str, with_permission: bool) -> bool {
+pub async fn has_mutual_connection(user_id: &str, target_id: &str, with_permission: bool) -> bool {
     let mut doc = doc! { "_id": 1 };
 
     if with_permission {
@@ -88,7 +89,7 @@ pub fn has_mutual_connection(user_id: &str, target_id: &str, with_permission: bo
 
     let opt = FindOptions::builder().projection(doc);
 
-    if let Ok(result) = get_collection("guilds").find(
+    if let Ok(mut result) = get_collection("guilds").find(
         doc! {
             "$and": [
                 { "members": { "$elemMatch": { "id": user_id   } } },
@@ -100,9 +101,9 @@ pub fn has_mutual_connection(user_id: &str, target_id: &str, with_permission: bo
         } else {
             opt.limit(1).build()
         },
-    ) {
+    ).await {
         if with_permission {
-            for item in result {
+            while let Some(item) = result.next().await {
                 // ? logic should match permissions.rs#calculate
                 if let Ok(guild) = item {
                     if guild.get_str("owner").unwrap() == user_id {
@@ -118,7 +119,7 @@ pub fn has_mutual_connection(user_id: &str, target_id: &str, with_permission: bo
             }
 
             false
-        } else if result.count() > 0 {
+        } else if result.collect::<Vec<Result<Document, _>>>().await.len() > 0 {
             true
         } else {
             false
diff --git a/src/database/permissions.rs b/src/database/permissions.rs
index 596419c0f2a631baa91070309f92d2fa68a773cd..e5726ca2ea3b6f9bcd4abb85bbfafc82864cbe92 100644
--- a/src/database/permissions.rs
+++ b/src/database/permissions.rs
@@ -115,7 +115,7 @@ impl PermissionCalculator {
         }
     }
 
-    pub fn fetch_data(mut self) -> PermissionCalculator {
+    pub async fn fetch_data(mut self) -> PermissionCalculator {
         let guild = if let Some(value) = self.guild {
             Some(value)
         } else if let Some(channel) = &self.channel {
@@ -123,7 +123,7 @@ impl PermissionCalculator {
                 0..=1 => None,
                 2 => {
                     if let Some(id) = &channel.guild {
-                        if let Ok(result) = fetch_guild(id) {
+                        if let Ok(result) = fetch_guild(id).await {
                             result
                         } else {
                             None
@@ -139,7 +139,7 @@ impl PermissionCalculator {
         };
 
         if let Some(guild) = &guild {
-            if let Ok(result) = fetch_member(MemberKey(guild.id.clone(), self.user.id.clone())) {
+            if let Ok(result) = fetch_member(MemberKey(guild.id.clone(), self.user.id.clone())).await {
                 self.member = result;
             }
         }
@@ -148,7 +148,7 @@ impl PermissionCalculator {
         self
     }
 
-    pub fn calculate(&self) -> u32 {
+    pub async fn calculate(&self) -> u32 {
         let mut permissions: u32 = 0;
         if let Some(guild) = &self.guild {
             if let Some(_member) = &self.member {
@@ -185,7 +185,7 @@ impl PermissionCalculator {
                                 || relationship == Relationship::BlockedOther
                             {
                                 permissions = 1;
-                            } else if has_mutual_connection(&self.user.id, other, true) {
+                            } else if has_mutual_connection(&self.user.id, other, true).await {
                                 permissions = 1024 + 128 + 32 + 16 + 1;
                             } else {
                                 permissions = 1;
@@ -222,7 +222,7 @@ impl PermissionCalculator {
         permissions
     }
 
-    pub fn as_permission(&self) -> MemberPermissions<[u32; 1]> {
-        MemberPermissions([self.calculate()])
+    pub async fn as_permission(&self) -> MemberPermissions<[u32; 1]> {
+        MemberPermissions([self.calculate().await])
     }
 }
diff --git a/src/database/user.rs b/src/database/user.rs
index 4bc362916063464e1c48b57840832121ac77383d..e20ba46a3bc638c157430b2d264fd851bc187648 100644
--- a/src/database/user.rs
+++ b/src/database/user.rs
@@ -1,15 +1,16 @@
-use super::channel::fetch_channels;
 use super::get_collection;
+use super::channel::fetch_channels;
 use super::guild::serialise_guilds_with_channels;
 
 use lru::LruCache;
-use mongodb::bson::{doc, from_bson, Bson, DateTime};
+use rocket::futures::StreamExt;
 use mongodb::options::FindOptions;
 use rocket::http::{RawStr, Status};
-use rocket::request::{self, FromParam, FromRequest, Request};
-use rocket::Outcome;
-use rocket_contrib::json::JsonValue;
 use serde::{Deserialize, Serialize};
+use rocket_contrib::json::JsonValue;
+use mongodb::bson::{doc, from_bson, Bson, DateTime, Document};
+use rocket::request::{self, FromParam, FromRequest, Request, Outcome};
+
 use std::sync::{Arc, Mutex};
 
 #[derive(Serialize, Deserialize, Debug, Clone)]
@@ -60,7 +61,7 @@ impl User {
         }
     }
 
-    pub fn find_guilds(&self) -> Result<Vec<String>, String> {
+    pub async fn find_guilds(&self) -> Result<Vec<String>, String> {
         let members = get_collection("members")
             .find(
                 doc! {
@@ -68,9 +69,12 @@ impl User {
                 },
                 None,
             )
+            .await
             .map_err(|_| "Failed to fetch members.")?;
 
         Ok(members
+            .collect::<Vec<Result<Document, _>>>()
+            .await
             .into_iter()
             .filter_map(|x| match x {
                 Ok(doc) => match doc.get_document("_id") {
@@ -85,7 +89,7 @@ impl User {
             .collect())
     }
 
-    pub fn find_dms(&self) -> Result<Vec<String>, String> {
+    pub async fn find_dms(&self) -> Result<Vec<String>, String> {
         let channels = get_collection("channels")
             .find(
                 doc! {
@@ -93,9 +97,12 @@ impl User {
                 },
                 FindOptions::builder().projection(doc! { "_id": 1 }).build(),
             )
+            .await
             .map_err(|_| "Failed to fetch channel ids.")?;
 
         Ok(channels
+            .collect::<Vec<Result<Document, _>>>()
+            .await
             .into_iter()
             .filter_map(|x| x.ok())
             .filter_map(|x| match x.get_str("_id") {
@@ -105,11 +112,11 @@ impl User {
             .collect())
     }
 
-    pub fn create_payload(self) -> Result<JsonValue, String> {
+    pub async fn create_payload(self) -> Result<JsonValue, String> {
         let v = vec![];
         let relations = self.relations.as_ref().unwrap_or(&v);
 
-        let users: Vec<JsonValue> = fetch_users(&relations.iter().map(|x| x.id.clone()).collect())?
+        let users: Vec<JsonValue> = fetch_users(&relations.iter().map(|x| x.id.clone()).collect()).await?
             .into_iter()
             .map(|x| {
                 let id = x.id.clone();
@@ -117,7 +124,7 @@ impl User {
             })
             .collect();
 
-        let channels: Vec<JsonValue> = fetch_channels(&self.find_dms()?)?
+        let channels: Vec<JsonValue> = fetch_channels(&self.find_dms().await?).await?
             .into_iter()
             .map(|x| x.serialise())
             .collect();
@@ -125,7 +132,7 @@ impl User {
         Ok(json!({
             "users": users,
             "channels": channels,
-            "guilds": serialise_guilds_with_channels(&self.find_guilds()?)?,
+            "guilds": serialise_guilds_with_channels(&self.find_guilds().await?).await?,
             "user": self.serialise(super::Relationship::SELF as i32)
         }))
     }
@@ -136,7 +143,7 @@ lazy_static! {
         Arc::new(Mutex::new(LruCache::new(4_000_000)));
 }
 
-pub fn fetch_user(id: &str) -> Result<Option<User>, String> {
+pub async fn fetch_user(id: &str) -> Result<Option<User>, String> {
     {
         if let Ok(mut cache) = CACHE.lock() {
             let existing = cache.get(&id.to_string());
@@ -150,7 +157,7 @@ pub fn fetch_user(id: &str) -> Result<Option<User>, String> {
     }
 
     let col = get_collection("users");
-    if let Ok(result) = col.find_one(doc! { "_id": id }, None) {
+    if let Ok(result) = col.find_one(doc! { "_id": id }, None).await {
         if let Some(doc) = result {
             if let Ok(user) = from_bson(Bson::Document(doc)) as Result<User, _> {
                 let mut cache = CACHE.lock().unwrap();
@@ -168,7 +175,7 @@ pub fn fetch_user(id: &str) -> Result<Option<User>, String> {
     }
 }
 
-pub fn fetch_users(ids: &Vec<String>) -> Result<Vec<User>, String> {
+pub async fn fetch_users(ids: &Vec<String>) -> Result<Vec<User>, String> {
     let mut missing = vec![];
     let mut users = vec![];
 
@@ -193,8 +200,8 @@ pub fn fetch_users(ids: &Vec<String>) -> Result<Vec<User>, String> {
     }
 
     let col = get_collection("users");
-    if let Ok(result) = col.find(doc! { "_id": { "$in": missing } }, None) {
-        for item in result {
+    if let Ok(mut result) = col.find(doc! { "_id": { "$in": missing } }, None).await {
+        while let Some(item) = result.next().await {
             let mut cache = CACHE.lock().unwrap();
             if let Ok(doc) = item {
                 if let Ok(user) = from_bson(Bson::Document(doc)) as Result<User, _> {
@@ -221,16 +228,17 @@ pub enum AuthError {
     Invalid,
 }
 
+#[rocket::async_trait]
 impl<'a, 'r> FromRequest<'a, 'r> for User {
     type Error = AuthError;
 
-    fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
+    async fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
         let u = request.headers().get("x-user").next();
         let t = request.headers().get("x-auth-token").next();
 
         if let Some(uid) = u {
             if let Some(token) = t {
-                if let Ok(result) = fetch_user(uid) {
+                if let Ok(result) = fetch_user(uid).await {
                     if let Some(user) = result {
                         if let Some(access_token) = &user.access_token {
                             if access_token == token {
@@ -260,7 +268,8 @@ impl<'r> FromParam<'r> for User {
     type Error = &'r RawStr;
 
     fn from_param(param: &'r RawStr) -> Result<Self, Self::Error> {
-        if let Ok(result) = fetch_user(&param.to_string()) {
+        Err(param)
+        /*if let Ok(result) = fetch_user(&param.to_string()).await {
             if let Some(user) = result {
                 Ok(user)
             } else {
@@ -268,7 +277,7 @@ impl<'r> FromParam<'r> for User {
             }
         } else {
             Err(param)
-        }
+        }*/
     }
 }
 
diff --git a/src/main.rs b/src/main.rs
index ff0efd9a386439b3aa60e793f0703fb167365aac..c6f8ac22a46257eeda0481079eda2493a540c867 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,4 +1,5 @@
 #![feature(proc_macro_hygiene, decl_macro)]
+#![feature(async_closure)]
 
 #[macro_use]
 extern crate rocket;
@@ -17,17 +18,18 @@ pub mod util;
 use log::info;
 use rocket_cors::AllowedOrigins;
 
-fn main() {
+#[tokio::main]
+async fn main() {
     dotenv::dotenv().ok();
     env_logger::init_from_env(env_logger::Env::default().filter_or("RUST_LOG", "info"));
 
     info!("Starting REVOLT server.");
 
     util::variables::preflight_checks();
-    database::connect();
+    database::connect().await;
 
     pubsub::hive::init_hive();
-    pubsub::websocket::launch_server();
+    //pubsub::websocket::launch_server();
 
     let cors = rocket_cors::CorsOptions {
         allowed_origins: AllowedOrigins::All,
@@ -36,5 +38,9 @@ fn main() {
     .to_cors()
     .unwrap();
 
-    routes::mount(rocket::ignite()).attach(cors).launch();
+    routes::mount(rocket::ignite())
+        .attach(cors)
+        .launch()
+        .await
+        .unwrap();
 }
diff --git a/src/pubsub/hive.rs b/src/pubsub/hive.rs
index c157baa4569c9d7fdd1f831ba0e4e3841cee38d5..2ffadd03cdab882571bbb93cf67579285cfcfdf7 100644
--- a/src/pubsub/hive.rs
+++ b/src/pubsub/hive.rs
@@ -1,8 +1,8 @@
 use super::events::Notification;
-use super::websocket;
+// use super::websocket;
 use crate::database::get_collection;
 
-use hive_pubsub::backend::mongo::{listen_thread, MongodbPubSub};
+use hive_pubsub::backend::mongo::MongodbPubSub;
 use hive_pubsub::PubSub;
 use once_cell::sync::OnceCell;
 use serde_json::to_string;
@@ -12,12 +12,12 @@ static HIVE: OnceCell<MongodbPubSub<String, String, Notification>> = OnceCell::n
 
 pub fn init_hive() {
     let hive = MongodbPubSub::new(
-        |ids, notification| {
+        |_ids, notification| {
             if let Ok(data) = to_string(&notification) {
                 debug!("Pushing out notification. {}", data);
-                if let Err(err) = websocket::publish(ids, data) {
-                    error!("Failed to publish notification through WebSocket! {}", err);
-                }
+                // if let Err(err) = websocket::publish(ids, data) {
+                //     error!("Failed to publish notification through WebSocket! {}", err);
+                // }
             } else {
                 error!("Failed to serialise notification.");
             }
@@ -25,7 +25,7 @@ pub fn init_hive() {
         get_collection("hive"),
     );
 
-    listen_thread(hive.clone());
+    //listen_thread(hive.clone());
 
     if HIVE.set(hive).is_err() {
         panic!("Failed to set global pubsub instance.");
diff --git a/src/pubsub/mod.rs b/src/pubsub/mod.rs
index 23abbfd52dd5c810e66c3b4c87e2c6ec3b29d821..d898b56f713f910cbec91b3de2ce4ded58bc552b 100644
--- a/src/pubsub/mod.rs
+++ b/src/pubsub/mod.rs
@@ -1,3 +1,3 @@
 pub mod events;
 pub mod hive;
-pub mod websocket;
+// pub mod websocket;
diff --git a/src/pubsub/websocket/client.rs b/src/pubsub/websocket.disabled/client.rs
similarity index 99%
rename from src/pubsub/websocket/client.rs
rename to src/pubsub/websocket.disabled/client.rs
index c3fc469e5c418700d898cb6982b52f756f0c57b3..ff4c7c684e049dd3dd58f12b159985b4b235ff3a 100644
--- a/src/pubsub/websocket/client.rs
+++ b/src/pubsub/websocket.disabled/client.rs
@@ -57,7 +57,7 @@ impl Handler for Client {
                                 FindOneOptions::builder()
                                     .projection(doc! { "_id": 1 })
                                     .build(),
-                            );
+                            ).await;
 
                             if let Ok(result) = user {
                                 if let Some(doc) = result {
diff --git a/src/pubsub/websocket/mod.rs b/src/pubsub/websocket.disabled/mod.rs
similarity index 100%
rename from src/pubsub/websocket/mod.rs
rename to src/pubsub/websocket.disabled/mod.rs
diff --git a/src/pubsub/websocket/state.rs b/src/pubsub/websocket.disabled/state.rs
similarity index 100%
rename from src/pubsub/websocket/state.rs
rename to src/pubsub/websocket.disabled/state.rs
diff --git a/src/routes/account.rs b/src/routes/account.rs
index ed19b3702ae9905483e722ccb9e0a69cb0d06b15..24a90e94f9ff20652a10c522d0ce7b6a25defe52 100644
--- a/src/routes/account.rs
+++ b/src/routes/account.rs
@@ -29,8 +29,8 @@ pub struct Create {
 /// (2) check email existence
 /// (3) add user and send email verification
 #[post("/create", data = "<info>")]
-pub fn create(info: Json<Create>) -> Response {
-    if let Err(error) = captcha::verify(&info.captcha) {
+pub async fn create(info: Json<Create>) -> Response {
+    if let Err(error) = captcha::verify(&info.captcha).await {
         return Response::BadRequest(json!({ "error": error }));
     }
 
@@ -58,6 +58,7 @@ pub fn create(info: Json<Create>) -> Response {
 
     if let Some(_) = col
         .find_one(doc! { "email": info.email.clone() }, None)
+        .await
         .expect("Failed user lookup")
     {
         return Response::Conflict(json!({ "error": "Email already in use!" }));
@@ -65,6 +66,7 @@ pub fn create(info: Json<Create>) -> Response {
 
     if let Some(_) = col
         .find_one(doc! { "username": info.username.clone() }, None)
+        .await
         .expect("Failed user lookup")
     {
         return Response::Conflict(json!({ "error": "Username already in use!" }));
@@ -99,7 +101,8 @@ pub fn create(info: Json<Create>) -> Response {
                 "email_verification": email_verification
             },
             None,
-        ) {
+        )
+        .await {
             Ok(_) => {
                 if *USE_EMAIL {
                     let sent = email::send_verification_email(info.email.clone(), code);
@@ -128,11 +131,12 @@ pub fn create(info: Json<Create>) -> Response {
 /// (2) check if it expired yet
 /// (3) set account as verified
 #[get("/verify/<code>")]
-pub fn verify_email(code: String) -> Response {
+pub async fn verify_email(code: String) -> Response {
     let col = database::get_collection("users");
 
     if let Some(u) = col
         .find_one(doc! { "email_verification.code": code.clone() }, None)
+        .await
         .expect("Failed user lookup")
     {
         let user: User = from_bson(Bson::Document(u)).expect("Failed to unwrap user.");
@@ -161,6 +165,7 @@ pub fn verify_email(code: String) -> Response {
                 },
                 None,
             )
+            .await
             .expect("Failed to update user!");
 
             if *USE_EMAIL {
@@ -187,8 +192,8 @@ pub struct Resend {
 /// (2) check for rate limit
 /// (3) resend the email
 #[post("/resend", data = "<info>")]
-pub fn resend_email(info: Json<Resend>) -> Response {
-    if let Err(error) = captcha::verify(&info.captcha) {
+pub async fn resend_email(info: Json<Resend>) -> Response {
+    if let Err(error) = captcha::verify(&info.captcha).await {
         return Response::BadRequest(json!({ "error": error }));
     }
 
@@ -199,6 +204,7 @@ pub fn resend_email(info: Json<Resend>) -> Response {
             doc! { "email_verification.target": info.email.clone() },
             None,
         )
+        .await
         .expect("Failed user lookup.")
     {
         let user: User = from_bson(Bson::Document(u)).expect("Failed to unwrap user.");
@@ -234,7 +240,9 @@ pub fn resend_email(info: Json<Resend>) -> Response {
 						},
 					},
 					None,
-				).expect("Failed to update user!");
+				)
+                .await
+                .expect("Failed to update user!");
 
             if let Err(err) = email::send_verification_email(info.email.clone(), code) {
                 return Response::InternalServerError(json!({ "error": err }));
@@ -259,8 +267,8 @@ pub struct Login {
 /// (2) verify password
 /// (3) return access token
 #[post("/login", data = "<info>")]
-pub fn login(info: Json<Login>) -> Response {
-    if let Err(error) = captcha::verify(&info.captcha) {
+pub async fn login(info: Json<Login>) -> Response {
+    if let Err(error) = captcha::verify(&info.captcha).await {
         return Response::BadRequest(json!({ "error": error }));
     }
 
@@ -268,6 +276,7 @@ pub fn login(info: Json<Login>) -> Response {
 
     if let Some(u) = col
         .find_one(doc! { "email": info.email.clone() }, None)
+        .await
         .expect("Failed user lookup")
     {
         let user: User = from_bson(Bson::Document(u)).expect("Failed to unwrap user.");
@@ -286,6 +295,7 @@ pub fn login(info: Json<Login>) -> Response {
                                 doc! { "$set": { "access_token": token.clone() } },
                                 None,
                             )
+                            .await
                             .is_err()
                         {
                             return Response::InternalServerError(
@@ -313,10 +323,10 @@ pub struct Token {
 
 /// login to a Revolt account via token
 #[post("/token", data = "<info>")]
-pub fn token(info: Json<Token>) -> Response {
+pub async fn token(info: Json<Token>) -> Response {
     let col = database::get_collection("users");
 
-    if let Ok(result) = col.find_one(doc! { "access_token": info.token.clone() }, None) {
+    if let Ok(result) = col.find_one(doc! { "access_token": info.token.clone() }, None).await {
         if let Some(user) = result {
             Response::Success(json!({
                 "id": user.get_str("_id").unwrap(),
@@ -332,24 +342,3 @@ pub fn token(info: Json<Token>) -> Response {
         }))
     }
 }
-
-#[options("/create")]
-pub fn create_preflight() -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/verify/<_code>")]
-pub fn verify_email_preflight(_code: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/resend")]
-pub fn resend_email_preflight() -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/login")]
-pub fn login_preflight() -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/token")]
-pub fn token_preflight() -> Response {
-    Response::Result(super::Status::Ok)
-}
diff --git a/src/routes/channel.rs b/src/routes/channel.rs
index 85952dd5a8275321a64e33989054fc1635e87528..592da2a9e4cd241e5ecc59c414868d5a514a8af4 100644
--- a/src/routes/channel.rs
+++ b/src/routes/channel.rs
@@ -6,11 +6,12 @@ use crate::database::{
 use crate::util::vec_to_set;
 
 use chrono::prelude::*;
-use mongodb::bson::{doc, from_bson, Bson};
+use mongodb::bson::{doc, from_bson, Bson, Document};
 use mongodb::options::FindOptions;
 use num_enum::TryFromPrimitive;
 use rocket::request::Form;
 use rocket_contrib::json::Json;
+use rocket::futures::StreamExt;
 use serde::{Deserialize, Serialize};
 use ulid::Ulid;
 
@@ -28,9 +29,10 @@ macro_rules! with_permissions {
     ($user: expr, $target: expr) => {{
         let permissions = PermissionCalculator::new($user.clone())
             .channel($target.clone())
-            .fetch_data();
+            .fetch_data()
+            .await;
 
-        let value = permissions.as_permission();
+        let value = permissions.as_permission().await;
         if !value.get_access() {
             return None;
         }
@@ -48,7 +50,7 @@ pub struct CreateGroup {
 
 /// create a new group
 #[post("/create", data = "<info>")]
-pub fn create_group(user: User, info: Json<CreateGroup>) -> Response {
+pub async fn create_group(user: User, info: Json<CreateGroup>) -> Response {
     let name: String = info.name.chars().take(32).collect();
     let nonce: String = info.nonce.chars().take(32).collect();
 
@@ -60,7 +62,7 @@ pub fn create_group(user: User, info: Json<CreateGroup>) -> Response {
     }
 
     let col = database::get_collection("channels");
-    if let Some(_) = col.find_one(doc! { "nonce": nonce.clone() }, None).unwrap() {
+    if let Some(_) = col.find_one(doc! { "nonce": nonce.clone() }, None).await.unwrap() {
         return Response::BadRequest(json!({ "error": "Group already created!" }));
     }
 
@@ -80,8 +82,8 @@ pub fn create_group(user: User, info: Json<CreateGroup>) -> Response {
             }
         },
         FindOptions::builder().limit(query.len() as i64).build(),
-    ) {
-        if result.count() != query.len() {
+    ).await {
+        if result.collect::<Vec<Result<Document, _>>>().await.len() != query.len() {
             return Response::BadRequest(json!({ "error": "Specified non-existant user(s)." }));
         }
 
@@ -110,6 +112,7 @@ pub fn create_group(user: User, info: Json<CreateGroup>) -> Response {
                 },
                 None,
             )
+            .await
             .is_ok()
         {
             Response::Success(json!({ "id": id }))
@@ -123,14 +126,14 @@ pub fn create_group(user: User, info: Json<CreateGroup>) -> Response {
 
 /// fetch channel information
 #[get("/<target>")]
-pub fn channel(user: User, target: Channel) -> Option<Response> {
+pub async fn channel(user: User, target: Channel) -> Option<Response> {
     with_permissions!(user, target);
     Some(Response::Success(target.serialise()))
 }
 
 /// [groups] add user to channel
 #[put("/<target>/recipients/<member>")]
-pub fn add_member(user: User, target: Channel, member: User) -> Option<Response> {
+pub async fn add_member(user: User, target: Channel, member: User) -> Option<Response> {
     if target.channel_type != 1 {
         return Some(Response::BadRequest(json!({ "error": "Not a group DM." })));
     }
@@ -163,6 +166,7 @@ pub fn add_member(user: User, target: Channel, member: User) -> Option<Response>
                     },
                     None,
                 )
+                .await
                 .is_ok()
             {
                 if (Message {
@@ -175,6 +179,7 @@ pub fn add_member(user: User, target: Channel, member: User) -> Option<Response>
                     previous_content: vec![],
                 })
                 .send(&target)
+                .await
                 {
                     /*notifications::send_message_given_channel(
                         Notification::group_user_join(UserJoin {
@@ -204,7 +209,7 @@ pub fn add_member(user: User, target: Channel, member: User) -> Option<Response>
 
 /// [groups] remove user from channel
 #[delete("/<target>/recipients/<member>")]
-pub fn remove_member(user: User, target: Channel, member: User) -> Option<Response> {
+pub async fn remove_member(user: User, target: Channel, member: User) -> Option<Response> {
     if target.channel_type != 1 {
         return Some(Response::BadRequest(json!({ "error": "Not a group DM." })));
     }
@@ -238,6 +243,7 @@ pub fn remove_member(user: User, target: Channel, member: User) -> Option<Respon
             },
             None,
         )
+        .await
         .is_ok()
     {
         if (Message {
@@ -250,6 +256,7 @@ pub fn remove_member(user: User, target: Channel, member: User) -> Option<Respon
             previous_content: vec![],
         })
         .send(&target)
+        .await
         {
             /*notifications::send_message_given_channel(
                 Notification::group_user_leave(UserLeave {
@@ -276,7 +283,7 @@ pub fn remove_member(user: User, target: Channel, member: User) -> Option<Respon
 /// or leave group DM
 /// or close DM conversation
 #[delete("/<target>")]
-pub fn delete(user: User, target: Channel) -> Option<Response> {
+pub async fn delete(user: User, target: Channel) -> Option<Response> {
     let permissions = with_permissions!(user, target);
 
     if !permissions.get_manage_channels() {
@@ -286,14 +293,15 @@ pub fn delete(user: User, target: Channel) -> Option<Response> {
     let col = database::get_collection("channels");
     let target_id = target.id.clone();
 
-    let try_delete = || {
+    let try_delete = async || {
         let messages = database::get_collection("messages");
 
         if messages
             .delete_many(doc! { "channel": &target_id }, None)
+            .await
             .is_ok()
         {
-            if col.delete_one(doc! { "_id": &target_id }, None).is_ok() {
+            if col.delete_one(doc! { "_id": &target_id }, None).await.is_ok() {
                 Some(Response::Result(super::Status::Ok))
             } else {
                 Some(Response::InternalServerError(
@@ -315,6 +323,7 @@ pub fn delete(user: User, target: Channel) -> Option<Response> {
                     doc! { "$set": { "active": false } },
                     None,
                 )
+                .await
                 .is_ok()
             {
                 Some(Response::Result(super::Status::Ok))
@@ -334,7 +343,7 @@ pub fn delete(user: User, target: Channel) -> Option<Response> {
             let owner = target.owner.as_ref().expect("Missing owner on Group DM.");
 
             if recipients.len() == 1 {
-                try_delete()
+                try_delete().await
             } else {
                 recipients.remove(&user.id);
                 let new_owner = if owner == &user.id {
@@ -356,6 +365,7 @@ pub fn delete(user: User, target: Channel) -> Option<Response> {
                         },
                         None,
                     )
+                    .await
                     .is_ok()
                 {
                     if (Message {
@@ -368,6 +378,7 @@ pub fn delete(user: User, target: Channel) -> Option<Response> {
                         previous_content: vec![],
                     })
                     .send(&target)
+                    .await
                     {
                         /*notifications::send_message_given_channel(
                             Notification::group_user_leave(UserLeave {
@@ -405,6 +416,7 @@ pub fn delete(user: User, target: Channel) -> Option<Response> {
                     },
                     None,
                 )
+                .await
                 .is_ok()
             {
                 /*notifications::send_message_threaded(
@@ -416,7 +428,7 @@ pub fn delete(user: User, target: Channel) -> Option<Response> {
                     }), FIXME
                 );*/
 
-                try_delete()
+                try_delete().await
             } else {
                 Some(Response::InternalServerError(
                     json!({ "error": "Failed to remove invites." }),
@@ -438,7 +450,7 @@ pub struct MessageFetchOptions {
 
 /// fetch channel messages
 #[get("/<target>/messages?<options..>")]
-pub fn messages(
+pub async fn messages(
     user: User,
     target: Channel,
     options: Form<MessageFetchOptions>,
@@ -467,7 +479,7 @@ pub fn messages(
     };
 
     let col = database::get_collection("messages");
-    let result = col
+    let mut result = col
         .find(
             query,
             FindOptions::builder()
@@ -477,10 +489,11 @@ pub fn messages(
                 })
                 .build(),
         )
+        .await
         .unwrap();
 
     let mut messages = Vec::new();
-    for item in result {
+    while let Some(item) = result.next().await {
         let message: Message =
             from_bson(Bson::Document(item.unwrap())).expect("Failed to unwrap message.");
         messages.push(json!({
@@ -502,7 +515,7 @@ pub struct SendMessage {
 
 /// send a message to a channel
 #[post("/<target>/messages", data = "<message>")]
-pub fn send_message(user: User, target: Channel, message: Json<SendMessage>) -> Option<Response> {
+pub async fn send_message(user: User, target: Channel, message: Json<SendMessage>) -> Option<Response> {
     let permissions = with_permissions!(user, target);
 
     if !permissions.get_send_messages() {
@@ -525,6 +538,7 @@ pub fn send_message(user: User, target: Channel, message: Json<SendMessage>) ->
     let col = database::get_collection("messages");
     if col
         .find_one(doc! { "nonce": nonce.clone() }, None)
+        .await
         .unwrap()
         .is_some()
     {
@@ -544,7 +558,7 @@ pub fn send_message(user: User, target: Channel, message: Json<SendMessage>) ->
         previous_content: vec![],
     };
 
-    if message.send(&target) {
+    if message.send(&target).await {
         Some(Response::Success(json!({ "id": id })))
     } else {
         Some(Response::BadRequest(
@@ -555,7 +569,7 @@ pub fn send_message(user: User, target: Channel, message: Json<SendMessage>) ->
 
 /// get a message
 #[get("/<target>/messages/<message>")]
-pub fn get_message(user: User, target: Channel, message: Message) -> Option<Response> {
+pub async fn get_message(user: User, target: Channel, message: Message) -> Option<Response> {
     let permissions = with_permissions!(user, target);
 
     if !permissions.get_read_messages() {
@@ -587,7 +601,7 @@ pub struct EditMessage {
 
 /// edit a message
 #[patch("/<target>/messages/<message>", data = "<edit>")]
-pub fn edit_message(
+pub async fn edit_message(
     user: User,
     target: Channel,
     message: Message,
@@ -624,7 +638,8 @@ pub fn edit_message(
             },
         },
         None,
-    ) {
+    )
+    .await {
         Ok(_) => {
             /*notifications::send_message_given_channel(
                 Notification::message_edit(Edit {
@@ -646,7 +661,7 @@ pub fn edit_message(
 
 /// delete a message
 #[delete("/<target>/messages/<message>")]
-pub fn delete_message(user: User, target: Channel, message: Message) -> Option<Response> {
+pub async fn delete_message(user: User, target: Channel, message: Message) -> Option<Response> {
     let permissions = with_permissions!(user, target);
 
     if !permissions.get_manage_messages() && message.author != user.id {
@@ -655,7 +670,7 @@ pub fn delete_message(user: User, target: Channel, message: Message) -> Option<R
 
     let col = database::get_collection("messages");
 
-    match col.delete_one(doc! { "_id": &message.id }, None) {
+    match col.delete_one(doc! { "_id": &message.id }, None).await {
         Ok(_) => {
             /*notifications::send_message_given_channel(
                 Notification::message_delete(Delete {
@@ -671,24 +686,3 @@ pub fn delete_message(user: User, target: Channel, message: Message) -> Option<R
         )),
     }
 }
-
-#[options("/create")]
-pub fn create_group_preflight() -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/<_target>")]
-pub fn channel_preflight(_target: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/<_target>/recipients/<_member>")]
-pub fn member_preflight(_target: String, _member: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/<_target>/messages")]
-pub fn messages_preflight(_target: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/<_target>/messages/<_message>")]
-pub fn message_preflight(_target: String, _message: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
diff --git a/src/routes/guild.rs b/src/routes/guild.rs
index c90c74aa5dd0891364fbb03b6402e395a1c1c541..4ab993a1ca8605c605fe131f82a67cf1da636911 100644
--- a/src/routes/guild.rs
+++ b/src/routes/guild.rs
@@ -12,6 +12,7 @@ use mongodb::options::{FindOneOptions, FindOptions};
 use rocket::request::Form;
 use rocket_contrib::json::Json;
 use serde::{Deserialize, Serialize};
+use rocket::futures::StreamExt;
 use ulid::Ulid;
 
 // ! FIXME: GET RID OF THIS
@@ -19,9 +20,10 @@ macro_rules! with_permissions {
     ($user: expr, $target: expr) => {{
         let permissions = PermissionCalculator::new($user.clone())
             .guild($target.clone())
-            .fetch_data();
+            .fetch_data()
+            .await;
 
-        let value = permissions.as_permission();
+        let value = permissions.as_permission().await;
         if !value.get_access() {
             return None;
         }
@@ -32,9 +34,9 @@ macro_rules! with_permissions {
 
 /// fetch your guilds
 #[get("/@me")]
-pub fn my_guilds(user: User) -> Response {
-    if let Ok(gids) = user.find_guilds() {
-        if let Ok(data) = serialise_guilds_with_channels(&gids) {
+pub async fn my_guilds(user: User) -> Response {
+    if let Ok(gids) = user.find_guilds().await {
+        if let Ok(data) = serialise_guilds_with_channels(&gids).await {
             Response::Success(json!(data))
         } else {
             Response::InternalServerError(json!({ "error": "Failed to fetch guilds." }))
@@ -46,10 +48,10 @@ pub fn my_guilds(user: User) -> Response {
 
 /// fetch a guild
 #[get("/<target>")]
-pub fn guild(user: User, target: Guild) -> Option<Response> {
+pub async fn guild(user: User, target: Guild) -> Option<Response> {
     with_permissions!(user, target);
 
-    if let Ok(result) = target.seralise_with_channels() {
+    if let Ok(result) = target.seralise_with_channels().await {
         Some(Response::Success(result))
     } else {
         Some(Response::InternalServerError(
@@ -60,20 +62,20 @@ pub fn guild(user: User, target: Guild) -> Option<Response> {
 
 /// delete or leave a guild
 #[delete("/<target>")]
-pub fn remove_guild(user: User, target: Guild) -> Option<Response> {
+pub async fn remove_guild(user: User, target: Guild) -> Option<Response> {
     with_permissions!(user, target);
 
     if user.id == target.owner {
         let channels = database::get_collection("channels");
-        if let Ok(result) = channels.find(
+        if let Ok(mut result) = channels.find(
             doc! {
                 "type": 2,
                 "guild": &target.id
             },
             FindOptions::builder().projection(doc! { "_id": 1 }).build(),
-        ) {
+        ).await {
             let mut values = vec![];
-            for item in result {
+            while let Some(item) = result.next().await {
                 if let Ok(doc) = item {
                     values.push(Bson::String(doc.get_str("_id").unwrap().to_string()));
                 }
@@ -88,6 +90,7 @@ pub fn remove_guild(user: User, target: Guild) -> Option<Response> {
                     },
                     None,
                 )
+                .await
                 .is_ok()
             {
                 if channels
@@ -98,6 +101,7 @@ pub fn remove_guild(user: User, target: Guild) -> Option<Response> {
                         },
                         None,
                     )
+                    .await
                     .is_ok()
                 {
                     if database::get_collection("members")
@@ -107,6 +111,7 @@ pub fn remove_guild(user: User, target: Guild) -> Option<Response> {
                             },
                             None,
                         )
+                        .await
                         .is_ok()
                     {
                         if database::get_collection("guilds")
@@ -116,6 +121,7 @@ pub fn remove_guild(user: User, target: Guild) -> Option<Response> {
                                 },
                                 None,
                             )
+                            .await
                             .is_ok()
                         {
                             /*notifications::send_message_threaded(
@@ -160,6 +166,7 @@ pub fn remove_guild(user: User, target: Guild) -> Option<Response> {
             },
             None,
         )
+        .await
         .is_ok()
     {
         /*notifications::send_message_threaded(
@@ -189,7 +196,7 @@ pub struct CreateChannel {
 
 /// create a new channel
 #[post("/<target>/channels", data = "<info>")]
-pub fn create_channel(user: User, target: Guild, info: Json<CreateChannel>) -> Option<Response> {
+pub async fn create_channel(user: User, target: Guild, info: Json<CreateChannel>) -> Option<Response> {
     let (permissions, _) = with_permissions!(user, target);
 
     if !permissions.get_manage_channels() {
@@ -208,6 +215,7 @@ pub fn create_channel(user: User, target: Guild, info: Json<CreateChannel>) -> O
 
     if let Ok(result) =
         database::get_collection("channels").find_one(doc! { "nonce": &nonce }, None)
+        .await
     {
         if result.is_some() {
             return Some(Response::BadRequest(
@@ -228,6 +236,7 @@ pub fn create_channel(user: User, target: Guild, info: Json<CreateChannel>) -> O
                 },
                 None,
             )
+            .await
             .is_ok()
         {
             if database::get_collection("guilds")
@@ -242,6 +251,7 @@ pub fn create_channel(user: User, target: Guild, info: Json<CreateChannel>) -> O
                     },
                     None,
                 )
+                .await
                 .is_ok()
             {
                 /*notifications::send_message_threaded(
@@ -280,7 +290,7 @@ pub struct InviteOptions {
 
 /// create a new invite
 #[post("/<target>/channels/<channel>/invite", data = "<_options>")]
-pub fn create_invite(
+pub async fn create_invite(
     user: User,
     target: Guild,
     channel: Channel,
@@ -307,6 +317,7 @@ pub fn create_invite(
             },
             None,
         )
+        .await
         .is_ok()
     {
         Some(Response::Success(json!({ "code": code })))
@@ -319,10 +330,10 @@ pub fn create_invite(
 
 /// remove an invite
 #[delete("/<target>/invites/<code>")]
-pub fn remove_invite(user: User, target: Guild, code: String) -> Option<Response> {
+pub async fn remove_invite(user: User, target: Guild, code: String) -> Option<Response> {
     let (permissions, _) = with_permissions!(user, target);
 
-    if let Some((guild_id, _, invite)) = get_invite(&code, None) {
+    if let Some((guild_id, _, invite)) = get_invite(&code, None).await {
         if invite.creator != user.id && !permissions.get_manage_server() {
             return Some(Response::LackingPermission(Permission::ManageServer));
         }
@@ -341,6 +352,7 @@ pub fn remove_invite(user: User, target: Guild, code: String) -> Option<Response
                 },
                 None,
             )
+            .await
             .is_ok()
         {
             Some(Response::Result(super::Status::Ok))
@@ -358,7 +370,7 @@ pub fn remove_invite(user: User, target: Guild, code: String) -> Option<Response
 
 /// fetch all guild invites
 #[get("/<target>/invites")]
-pub fn fetch_invites(user: User, target: Guild) -> Option<Response> {
+pub async fn fetch_invites(user: User, target: Guild) -> Option<Response> {
     let (permissions, _) = with_permissions!(user, target);
 
     if !permissions.get_manage_server() {
@@ -370,9 +382,9 @@ pub fn fetch_invites(user: User, target: Guild) -> Option<Response> {
 
 /// view an invite before joining
 #[get("/join/<code>", rank = 1)]
-pub fn fetch_invite(user: User, code: String) -> Response {
-    if let Some((guild_id, name, invite)) = get_invite(&code, user.id) {
-        match fetch_channel(&invite.channel) {
+pub async fn fetch_invite(user: User, code: String) -> Response {
+    if let Some((guild_id, name, invite)) = get_invite(&code, user.id).await {
+        match fetch_channel(&invite.channel).await {
             Ok(result) => {
                 if let Some(channel) = result {
                     Response::Success(json!({
@@ -398,8 +410,8 @@ pub fn fetch_invite(user: User, code: String) -> Response {
 
 /// join a guild using an invite
 #[post("/join/<code>", rank = 1)]
-pub fn use_invite(user: User, code: String) -> Response {
-    if let Some((guild_id, _, invite)) = get_invite(&code, Some(user.id.clone())) {
+pub async fn use_invite(user: User, code: String) -> Response {
+    if let Some((guild_id, _, invite)) = get_invite(&code, Some(user.id.clone())).await {
         if let Ok(result) = database::get_collection("members").find_one(
             doc! {
                 "_id.guild": &guild_id,
@@ -408,7 +420,8 @@ pub fn use_invite(user: User, code: String) -> Response {
             FindOneOptions::builder()
                 .projection(doc! { "_id": 1 })
                 .build(),
-        ) {
+        )
+        .await {
             if result.is_none() {
                 if database::get_collection("members")
                     .insert_one(
@@ -420,6 +433,7 @@ pub fn use_invite(user: User, code: String) -> Response {
                         },
                         None,
                     )
+                    .await
                     .is_ok()
                 {
                     /*notifications::send_message_threaded(
@@ -462,7 +476,7 @@ pub struct CreateGuild {
 
 /// create a new guild
 #[post("/create", data = "<info>")]
-pub fn create_guild(user: User, info: Json<CreateGuild>) -> Response {
+pub async fn create_guild(user: User, info: Json<CreateGuild>) -> Response {
     if !user.email_verification.verified {
         return Response::Unauthorized(json!({ "error": "Email not verified!" }));
     }
@@ -481,6 +495,7 @@ pub fn create_guild(user: User, info: Json<CreateGuild>) -> Response {
     let col = database::get_collection("guilds");
     if col
         .find_one(doc! { "nonce": nonce.clone() }, None)
+        .await
         .unwrap()
         .is_some()
     {
@@ -500,6 +515,7 @@ pub fn create_guild(user: User, info: Json<CreateGuild>) -> Response {
             },
             None,
         )
+        .await
         .is_err()
     {
         return Response::InternalServerError(
@@ -517,6 +533,7 @@ pub fn create_guild(user: User, info: Json<CreateGuild>) -> Response {
             },
             None,
         )
+        .await
         .is_err()
     {
         return Response::InternalServerError(
@@ -539,12 +556,14 @@ pub fn create_guild(user: User, info: Json<CreateGuild>) -> Response {
             },
             None,
         )
+        .await
         .is_ok()
     {
         Response::Success(json!({ "id": id }))
     } else {
         channels
             .delete_one(doc! { "_id": channel_id }, None)
+            .await
             .expect("Failed to delete the channel we just made.");
 
         Response::InternalServerError(json!({ "error": "Failed to create guild." }))
@@ -553,15 +572,16 @@ pub fn create_guild(user: User, info: Json<CreateGuild>) -> Response {
 
 /// fetch a guild's member
 #[get("/<target>/members")]
-pub fn fetch_members(user: User, target: Guild) -> Option<Response> {
+pub async fn fetch_members(user: User, target: Guild) -> Option<Response> {
     with_permissions!(user, target);
 
-    if let Ok(result) =
+    if let Ok(mut result) =
         database::get_collection("members").find(doc! { "_id.guild": target.id }, None)
+        .await
     {
         let mut users = vec![];
 
-        for item in result {
+        while let Some(item) = result.next().await {
             if let Ok(doc) = item {
                 users.push(json!({
                     "id": doc.get_document("_id").unwrap().get_str("user").unwrap(),
@@ -580,10 +600,10 @@ pub fn fetch_members(user: User, target: Guild) -> Option<Response> {
 
 /// fetch a guild member
 #[get("/<target>/members/<other>")]
-pub fn fetch_member(user: User, target: Guild, other: String) -> Option<Response> {
+pub async fn fetch_member(user: User, target: Guild, other: String) -> Option<Response> {
     with_permissions!(user, target);
 
-    if let Ok(result) = get_member(MemberKey(target.id, other)) {
+    if let Ok(result) = get_member(MemberKey(target.id, other)).await {
         if let Some(member) = result {
             Some(Response::Success(json!({
                 "id": member.id.user,
@@ -603,7 +623,7 @@ pub fn fetch_member(user: User, target: Guild, other: String) -> Option<Response
 
 /// kick a guild member
 #[delete("/<target>/members/<other>")]
-pub fn kick_member(user: User, target: Guild, other: String) -> Option<Response> {
+pub async fn kick_member(user: User, target: Guild, other: String) -> Option<Response> {
     let (permissions, _) = with_permissions!(user, target);
 
     if user.id == other {
@@ -616,7 +636,7 @@ pub fn kick_member(user: User, target: Guild, other: String) -> Option<Response>
         return Some(Response::LackingPermission(Permission::KickMembers));
     }
 
-    if let Ok(result) = get_member(MemberKey(target.id.clone(), other.clone())) {
+    if let Ok(result) = get_member(MemberKey(target.id.clone(), other.clone())).await {
         if result.is_none() {
             return Some(Response::BadRequest(
                 json!({ "error": "User not part of guild." }),
@@ -636,6 +656,7 @@ pub fn kick_member(user: User, target: Guild, other: String) -> Option<Response>
             },
             None,
         )
+        .await
         .is_ok()
     {
         /*notifications::send_message_threaded(
@@ -663,7 +684,7 @@ pub struct BanOptions {
 
 /// ban a guild member
 #[put("/<target>/members/<other>/ban?<options..>")]
-pub fn ban_member(
+pub async fn ban_member(
     user: User,
     target: Guild,
     other: String,
@@ -688,7 +709,7 @@ pub fn ban_member(
         return Some(Response::LackingPermission(Permission::BanMembers));
     }
 
-    if let Ok(result) = get_member(MemberKey(target.id.clone(), other.clone())) {
+    if let Ok(result) = get_member(MemberKey(target.id.clone(), other.clone())).await {
         if result.is_none() {
             return Some(Response::BadRequest(
                 json!({ "error": "User not part of guild." }),
@@ -713,6 +734,7 @@ pub fn ban_member(
             },
             None,
         )
+        .await
         .is_err()
     {
         return Some(Response::BadRequest(
@@ -728,6 +750,7 @@ pub fn ban_member(
             },
             None,
         )
+        .await
         .is_ok()
     {
         /*notifications::send_message_threaded(
@@ -750,7 +773,7 @@ pub fn ban_member(
 
 /// unban a guild member
 #[delete("/<target>/members/<other>/ban")]
-pub fn unban_member(user: User, target: Guild, other: String) -> Option<Response> {
+pub async fn unban_member(user: User, target: Guild, other: String) -> Option<Response> {
     let (permissions, _) = with_permissions!(user, target);
 
     if user.id == other {
@@ -783,6 +806,7 @@ pub fn unban_member(user: User, target: Guild, other: String) -> Option<Response
             },
             None,
         )
+        .await
         .is_ok()
     {
         Some(Response::Result(super::Status::Ok))
@@ -792,44 +816,3 @@ pub fn unban_member(user: User, target: Guild, other: String) -> Option<Response
         ))
     }
 }
-
-#[options("/<_target>")]
-pub fn guild_preflight(_target: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/<_target>/channels")]
-pub fn create_channel_preflight(_target: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/<_target>/channels/<_channel>/invite")]
-pub fn create_invite_preflight(_target: String, _channel: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/<_target>/invites/<_code>")]
-pub fn remove_invite_preflight(_target: String, _code: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/<_target>/invites")]
-pub fn fetch_invites_preflight(_target: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/join/<_code>", rank = 1)]
-pub fn invite_preflight(_code: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/create")]
-pub fn create_guild_preflight() -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/<_target>/members")]
-pub fn fetch_members_preflight(_target: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/<_target>/members/<_other>")]
-pub fn fetch_member_preflight(_target: String, _other: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/<_target>/members/<_other>/ban")]
-pub fn ban_member_preflight(_target: String, _other: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
diff --git a/src/routes/mod.rs b/src/routes/mod.rs
index 499fd89d4d3bba7dd538706c63460676862af684..17e93b4a85010cf31d381e9bd784a55707239d91 100644
--- a/src/routes/mod.rs
+++ b/src/routes/mod.rs
@@ -49,21 +49,25 @@ use rocket::http::ContentType;
 use rocket::request::Request;
 use std::io::Cursor;
 
-impl<'a> rocket::response::Responder<'a> for Permission {
-    fn respond_to(self, _: &Request) -> rocket::response::Result<'a> {
+use rocket::response::{Responder, Result};
+
+impl<'a> Responder<'a, 'static> for Permission {
+    fn respond_to(self, _: &Request) -> Result<'static> {
+        let body = format!(
+            "{{\"error\":\"Lacking permission: {:?}.\",\"permission\":{}}}",
+            self, self as u32,
+        );
+
         rocket::response::Response::build()
             .header(ContentType::JSON)
-            .sized_body(Cursor::new(format!(
-                "{{\"error\":\"Lacking permission: {:?}.\",\"permission\":{}}}",
-                self, self as u32,
-            )))
+            .sized_body(body.len(), Cursor::new(body))
             .ok()
     }
 }
 
 pub fn mount(rocket: Rocket) -> Rocket {
     rocket
-        .mount("/", routes![root::root, root::root_preflight, root::teapot])
+        .mount("/", routes![root::root, root::teapot])
         .mount(
             "/account",
             routes![
@@ -72,11 +76,6 @@ pub fn mount(rocket: Rocket) -> Rocket {
                 account::resend_email,
                 account::login,
                 account::token,
-                account::create_preflight,
-                account::verify_email_preflight,
-                account::resend_email_preflight,
-                account::login_preflight,
-                account::token_preflight,
             ],
         )
         .mount(
@@ -93,12 +92,6 @@ pub fn mount(rocket: Rocket) -> Rocket {
                 user::remove_friend,
                 user::block_user,
                 user::unblock_user,
-                user::user_preflight,
-                user::query_preflight,
-                user::dms_preflight,
-                user::dm_preflight,
-                user::friend_preflight,
-                user::block_user_preflight,
             ],
         )
         .mount(
@@ -114,11 +107,6 @@ pub fn mount(rocket: Rocket) -> Rocket {
                 channel::send_message,
                 channel::edit_message,
                 channel::delete_message,
-                channel::create_group_preflight,
-                channel::channel_preflight,
-                channel::member_preflight,
-                channel::messages_preflight,
-                channel::message_preflight,
             ],
         )
         .mount(
@@ -139,16 +127,6 @@ pub fn mount(rocket: Rocket) -> Rocket {
                 guild::kick_member,
                 guild::ban_member,
                 guild::unban_member,
-                guild::guild_preflight,
-                guild::create_channel_preflight,
-                guild::create_invite_preflight,
-                guild::remove_invite_preflight,
-                guild::fetch_invites_preflight,
-                guild::invite_preflight,
-                guild::create_guild_preflight,
-                guild::fetch_members_preflight,
-                guild::fetch_member_preflight,
-                guild::ban_member_preflight,
             ],
         )
 }
diff --git a/src/routes/root.rs b/src/routes/root.rs
index af33c5ee516da6c342e866c299288a0279f96085..cc38e8c547bb8855899abe0bc689cd2a8dfe37e4 100644
--- a/src/routes/root.rs
+++ b/src/routes/root.rs
@@ -5,7 +5,7 @@ use mongodb::bson::doc;
 
 /// root
 #[get("/")]
-pub fn root() -> Response {
+pub async fn root() -> Response {
     Response::Success(json!({
         "revolt": "0.2.11",
         "features": {
@@ -19,14 +19,9 @@ pub fn root() -> Response {
     }))
 }
 
-#[options("/")]
-pub fn root_preflight() -> Response {
-    Response::Result(super::Status::Ok)
-}
-
 /// I'm a teapot.
 #[delete("/")]
-pub fn teapot() -> Response {
+pub async fn teapot() -> Response {
     Response::Teapot(json!({
         "teapot": true,
         "can_delete": false
diff --git a/src/routes/user.rs b/src/routes/user.rs
index bf9a0ede3df37651f4329e8447ac3da9f8e2cde2..e464e82fb21659f99029f007167e0297e578bee0 100644
--- a/src/routes/user.rs
+++ b/src/routes/user.rs
@@ -8,17 +8,18 @@ use mongodb::bson::doc;
 use mongodb::options::{Collation, FindOneOptions, FindOptions};
 use rocket_contrib::json::Json;
 use serde::{Deserialize, Serialize};
+use rocket::futures::StreamExt;
 use ulid::Ulid;
 
 /// retrieve your user information
 #[get("/@me")]
-pub fn me(user: User) -> Response {
+pub async fn me(user: User) -> Response {
     Response::Success(user.serialise(Relationship::SELF as i32))
 }
 
 /// retrieve another user's information
 #[get("/<target>")]
-pub fn user(user: User, target: User) -> Response {
+pub async fn user(user: User, target: User) -> Response {
     let relationship = get_relationship(&user, &target) as i32;
     Response::Success(user.serialise(relationship))
 }
@@ -30,7 +31,7 @@ pub struct UserQuery {
 
 /// find a user by their username
 #[post("/query", data = "<query>")]
-pub fn query(user: User, query: Json<UserQuery>) -> Response {
+pub async fn query(user: User, query: Json<UserQuery>) -> Response {
     let col = database::get_collection("users");
 
     if let Ok(result) = col.find_one(
@@ -38,7 +39,8 @@ pub fn query(user: User, query: Json<UserQuery>) -> Response {
         FindOneOptions::builder()
             .collation(Collation::builder().locale("en").strength(2).build())
             .build(),
-    ) {
+    )
+    .await {
         if let Some(doc) = result {
             let id = doc.get_str("_id").unwrap();
             Response::Success(json!({
@@ -96,10 +98,10 @@ pub fn lookup(user: User, query: Json<LookupQuery>) -> Response {
 
 /// retrieve all of your DMs
 #[get("/@me/dms")]
-pub fn dms(user: User) -> Response {
+pub async fn dms(user: User) -> Response {
     let col = database::get_collection("channels");
 
-    if let Ok(results) = col.find(
+    if let Ok(mut results) = col.find(
         doc! {
             "$or": [
                 {
@@ -113,9 +115,10 @@ pub fn dms(user: User) -> Response {
             "recipients": user.id
         },
         FindOptions::builder().projection(doc! {}).build(),
-    ) {
+    )
+    .await {
         let mut channels = Vec::new();
-        for item in results {
+        while let Some(item) = results.next().await {
             if let Ok(doc) = item {
                 let id = doc.get_str("_id").unwrap();
                 let last_message = doc.get_document("last_message").unwrap();
@@ -153,13 +156,14 @@ pub fn dms(user: User) -> Response {
 
 /// open a DM with a user
 #[get("/<target>/dm")]
-pub fn dm(user: User, target: User) -> Response {
+pub async fn dm(user: User, target: User) -> Response {
     let col = database::get_collection("channels");
 
     if let Ok(result) = col.find_one(
 		doc! { "type": channel::ChannelType::DM as i32, "recipients": { "$all": [ user.id.clone(), target.id.clone() ] } },
 		None
-	) {
+	)
+    .await {
         if let Some(channel) = result {
             Response::Success( json!({ "id": channel.get_str("_id").unwrap() }))
         } else {
@@ -173,7 +177,9 @@ pub fn dm(user: User, target: User) -> Response {
 					"active": false
 				},
 				None
-			).is_ok() {
+			)
+            .await
+            .is_ok() {
                 Response::Success(json!({ "id": id.to_string() }))
             } else {
                 Response::InternalServerError(json!({ "error": "Failed to create new channel." }))
@@ -186,7 +192,7 @@ pub fn dm(user: User, target: User) -> Response {
 
 /// retrieve all of your friends
 #[get("/@me/friend")]
-pub fn get_friends(user: User) -> Response {
+pub async fn get_friends(user: User) -> Response {
     let mut results = Vec::new();
     if let Some(arr) = user.relations {
         for item in arr {
@@ -202,13 +208,13 @@ pub fn get_friends(user: User) -> Response {
 
 /// retrieve friend status with user
 #[get("/<target>/friend")]
-pub fn get_friend(user: User, target: User) -> Response {
+pub async fn get_friend(user: User, target: User) -> Response {
     Response::Success(json!({ "status": get_relationship(&user, &target) as i32 }))
 }
 
 /// create or accept a friend request
 #[put("/<target>/friend")]
-pub fn add_friend(user: User, target: User) -> Response {
+pub async fn add_friend(user: User, target: User) -> Response {
     let col = database::get_collection("users");
 
     match get_relationship(&user, &target) {
@@ -230,6 +236,7 @@ pub fn add_friend(user: User, target: User) -> Response {
                     },
                     None,
                 )
+                .await
                 .is_ok()
             {
                 if col
@@ -245,6 +252,7 @@ pub fn add_friend(user: User, target: User) -> Response {
                         },
                         None,
                     )
+                    .await
                     .is_ok()
                 {
                     /*notifications::send_message_threaded(
@@ -301,6 +309,7 @@ pub fn add_friend(user: User, target: User) -> Response {
                     },
                     None,
                 )
+                .await
                 .is_ok()
             {
                 if col
@@ -318,6 +327,7 @@ pub fn add_friend(user: User, target: User) -> Response {
                         },
                         None,
                     )
+                    .await
                     .is_ok()
                 {
                     /*notifications::send_message_threaded(
@@ -360,7 +370,7 @@ pub fn add_friend(user: User, target: User) -> Response {
 
 /// remove a friend or deny a request
 #[delete("/<target>/friend")]
-pub fn remove_friend(user: User, target: User) -> Response {
+pub async fn remove_friend(user: User, target: User) -> Response {
     let col = database::get_collection("users");
 
     match get_relationship(&user, &target) {
@@ -379,6 +389,7 @@ pub fn remove_friend(user: User, target: User) -> Response {
                     },
                     None,
                 )
+                .await
                 .is_ok()
             {
                 if col
@@ -395,6 +406,7 @@ pub fn remove_friend(user: User, target: User) -> Response {
                         },
                         None,
                     )
+                    .await
                     .is_ok()
                 {
                     /*notifications::send_message_threaded(
@@ -438,7 +450,7 @@ pub fn remove_friend(user: User, target: User) -> Response {
 
 /// block a user
 #[put("/<target>/block")]
-pub fn block_user(user: User, target: User) -> Response {
+pub async fn block_user(user: User, target: User) -> Response {
     let col = database::get_collection("users");
 
     match get_relationship(&user, &target) {
@@ -456,6 +468,7 @@ pub fn block_user(user: User, target: User) -> Response {
                     },
                     None,
                 )
+                .await
                 .is_ok()
             {
                 if col
@@ -471,6 +484,7 @@ pub fn block_user(user: User, target: User) -> Response {
                         },
                         None,
                     )
+                    .await
                     .is_ok()
                 {
                     /*notifications::send_message_threaded(
@@ -522,6 +536,7 @@ pub fn block_user(user: User, target: User) -> Response {
                     },
                     None,
                 )
+                .await
                 .is_ok()
             {
                 if col
@@ -539,6 +554,7 @@ pub fn block_user(user: User, target: User) -> Response {
                         },
                         None,
                     )
+                    .await
                     .is_ok()
                 {
                     /*notifications::send_message_threaded(
@@ -590,6 +606,7 @@ pub fn block_user(user: User, target: User) -> Response {
                     },
                     None,
                 )
+                .await
                 .is_ok()
             {
                 /*notifications::send_message_threaded(
@@ -615,7 +632,7 @@ pub fn block_user(user: User, target: User) -> Response {
 
 /// unblock a user
 #[delete("/<target>/block")]
-pub fn unblock_user(user: User, target: User) -> Response {
+pub async fn unblock_user(user: User, target: User) -> Response {
     let col = database::get_collection("users");
 
     match get_relationship(&user, &target) {
@@ -634,6 +651,7 @@ pub fn unblock_user(user: User, target: User) -> Response {
                         },
                         None,
                     )
+                    .await
                     .is_ok()
                 {
                     /*notifications::send_message_threaded(
@@ -668,6 +686,7 @@ pub fn unblock_user(user: User, target: User) -> Response {
                         },
                         None,
                     )
+                    .await
                     .is_ok()
                 {
                     if col
@@ -684,6 +703,7 @@ pub fn unblock_user(user: User, target: User) -> Response {
                             },
                             None,
                         )
+                        .await
                         .is_ok()
                     {
                         /*notifications::send_message_threaded(
@@ -730,28 +750,3 @@ pub fn unblock_user(user: User, target: User) -> Response {
         | Relationship::NONE => Response::BadRequest(json!({ "error": "This has no effect." })),
     }
 }
-
-#[options("/<_target>")]
-pub fn user_preflight(_target: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/query")]
-pub fn query_preflight() -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/@me/dms")]
-pub fn dms_preflight() -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/<_target>/dm")]
-pub fn dm_preflight(_target: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/<_target>/friend")]
-pub fn friend_preflight(_target: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
-#[options("/<_target>/block")]
-pub fn block_user_preflight(_target: String) -> Response {
-    Response::Result(super::Status::Ok)
-}
diff --git a/src/util/captcha.rs b/src/util/captcha.rs
index 3a484eb3b3f57c1dad662e575a90ff6fae661b8c..e8df55685a3421ae2eb09a2982852ca84e89391e 100644
--- a/src/util/captcha.rs
+++ b/src/util/captcha.rs
@@ -1,6 +1,6 @@
 use crate::util::variables::{HCAPTCHA_KEY, USE_HCAPTCHA};
 
-use reqwest::blocking::Client;
+use reqwest::Client;
 use serde::{Deserialize, Serialize};
 use std::collections::HashMap;
 
@@ -9,7 +9,7 @@ struct CaptchaResponse {
     success: bool,
 }
 
-pub fn verify(user_token: &Option<String>) -> Result<(), String> {
+pub async fn verify(user_token: &Option<String>) -> Result<(), String> {
     if *USE_HCAPTCHA {
         if let Some(token) = user_token {
             let mut map = HashMap::new();
@@ -21,9 +21,11 @@ pub fn verify(user_token: &Option<String>) -> Result<(), String> {
                 .post("https://hcaptcha.com/siteverify")
                 .form(&map)
                 .send()
+                .await
             {
                 let result: CaptchaResponse = response
                     .json()
+                    .await
                     .map_err(|_| "Failed to deserialise captcha result.".to_string())?;
 
                 if result.success {
diff --git a/src/util/mod.rs b/src/util/mod.rs
index abd1031434b49ca9becb1fc219295381db4e5333..9f09ffdbf78609389649c75a29c41f2499f80b7c 100644
--- a/src/util/mod.rs
+++ b/src/util/mod.rs
@@ -1,5 +1,5 @@
-use hashbrown::HashSet;
 use rand::{distributions::Alphanumeric, Rng};
+use std::collections::HashSet;
 use std::iter::FromIterator;
 
 pub mod captcha;