From 9f9bc0c1ef60be550b382a78a7b1e2a6942f5e35 Mon Sep 17 00:00:00 2001 From: Dario Date: Wed, 22 Apr 2020 15:05:08 +0200 Subject: [PATCH] adding admin user password reset --- src/cpp/Crypto/KeyPair.cpp | 43 ++- src/cpp/Crypto/KeyPair.h | 2 + .../HTTPInterface/AdminUserPasswordReset.cpp | 265 ++++++++++++++++++ .../HTTPInterface/AdminUserPasswordReset.h | 20 ++ src/cpp/controller/User.cpp | 8 + src/cpp/controller/User.h | 2 +- src/cpp/controller/UserBackups.cpp | 38 +++ src/cpp/controller/UserBackups.h | 8 +- src/cpp/model/User.cpp | 27 +- src/cpp/model/email/EmailModificate.cpp | 0 src/cpp/model/email/EmailModificate.h | 12 + src/cpsp/PassphrasedTransaction.cpsp | 1 + src/cpsp/adminUserPasswordReset.cpsp | 118 ++++++++ 13 files changed, 515 insertions(+), 29 deletions(-) create mode 100644 src/cpp/HTTPInterface/AdminUserPasswordReset.cpp create mode 100644 src/cpp/HTTPInterface/AdminUserPasswordReset.h create mode 100644 src/cpp/model/email/EmailModificate.cpp create mode 100644 src/cpp/model/email/EmailModificate.h create mode 100644 src/cpsp/adminUserPasswordReset.cpsp diff --git a/src/cpp/Crypto/KeyPair.cpp b/src/cpp/Crypto/KeyPair.cpp index 17aaf87e5..a94fb3f7c 100644 --- a/src/cpp/Crypto/KeyPair.cpp +++ b/src/cpp/Crypto/KeyPair.cpp @@ -160,6 +160,16 @@ bool KeyPair::generateFromPassphrase(const char* passphrase, const Mnemonic* wor return true; } +bool KeyPair::generateFromPassphrase(const std::string& passphrase) +{ + //static bool validatePassphrase(const std::string& passphrase, Mnemonic** wordSource = nullptr); + Mnemonic* wordSource = nullptr; + if (validatePassphrase(passphrase, &wordSource)) { + return generateFromPassphrase(passphrase.data(), wordSource); + } + return false; +} + MemoryBin* KeyPair::createWordIndices(const std::string& passphrase, const Mnemonic* word_source) { auto er = ErrorManager::getInstance(); @@ -366,4 +376,35 @@ bool KeyPair::savePrivKey(int userId) bool KeyPair::isPubkeysTheSame(const unsigned char* pubkey) const { return sodium_memcmp(pubkey, mPublicKey, ed25519_pubkey_SIZE) == 0; -} \ No newline at end of file +} + +bool KeyPair::validatePassphrase(const std::string& passphrase, Mnemonic** wordSource/* = nullptr*/) +{ + std::istringstream iss(passphrase); + std::vector results(std::istream_iterator{iss}, + std::istream_iterator()); + + for (int i = 0; i < ServerConfig::Mnemonic_Types::MNEMONIC_MAX; i++) { + Mnemonic& m = ServerConfig::g_Mnemonic_WordLists[i]; + bool existAll = true; + for (auto it = results.begin(); it != results.end(); it++) { + if (*it == "\0" || *it == "" || it->size() < 3) continue; + if (!m.isWordExist(*it)) { + if (i == 1) { + int zahl = 0; + } + //printf("wordlist: %d, word not found: %s\n", i, it->data()); + existAll = false; + continue; + } + } + if (existAll) { + if (wordSource) { + *wordSource = &m; + } + + return true; + } + } + return false; +} diff --git a/src/cpp/Crypto/KeyPair.h b/src/cpp/Crypto/KeyPair.h index c2a557462..51a7076d2 100644 --- a/src/cpp/Crypto/KeyPair.h +++ b/src/cpp/Crypto/KeyPair.h @@ -29,8 +29,10 @@ public: ~KeyPair(); bool generateFromPassphrase(const char* passphrase, const Mnemonic* word_source); + bool generateFromPassphrase(const std::string& passphrase); static std::string passphraseTransform(const std::string& passphrase, const Mnemonic* currentWordSource, const Mnemonic* targetWordSource); static std::string filterPassphrase(const std::string& passphrase); + static bool validatePassphrase(const std::string& passphrase, Mnemonic** wordSource = nullptr); std::string getPubkeyHex(); bool savePrivKey(int userId); diff --git a/src/cpp/HTTPInterface/AdminUserPasswordReset.cpp b/src/cpp/HTTPInterface/AdminUserPasswordReset.cpp new file mode 100644 index 000000000..d56f16871 --- /dev/null +++ b/src/cpp/HTTPInterface/AdminUserPasswordReset.cpp @@ -0,0 +1,265 @@ +#include "AdminUserPasswordReset.h" +#include "Poco/Net/HTTPServerRequest.h" +#include "Poco/Net/HTTPServerResponse.h" +#include "Poco/Net/HTMLForm.h" +#include "Poco/DeflatingStream.h" + + +#line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + +// includes +#include "../controller/User.h" +#include "../controller/EmailVerificationCode.h" +#include "../controller/UserBackups.h" + + +enum PageState +{ + PAGE_ASK_EMAIL, + PAGE_SHOW_EMAIL +}; +#line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp" + +#include "../ServerConfig.h" + + +AdminUserPasswordReset::AdminUserPasswordReset(Session* arg): + SessionHTTPRequestHandler(arg) +{ +} + + +void AdminUserPasswordReset::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response) +{ + response.setChunkedTransferEncoding(true); + response.setContentType("text/html"); + bool _compressResponse(request.hasToken("Accept-Encoding", "gzip")); + if (_compressResponse) response.set("Content-Encoding", "gzip"); + + Poco::Net::HTMLForm form(request, request.stream()); +#line 19 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + + // code + PageState state = PAGE_ASK_EMAIL; + Poco::AutoPtr user = controller::User::create(); + Poco::AutoPtr code; + Poco::AutoPtr userBackup; + bool validUser = false; + std::string pageName = "Admin User Passwort Reset"; + + if(!form.empty()) { + auto email = form.get("user-email", ""); + + if("" != email) { + if(1 != user->load(email)) { + addError(new Error("Benutzer Email", "Konnte keinen passenden Benutzer finden!")); + } else { + validUser = true; + } + } + } + if(validUser) { + auto userId = user->getModel()->getID(); + code = controller::EmailVerificationCode::load(userId, model::table::EMAIL_OPT_IN_RESET_PASSWORD); + if(code.isNull()) { + code = controller::EmailVerificationCode::create(userId, model::table::EMAIL_OPT_IN_RESET_PASSWORD); + if(!code->getModel()->insertIntoDB(false)) { + addError(new Error("E-Mail Verification Code", "Fehler beim speichern!")); + getErrors(code->getModel()); + } + } + + auto backups = controller::UserBackups::load(userId); + auto userPubkey = user->getModel()->getPublicKey(); + for(auto it = backups.begin(); it != backups.end(); it++) { + auto keys = (*it)->getKeyPair(); + if(keys->isPubkeysTheSame(userPubkey)) { + userBackup = *it; + break; + } + } + if(userBackup.isNull()) { + addError(new Error("User Backup", "Kein passendes User Backup gefunden!")); + } + + if(!userBackup.isNull() && !code.isNull()) { + state = PAGE_SHOW_EMAIL; + } + } + + std::ostream& _responseStream = response.send(); + Poco::DeflatingOutputStream _gzipStream(_responseStream, Poco::DeflatingStreamBuf::STREAM_GZIP, 1); + std::ostream& responseStream = _compressResponse ? _gzipStream : _responseStream; + responseStream << "\n"; + // begin include header_old.cpsp + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "Gradido Login Server: "; +#line 9 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp" + responseStream << ( pageName ); + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "\t

Login Server in Entwicklung

\n"; + responseStream << "\t

Alpha "; +#line 53 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp" + responseStream << ( ServerConfig::g_versionString ); + responseStream << "

\n"; + responseStream << "
\n"; + // end include header_old.cpsp + responseStream << "\n"; + responseStream << "
\n"; + responseStream << "\t"; +#line 70 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + responseStream << ( getErrorsHtml() ); + responseStream << "\n"; + responseStream << "\t

Admin User Passwort Reset

\n"; + responseStream << "\t

Ein Benutzer hat ein Passwort Reset angefordert, hat aber seine Passphrase nicht.

\n"; + responseStream << "\t"; +#line 73 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + if(PAGE_ASK_EMAIL == state) { responseStream << "\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t\t

\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t\t\n"; + responseStream << "\t\t\t

\n"; + responseStream << "\t\t\t

\n"; + responseStream << "\t\t
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t"; +#line 83 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + } responseStream << "\n"; + responseStream << "\t"; +#line 84 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + if(validUser) { + auto userModel = user->getModel(); responseStream << "\n"; + responseStream << "\t\t

Benutzer gefunden

\n"; + responseStream << "\t\t
    \n"; + responseStream << "\t\t\t
  • "; +#line 88 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + responseStream << ( userModel->getFirstName() ); + responseStream << " "; +#line 88 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + responseStream << ( userModel->getLastName() ); + responseStream << "
  • \n"; + responseStream << "\t\t\t
  • "; +#line 89 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + responseStream << ( userModel->getEmail() ); + responseStream << "
  • \n"; + responseStream << "\t\t\t
  • Public Key: "; +#line 90 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + responseStream << ( userModel->getPublicKeyHex() ); + responseStream << "
  • \n"; + responseStream << "\t\t\t
  • E-Mail überprüft: "; +#line 91 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + responseStream << ( std::to_string(userModel->isEmailChecked()) ); + responseStream << "
  • \n"; + responseStream << "\t\t\t
  • Private Key verschlüsselt: "; +#line 92 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + responseStream << ( std::to_string(userModel->existPrivateKeyCrypted()) ); + responseStream << "
  • \n"; + responseStream << "\t\t\t
  • Passwort gesetzt: "; +#line 93 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + responseStream << ( std::to_string(userModel->getPasswordHashed() != 0) ); + responseStream << "
  • \n"; + responseStream << "\t\t
\n"; + responseStream << "\t"; +#line 95 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + } responseStream << "\n"; + responseStream << "\t"; +#line 96 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + if(PAGE_SHOW_EMAIL == state) { responseStream << "\n"; + responseStream << "\t\t
E-Mail\n"; + responseStream << "\t\t\t

An: "; +#line 98 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + responseStream << ( user->getEmailWithNames() ); + responseStream << "\n"; + responseStream << "\t\t\t

\n"; + responseStream << "
Liebe(r) ";
+#line 100 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+	responseStream << ( user->getModel()->getFirstName() );
+	responseStream << ",\n";
+	responseStream << "\n";
+	responseStream << "hier findst du deine Passphrase mit dessen Hilfe du dir ein neues Passwort einstellen kannst.\n";
+	responseStream << "Bitte schreibe sie dir auf und packe sie gut weg.\n";
+	responseStream << "\n";
+#line 105 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+	responseStream << ( userBackup->getPassphrase(ServerConfig::Mnemonic_Types::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER) );
+	responseStream << "\n";
+	responseStream << "Unter diesem Link kannst du dir mit hilfe der Passphrase ein neues Passwort setzen:\n";
+#line 109 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp"
+	responseStream << ( code->getLink() );
+	responseStream << "\n";
+	responseStream << "Liebe Grüße\n";
+	responseStream << "Dario, Softwareentwickler bei Gradido\n";
+	responseStream << "
\n"; + responseStream << "\t\t
\n"; + responseStream << "\t"; +#line 115 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\adminUserPasswordReset.cpsp" + } responseStream << "\n"; + responseStream << "
\n"; + // begin include footer.cpsp + responseStream << "\t
\n"; + responseStream << "\t\t\t"; +#line 2 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\footer.cpsp" + responseStream << ( mTimeProfiler.string() ); + responseStream << "\n"; + responseStream << "\t
\n"; + responseStream << "\n"; + responseStream << ""; + // end include footer.cpsp + responseStream << "\n"; + responseStream << "\t\n"; + if (_compressResponse) _gzipStream.close(); +} diff --git a/src/cpp/HTTPInterface/AdminUserPasswordReset.h b/src/cpp/HTTPInterface/AdminUserPasswordReset.h new file mode 100644 index 000000000..12ebbf3ca --- /dev/null +++ b/src/cpp/HTTPInterface/AdminUserPasswordReset.h @@ -0,0 +1,20 @@ +#ifndef AdminUserPasswordReset_INCLUDED +#define AdminUserPasswordReset_INCLUDED + + +#include "Poco/Net/HTTPRequestHandler.h" + + +#include "SessionHTTPRequestHandler.h" + + +class AdminUserPasswordReset: public SessionHTTPRequestHandler +{ +public: + AdminUserPasswordReset(Session*); + + void handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::HTTPServerResponse& response); +}; + + +#endif // AdminUserPasswordReset_INCLUDED diff --git a/src/cpp/controller/User.cpp b/src/cpp/controller/User.cpp index bc2d7a62c..3a8617136 100644 --- a/src/cpp/controller/User.cpp +++ b/src/cpp/controller/User.cpp @@ -92,6 +92,14 @@ namespace controller { return mPublicHex; } + std::string User::getEmailWithNames() + { + std::stringstream ss; + auto model = getModel(); + ss << model->getFirstName() << " " << model->getLastName() << "<" << model->getEmail() << ">"; + return ss.str(); + } + Poco::JSON::Object User::getJson() { auto json = getModel()->getJson(); diff --git a/src/cpp/controller/User.h b/src/cpp/controller/User.h index b8ac5f45f..fdfbddf57 100644 --- a/src/cpp/controller/User.h +++ b/src/cpp/controller/User.h @@ -35,7 +35,7 @@ namespace controller { inline const model::table::User* getModel() const { return _getModel(); } - + std::string getEmailWithNames(); const std::string& getPublicHex(); diff --git a/src/cpp/controller/UserBackups.cpp b/src/cpp/controller/UserBackups.cpp index ca3e17207..0d9a408a1 100644 --- a/src/cpp/controller/UserBackups.cpp +++ b/src/cpp/controller/UserBackups.cpp @@ -46,4 +46,42 @@ namespace controller { } + Poco::SharedPtr UserBackups::getKeyPair() + { + if (!mKeyPair.isNull()) { + return mKeyPair; + } + mKeyPair = new KeyPair; + auto model = getModel(); + auto passphrase = model->getPassphrase(); + + mKeyPair->generateFromPassphrase(passphrase); + return mKeyPair; + } + + std::string UserBackups::getPassphrase(ServerConfig::Mnemonic_Types type) + { + if ((int)type < 0 || (int)type >= ServerConfig::Mnemonic_Types::MNEMONIC_MAX) { + return ""; + } + auto passphrase = getModel()->getPassphrase(); + Mnemonic* wordSource = nullptr; + if (KeyPair::validatePassphrase(passphrase, &wordSource)) { + for (int i = 0; i < ServerConfig::Mnemonic_Types::MNEMONIC_MAX; i++) { + Mnemonic* m = &ServerConfig::g_Mnemonic_WordLists[i]; + if (m == wordSource) { + if (type == i) { + return passphrase; + } + else { + return KeyPair::passphraseTransform(passphrase, m, &ServerConfig::g_Mnemonic_WordLists[type]); + } + } + } + } + else { + return ""; + } + } + } \ No newline at end of file diff --git a/src/cpp/controller/UserBackups.h b/src/cpp/controller/UserBackups.h index b55adaa9f..780207a9d 100644 --- a/src/cpp/controller/UserBackups.h +++ b/src/cpp/controller/UserBackups.h @@ -2,6 +2,9 @@ #define GRADIDO_LOGIN_SERVER_CONTROLLER_USER_BACKUPS_INCLUDE #include "../model/table/UserBackups.h" +#include "../Crypto/KeyPair.h" + +#include "Poco/SharedPtr.h" #include "TableControllerBase.h" @@ -20,10 +23,13 @@ namespace controller { inline Poco::AutoPtr getModel() { return _getModel(); } + //! \return create keyPair from passphrase if not exist, else return existing pointer + Poco::SharedPtr getKeyPair(); + std::string getPassphrase(ServerConfig::Mnemonic_Types type); protected: UserBackups(model::table::UserBackups* dbModel); - + Poco::SharedPtr mKeyPair; }; } diff --git a/src/cpp/model/User.cpp b/src/cpp/model/User.cpp index fff3c1a9f..212a8ab69 100644 --- a/src/cpp/model/User.cpp +++ b/src/cpp/model/User.cpp @@ -550,33 +550,8 @@ std::string User::generateNewPassphrase(Mnemonic* word_source) bool User::validatePassphrase(const std::string& passphrase, Mnemonic** wordSource/* = nullptr*/) { - std::istringstream iss(passphrase); - std::vector results(std::istream_iterator{iss}, - std::istream_iterator()); + return KeyPair::validatePassphrase(passphrase, wordSource); - for (int i = 0; i < ServerConfig::Mnemonic_Types::MNEMONIC_MAX; i++) { - Mnemonic& m = ServerConfig::g_Mnemonic_WordLists[i]; - bool existAll = true; - for (auto it = results.begin(); it != results.end(); it++) { - if (*it == "\0" || *it == "" || it->size() < 3) continue; - if (!m.isWordExist(*it)) { - if (i == 1) { - int zahl = 0; - } - //printf("wordlist: %d, word not found: %s\n", i, it->data()); - existAll = false; - continue; - } - } - if (existAll) { - if (wordSource) { - *wordSource = &m; - } - - return true; - } - } - return false; } bool User::isEmptyPassword() diff --git a/src/cpp/model/email/EmailModificate.cpp b/src/cpp/model/email/EmailModificate.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/src/cpp/model/email/EmailModificate.h b/src/cpp/model/email/EmailModificate.h new file mode 100644 index 000000000..a87287b79 --- /dev/null +++ b/src/cpp/model/email/EmailModificate.h @@ -0,0 +1,12 @@ +/*! +* +* \author: einhornimmond +* +* \date: 22.04.20 +* +* \brief: make email modificateable +*/ + + +namespace model { +} \ No newline at end of file diff --git a/src/cpsp/PassphrasedTransaction.cpsp b/src/cpsp/PassphrasedTransaction.cpsp index 5f7e4b8a0..debc1f296 100644 --- a/src/cpsp/PassphrasedTransaction.cpsp +++ b/src/cpsp/PassphrasedTransaction.cpsp @@ -153,6 +153,7 @@ enum PageState {

+ <% } else if(PAGE_STATE_SUCCESS == state) { %>

Gradidos wurden erfolgreich überwiesen.

Weitere Gradidos überweisen diff --git a/src/cpsp/adminUserPasswordReset.cpsp b/src/cpsp/adminUserPasswordReset.cpsp new file mode 100644 index 000000000..870e044d7 --- /dev/null +++ b/src/cpsp/adminUserPasswordReset.cpsp @@ -0,0 +1,118 @@ +<%@ page class="AdminUserPasswordReset" %> +<%@ page form="true" %> +<%@ page compressed="true" %> +<%@ page baseClass="SessionHTTPRequestHandler" %> +<%@ page ctorArg="Session*" %> +<%@ header include="SessionHTTPRequestHandler.h" %> +<%! +// includes +#include "../controller/User.h" +#include "../controller/EmailVerificationCode.h" +#include "../controller/UserBackups.h" + + +enum PageState +{ + PAGE_ASK_EMAIL, + PAGE_SHOW_EMAIL +}; +%><%% + // code + PageState state = PAGE_ASK_EMAIL; + Poco::AutoPtr user = controller::User::create(); + Poco::AutoPtr code; + Poco::AutoPtr userBackup; + bool validUser = false; + std::string pageName = "Admin User Passwort Reset"; + + if(!form.empty()) { + auto email = form.get("user-email", ""); + + if("" != email) { + if(1 != user->load(email)) { + addError(new Error("Benutzer Email", "Konnte keinen passenden Benutzer finden!")); + } else { + validUser = true; + } + } + } + if(validUser) { + auto userId = user->getModel()->getID(); + code = controller::EmailVerificationCode::load(userId, model::table::EMAIL_OPT_IN_RESET_PASSWORD); + if(code.isNull()) { + code = controller::EmailVerificationCode::create(userId, model::table::EMAIL_OPT_IN_RESET_PASSWORD); + if(!code->getModel()->insertIntoDB(false)) { + addError(new Error("E-Mail Verification Code", "Fehler beim speichern!")); + getErrors(code->getModel()); + } + } + + auto backups = controller::UserBackups::load(userId); + auto userPubkey = user->getModel()->getPublicKey(); + for(auto it = backups.begin(); it != backups.end(); it++) { + auto keys = (*it)->getKeyPair(); + if(keys->isPubkeysTheSame(userPubkey)) { + userBackup = *it; + break; + } + } + if(userBackup.isNull()) { + addError(new Error("User Backup", "Kein passendes User Backup gefunden!")); + } + + if(!userBackup.isNull() && !code.isNull()) { + state = PAGE_SHOW_EMAIL; + } + } + +%><%@ include file="header_old.cpsp" %> +
+ <%= getErrorsHtml() %> +

Admin User Passwort Reset

+

Ein Benutzer hat ein Passwort Reset angefordert, hat aber seine Passphrase nicht.

+ <% if(PAGE_ASK_EMAIL == state) { %> +
+
+

+ + "/> +

+

+
+
+ <% } %> + <% if(validUser) { + auto userModel = user->getModel(); %> +

Benutzer gefunden

+
    +
  • <%= userModel->getFirstName() %> <%= userModel->getLastName() %>
  • +
  • <%= userModel->getEmail() %>
  • +
  • Public Key: <%= userModel->getPublicKeyHex() %>
  • +
  • E-Mail überprüft: <%= std::to_string(userModel->isEmailChecked()) %>
  • +
  • Private Key verschlüsselt: <%= std::to_string(userModel->existPrivateKeyCrypted()) %>
  • +
  • Passwort gesetzt: <%= std::to_string(userModel->getPasswordHashed() != 0) %>
  • +
+ <% } %> + <% if(PAGE_SHOW_EMAIL == state) { %> +
E-Mail +

An: <%= user->getEmailWithNames() %> +

+
Liebe(r) <%= user->getModel()->getFirstName() %>,
+
+hier findst du deine Passphrase mit dessen Hilfe du dir ein neues Passwort einstellen kannst.
+Bitte schreibe sie dir auf und packe sie gut weg.
+
+<%= userBackup->getPassphrase(ServerConfig::Mnemonic_Types::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER) %>
+
+
+Unter diesem Link kannst du dir mit hilfe der Passphrase ein neues Passwort setzen:
+<%= code->getLink() %>
+
+Liebe Grüße
+Dario, Softwareentwickler bei Gradido
+
+
+ <% } %> +
+<%@ include file="footer.cpsp" %> +