From 205fcbdcc16a85b80bf37d8d9e1f5e699db253a2 Mon Sep 17 00:00:00 2001 From: trisua Date: Fri, 4 Apr 2025 21:42:08 -0400 Subject: [PATCH] add: user totp 2fa --- Cargo.lock | 87 +++++++-- crates/app/Cargo.toml | 6 +- crates/app/src/langs/en-US.toml | 1 + crates/app/src/public/html/auth/login.html | 73 +++++-- .../src/public/html/communities/settings.html | 2 +- crates/app/src/public/html/components.html | 4 +- crates/app/src/public/html/mod/audit_log.html | 2 +- crates/app/src/public/html/mod/ip_bans.html | 2 +- crates/app/src/public/html/mod/reports.html | 2 +- crates/app/src/public/html/profile/base.html | 10 +- .../app/src/public/html/profile/settings.html | 179 +++++++++++++++++- crates/app/src/public/js/atto.js | 6 +- crates/app/src/public/js/me.js | 4 +- crates/app/src/routes/api/v1/auth/images.rs | 4 +- crates/app/src/routes/api/v1/auth/mod.rs | 5 + crates/app/src/routes/api/v1/auth/profile.rs | 132 ++++++++++++- crates/app/src/routes/api/v1/auth/social.rs | 2 +- .../src/routes/api/v1/communities/images.rs | 14 +- crates/app/src/routes/api/v1/mod.rs | 62 +++--- crates/core/Cargo.toml | 1 + crates/core/src/database/auth.rs | 139 +++++++++++++- crates/core/src/database/communities.rs | 29 +-- crates/core/src/database/memberships.rs | 2 +- crates/core/src/database/posts.rs | 6 +- crates/core/src/database/reactions.rs | 4 +- crates/core/src/model/auth.rs | 29 +++ crates/core/src/model/permissions.rs | 1 + crates/shared/Cargo.toml | 2 +- sql_upgrades/totp.sql | 5 + 29 files changed, 699 insertions(+), 116 deletions(-) create mode 100644 sql_upgrades/totp.sql diff --git a/Cargo.lock b/Cargo.lock index 54efba0..8b347ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -204,9 +204,9 @@ dependencies = [ [[package]] name = "axum" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d6fd624c75e18b3b4c6b9caf42b1afe24437daaee904069137d8bab077be8b8" +checksum = "de45108900e1f9b9242f7f2e254aa3e2c029c921c258fe9e6b4217eeebd54288" dependencies = [ "axum-core", "axum-macros", @@ -239,12 +239,12 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1362f362fd16024ae199c1970ce98f9661bf5ef94b9808fee734bc3698b733" +checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" dependencies = [ "bytes", - "futures-util", + "futures-core", "http", "http-body", "http-body-util", @@ -259,9 +259,9 @@ dependencies = [ [[package]] name = "axum-extra" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fc6f625a1f7705c6cf62d0d070794e94668988b1c38111baeec177c715f7b" +checksum = "45bf463831f5131b7d3c756525b305d40f1185b688565648a92e1392ca35713d" dependencies = [ "axum", "axum-core", @@ -275,6 +275,7 @@ dependencies = [ "mime", "multer", "pin-project-lite", + "rustversion", "serde", "tower", "tower-layer", @@ -307,6 +308,12 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "base32" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ce669cd6c8588f79e15cf450314f9638f967fc5770ff1c7c1deb0925ea7cfa" + [[package]] name = "base64" version = "0.22.1" @@ -616,9 +623,9 @@ dependencies = [ [[package]] name = "comrak" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5afa2702ef2fecc5bd7ca605f37e875a6be3fc8138c4633e711a945b70351550" +checksum = "2a4f05e73ca9a30af27bebc13600f91fd1651b2ec7d139ca82a89df7ca583af1" dependencies = [ "bon", "caseless", @@ -633,6 +640,12 @@ dependencies = [ "xdg", ] +[[package]] +name = "constant_time_eq" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6" + [[package]] name = "cookie" version = "0.18.1" @@ -1490,9 +1503,9 @@ dependencies = [ [[package]] name = "image" -version = "0.25.5" +version = "0.25.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd6f44aed642f18953a158afeb30206f4d50da59fbc66ecb53c66488de73563b" +checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" dependencies = [ "bytemuck", "byteorder-lite", @@ -2283,6 +2296,23 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "qrcodegen" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4339fc7a1021c9c1621d87f5e3505f2805c8c105420ba2f2a4df86814590c142" + +[[package]] +name = "qrcodegen-image" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "221b7eace1aef8c95d65dbe09fb7a1a43d006045394a89afba6997721fcb7708" +dependencies = [ + "base64", + "image", + "qrcodegen", +] + [[package]] name = "quick-error" version = "2.0.1" @@ -2808,6 +2838,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sha1_smol" version = "1.0.1" @@ -3152,6 +3193,7 @@ dependencies = [ "tetratto-shared", "tokio-postgres", "toml", + "totp-rs", ] [[package]] @@ -3416,6 +3458,23 @@ dependencies = [ "winnow", ] +[[package]] +name = "totp-rs" +version = "5.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b2f27dad992486c26b4e7455f38aa487e838d6d61b57e72906ee2b8c287a90" +dependencies = [ + "base32", + "constant_time_eq", + "hmac", + "qrcodegen-image", + "rand 0.8.5", + "sha1", + "sha2", + "url", + "urlencoding", +] + [[package]] name = "tower" version = "0.5.2" @@ -3661,6 +3720,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf-8" version = "0.7.6" diff --git a/crates/app/Cargo.toml b/crates/app/Cargo.toml index 68e9544..06c44e7 100644 --- a/crates/app/Cargo.toml +++ b/crates/app/Cargo.toml @@ -16,16 +16,16 @@ tera = "1.20.0" tracing = "0.1.41" tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } tower-http = { version = "0.6.2", features = ["trace", "fs"] } -axum = { version = "0.8.1", features = ["macros"] } +axum = { version = "0.8.3", features = ["macros"] } tokio = { version = "1.44.1", features = ["macros", "rt-multi-thread"] } -axum-extra = { version = "0.10.0", features = ["cookie", "multipart"] } +axum-extra = { version = "0.10.1", features = ["cookie", "multipart"] } tetratto-shared = { path = "../shared" } tetratto-core = { path = "../core", features = [ "redis", ], default-features = false } tetratto-l10n = { path = "../l10n" } -image = "0.25.5" +image = "0.25.6" reqwest = { version = "0.12.15", features = ["json", "stream"] } regex = "1.11.1" serde_json = "1.0.140" diff --git a/crates/app/src/langs/en-US.toml b/crates/app/src/langs/en-US.toml index 30164fe..6275570 100644 --- a/crates/app/src/langs/en-US.toml +++ b/crates/app/src/langs/en-US.toml @@ -89,6 +89,7 @@ version = "1.0.0" "settings:label.new_password" = "New password" "settings:label.change_username" = "Change username" "settings:label.new_username" = "New username" +"settings:label.two_factor_authentication" = "Two-factor authentication" "settings:label.change_avatar" = "Change avatar" "settings:label.change_banner" = "Change banner" diff --git a/crates/app/src/public/html/auth/login.html b/crates/app/src/public/html/auth/login.html index 68757d4..943676e 100644 --- a/crates/app/src/public/html/auth/login.html +++ b/crates/app/src/public/html/auth/login.html @@ -2,34 +2,68 @@ Login {% endblock %} {% block title %}Login{% endblock %} {% block content %}
-
- - +
+
+ + +
+ +
+ + +
-
- - +