From 751a21485fa43ffbe032dfff7f25be7dc21984bb Mon Sep 17 00:00:00 2001
From: Philippe Loctaux
Date: Wed, 19 Apr 2023 18:03:38 +0200
Subject: [PATCH] forgot password: email and paper key, reset password
---
Cargo.lock | 1 +
Cargo.toml | 1 +
.../get_one_from_password_reset_token.sql | 15 ++
.../users/set_password_reset_token.sql | 5 +
crates/database/sqlx-data.json | 94 +++++++++++
crates/database/src/tables/users.rs | 28 ++++
crates/ezidam/src/guards.rs | 2 +
.../ezidam/src/guards/reset_password_token.rs | 36 +++++
crates/ezidam/src/icons.rs | 8 +-
crates/ezidam/src/page.rs | 10 ++
crates/ezidam/src/routes/root.rs | 16 ++
.../ezidam/src/routes/root/forgot_password.rs | 150 ++++++++++++++++++
.../ezidam/src/routes/root/reset_password.rs | 81 ++++++++++
.../templates/pages/forgot-password.html.tera | 96 +++++++++++
.../templates/pages/oauth/authorize.html.tera | 2 +-
.../templates/pages/reset-password.html.tera | 56 +++++++
crates/hash/Cargo.toml | 2 +-
crates/users/Cargo.toml | 1 +
crates/users/src/database.rs | 29 +++-
crates/users/src/lib.rs | 4 +
crates/users/src/password_reset.rs | 55 +++++++
21 files changed, 688 insertions(+), 4 deletions(-)
create mode 100644 crates/database/queries/users/get_one_from_password_reset_token.sql
create mode 100644 crates/database/queries/users/set_password_reset_token.sql
create mode 100644 crates/ezidam/src/guards/reset_password_token.rs
create mode 100644 crates/ezidam/src/routes/root/forgot_password.rs
create mode 100644 crates/ezidam/src/routes/root/reset_password.rs
create mode 100644 crates/ezidam/templates/pages/forgot-password.html.tera
create mode 100644 crates/ezidam/templates/pages/reset-password.html.tera
create mode 100644 crates/users/src/password_reset.rs
diff --git a/Cargo.lock b/Cargo.lock
index 374923d..d2d680d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3279,6 +3279,7 @@ dependencies = [
"chrono",
"database",
"email_address",
+ "gen_passphrase",
"hash",
"id",
"serde",
diff --git a/Cargo.toml b/Cargo.toml
index a38a89b..c775884 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,6 +14,7 @@ serde_json = "1"
nanoid = "0.4"
nanoid-dictionary = "0.4"
email_address = { version = "0.2", default-features = false }
+gen_passphrase = "0.1.1"
[profile.dev.package.sqlx-macros]
opt-level = 3
diff --git a/crates/database/queries/users/get_one_from_password_reset_token.sql b/crates/database/queries/users/get_one_from_password_reset_token.sql
new file mode 100644
index 0000000..e2ff3c7
--- /dev/null
+++ b/crates/database/queries/users/get_one_from_password_reset_token.sql
@@ -0,0 +1,15 @@
+select id,
+ created_at as "created_at: DateTime",
+ updated_at as "updated_at: DateTime",
+ is_admin as "is_admin: bool",
+ username,
+ name,
+ email,
+ password,
+ password_recover,
+ paper_key,
+ is_archived as "is_archived: bool",
+ timezone
+from users
+
+where password_recover is (?)
diff --git a/crates/database/queries/users/set_password_reset_token.sql b/crates/database/queries/users/set_password_reset_token.sql
new file mode 100644
index 0000000..21cba34
--- /dev/null
+++ b/crates/database/queries/users/set_password_reset_token.sql
@@ -0,0 +1,5 @@
+update users
+
+set password_recover = ?
+
+where id is ?
\ No newline at end of file
diff --git a/crates/database/sqlx-data.json b/crates/database/sqlx-data.json
index 4c076ba..69b1c18 100644
--- a/crates/database/sqlx-data.json
+++ b/crates/database/sqlx-data.json
@@ -110,6 +110,16 @@
},
"query": "update apps\n\nset is_archived = 1\n\nwhere id is ?"
},
+ "32d35bdd1f4cf64ce0ff7beb7a11591e0f35eab7211692bcde8230c68e4cedf3": {
+ "describe": {
+ "columns": [],
+ "nullable": [],
+ "parameters": {
+ "Right": 2
+ }
+ },
+ "query": "update users\n\nset password_recover = ?\n\nwhere id is ?"
+ },
"35de1a35e6cf6c683a1b2ca3605791aea9cbb852ac1d3df151cc21c341046361": {
"describe": {
"columns": [
@@ -284,6 +294,90 @@
},
"query": "update users\n\nset username = ?\n\nwhere id is ?"
},
+ "56a88e7e68cfa94a055008510e3bc4389d7a7f64b43479d5fc8e4495ade0f84a": {
+ "describe": {
+ "columns": [
+ {
+ "name": "id",
+ "ordinal": 0,
+ "type_info": "Text"
+ },
+ {
+ "name": "created_at: DateTime",
+ "ordinal": 1,
+ "type_info": "Text"
+ },
+ {
+ "name": "updated_at: DateTime",
+ "ordinal": 2,
+ "type_info": "Text"
+ },
+ {
+ "name": "is_admin: bool",
+ "ordinal": 3,
+ "type_info": "Int64"
+ },
+ {
+ "name": "username",
+ "ordinal": 4,
+ "type_info": "Text"
+ },
+ {
+ "name": "name",
+ "ordinal": 5,
+ "type_info": "Text"
+ },
+ {
+ "name": "email",
+ "ordinal": 6,
+ "type_info": "Text"
+ },
+ {
+ "name": "password",
+ "ordinal": 7,
+ "type_info": "Text"
+ },
+ {
+ "name": "password_recover",
+ "ordinal": 8,
+ "type_info": "Text"
+ },
+ {
+ "name": "paper_key",
+ "ordinal": 9,
+ "type_info": "Text"
+ },
+ {
+ "name": "is_archived: bool",
+ "ordinal": 10,
+ "type_info": "Int64"
+ },
+ {
+ "name": "timezone",
+ "ordinal": 11,
+ "type_info": "Text"
+ }
+ ],
+ "nullable": [
+ false,
+ false,
+ false,
+ false,
+ false,
+ true,
+ true,
+ true,
+ true,
+ true,
+ false,
+ false
+ ],
+ "parameters": {
+ "Right": 1
+ }
+ },
+ "query": "select id,\n created_at as \"created_at: DateTime\",\n updated_at as \"updated_at: DateTime\",\n is_admin as \"is_admin: bool\",\n username,\n name,\n email,\n password,\n password_recover,\n paper_key,\n is_archived as \"is_archived: bool\",\n timezone\nfrom users\n\nwhere password_recover is (?)\n"
+ },
"56a9c0dff010858189a95087d014c7d0ce930da5d841b9d788a9c0e84b580bc6": {
"describe": {
"columns": [
diff --git a/crates/database/src/tables/users.rs b/crates/database/src/tables/users.rs
index 0173cb3..46d348b 100644
--- a/crates/database/src/tables/users.rs
+++ b/crates/database/src/tables/users.rs
@@ -97,6 +97,20 @@ impl Users {
.map_err(handle_error)
}
+ pub async fn get_one_from_password_reset_token(
+ conn: impl SqliteExecutor<'_>,
+ token: &str,
+ ) -> Result