From c031ae9f2fcf3440187a322202888dfd19fa644b Mon Sep 17 00:00:00 2001
From: Jean-Christophe BEGUE <jean-Christophe.begue@fraudbuster.mobi>
Date: Fri, 10 Aug 2018 15:21:42 +0200
Subject: [PATCH 1/2] Make password hints available in the error message #85

---
 .env                     |  3 +++
 src/api/core/accounts.rs | 20 ++++++++++++++++++++
 src/api/core/mod.rs      |  1 +
 src/main.rs              |  3 +++
 4 files changed, 27 insertions(+)

diff --git a/.env b/.env
index 0c231d74..735724ee 100644
--- a/.env
+++ b/.env
@@ -27,6 +27,9 @@
 ## The change only applies when the password is changed
 # PASSWORD_ITERATIONS=100000
 
+## Whether password hint should be sent into the error response when the client request it
+# SHOW_PASSWORD_HINT=true
+
 ## Domain settings
 ## The domain must match the address from where you access the server
 ## Unless you are using U2F, or having problems with attachments not downloading, there is no need to change this
diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs
index 03315d6b..41cccaae 100644
--- a/src/api/core/accounts.rs
+++ b/src/api/core/accounts.rs
@@ -247,3 +247,23 @@ fn revision_date(headers: Headers) -> String {
     let revision_date = headers.user.updated_at.timestamp();
     revision_date.to_string()
 }
+
+#[derive(Deserialize)]
+#[allow(non_snake_case)]
+struct PasswordHintData {
+    Email: String,
+}
+
+#[post("/accounts/password-hint", data = "<data>")]
+fn password_hint(data: JsonUpcase<PasswordHintData>, conn: DbConn) -> EmptyResult {
+    let data: PasswordHintData = data.into_inner().data;
+
+    if !CONFIG.show_password_hint {
+        return Ok(())
+    }
+
+    match User::find_by_mail(&data.Email, &conn) {
+        Some(user) => err!(user.password_hint.to_owned().unwrap_or("".to_string())),
+        None => Ok(()),
+    }
+}
diff --git a/src/api/core/mod.rs b/src/api/core/mod.rs
index 513319bc..5ce63062 100644
--- a/src/api/core/mod.rs
+++ b/src/api/core/mod.rs
@@ -23,6 +23,7 @@ pub fn routes() -> Vec<Route> {
         post_email,
         delete_account,
         revision_date,
+        password_hint,
 
         sync,
 
diff --git a/src/main.rs b/src/main.rs
index 59840b9c..4a42452d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -169,6 +169,7 @@ pub struct Config {
     local_icon_extractor: bool,
     signups_allowed: bool,
     password_iterations: i32,
+    show_password_hint: bool,
     domain: String,
     domain_set: bool,
 }
@@ -197,6 +198,8 @@ impl Config {
             local_icon_extractor: util::parse_option_string(env::var("LOCAL_ICON_EXTRACTOR").ok()).unwrap_or(false),
             signups_allowed: util::parse_option_string(env::var("SIGNUPS_ALLOWED").ok()).unwrap_or(true),
             password_iterations: util::parse_option_string(env::var("PASSWORD_ITERATIONS").ok()).unwrap_or(100_000),
+            show_password_hint: util::parse_option_string(env::var("SHOW_PASSWORD_HINT").ok()).unwrap_or(true),
+
             domain_set: domain.is_ok(),
             domain: domain.unwrap_or("http://localhost".into()),
         }

From d3b4b10d18572ff0a6e1568481ec65f4317a4346 Mon Sep 17 00:00:00 2001
From: Jean-Christophe BEGUE <jean-Christophe.begue@fraudbuster.mobi>
Date: Fri, 10 Aug 2018 16:59:23 +0200
Subject: [PATCH 2/2] Add a explaination to the password hint message #85

---
 src/api/core/accounts.rs | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/api/core/accounts.rs b/src/api/core/accounts.rs
index 41cccaae..e45c08dc 100644
--- a/src/api/core/accounts.rs
+++ b/src/api/core/accounts.rs
@@ -263,7 +263,10 @@ fn password_hint(data: JsonUpcase<PasswordHintData>, conn: DbConn) -> EmptyResul
     }
 
     match User::find_by_mail(&data.Email, &conn) {
-        Some(user) => err!(user.password_hint.to_owned().unwrap_or("".to_string())),
+        Some(user) => {
+            let hint = user.password_hint.to_owned().unwrap_or_default();
+            err!(format!("Your password hint is: {}", hint))
+        },
         None => Ok(()),
     }
 }