mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
add email for verification with duration in text (for example: you have registered for 10 days),
This commit is contained in:
parent
5f9ec065af
commit
1573b1f70c
@ -101,4 +101,6 @@ namespace controller {
|
||||
link += std::to_string(getModel()->getCode());
|
||||
return link;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -24,6 +24,7 @@ namespace controller {
|
||||
inline Poco::AutoPtr<model::table::EmailOptIn> getModel() { return _getModel<model::table::EmailOptIn>(); }
|
||||
|
||||
std::string getLink();
|
||||
inline Poco::Timespan getAge() { return Poco::DateTime() - getModel()->getCreated(); }
|
||||
|
||||
protected:
|
||||
EmailVerificationCode(model::table::EmailOptIn* dbModel);
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include "sodium.h"
|
||||
#include <assert.h>
|
||||
|
||||
// needed for memset in linux
|
||||
#include <string.h>
|
||||
@ -169,4 +170,35 @@ namespace DataTypeConverter
|
||||
mm->releaseMemory(hex);
|
||||
return hexString;
|
||||
}
|
||||
|
||||
std::string convertTimespanToLocalizedString(Poco::Timespan duration, LanguageCatalog* lang)
|
||||
{
|
||||
assert(lang);
|
||||
int value = 0;
|
||||
std::string result;
|
||||
std::string unit_name;
|
||||
if (duration.days() > 0) {
|
||||
value = duration.days();
|
||||
unit_name = "Day";
|
||||
}
|
||||
else if (duration.hours() > 0) {
|
||||
value = duration.hours();
|
||||
unit_name = "Hour";
|
||||
}
|
||||
else if (duration.minutes() > 0) {
|
||||
value = duration.minutes();
|
||||
unit_name = "Minute";
|
||||
}
|
||||
else {
|
||||
value = duration.seconds();
|
||||
unit_name = "Second";
|
||||
}
|
||||
result = std::to_string(value);
|
||||
result += " ";
|
||||
std::string unit_plural = unit_name;
|
||||
unit_plural += "s";
|
||||
result += lang->ngettext(unit_name.data(), unit_plural.data(), value);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,9 @@
|
||||
#include <string>
|
||||
#include "../SingletonManager/MemoryManager.h"
|
||||
|
||||
#include "Poco/Timespan.h"
|
||||
#include "../SingletonManager/LanguageManager.h"
|
||||
|
||||
|
||||
namespace DataTypeConverter {
|
||||
|
||||
@ -27,6 +30,9 @@ namespace DataTypeConverter {
|
||||
|
||||
|
||||
const char* numberParseStateToString(NumberParseState state);
|
||||
|
||||
//! \brief convert duration in string showing seconds, minutes, hours or days
|
||||
std::string convertTimespanToLocalizedString(Poco::Timespan duration, LanguageCatalog* lang);
|
||||
};
|
||||
|
||||
#endif // __GRADIDO_LOGIN_SERVER_LIB_DATA_TYPE_CONVERTER_H
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
|
||||
#include "../TransactionBase.h"
|
||||
|
||||
#include "../lib/DataTypeConverter.h"
|
||||
|
||||
namespace model {
|
||||
|
||||
const static char EmailText_emailVerification[] = {u8"\
|
||||
@ -18,6 +20,28 @@ Mit freundlichen Grüßen\n\
|
||||
Dario, Gradido Server Admin\n\
|
||||
"};
|
||||
|
||||
const static char EmailText_emailVerificationResend[] = { u8"\
|
||||
Hallo [first_name] [last_name],\n\
|
||||
\n\
|
||||
Du oder jemand anderes hat sich vor 7 Tagen mit dieser E-Mail Adresse bei Gradido registriert.\n\
|
||||
Wenn du es warst, klicke bitte auf den Link: [link]\n\
|
||||
oder kopiere den obigen Link in Dein Browserfenster.\n\
|
||||
\n\
|
||||
Mit freundlichen Grüßen\n\
|
||||
Dario, Gradido Server Admin\n\
|
||||
" };
|
||||
|
||||
const static char EmailText_emailVerificationResendAfterLongTime[] = { u8"\
|
||||
Hallo [first_name] [last_name],\n\
|
||||
\n\
|
||||
Du oder jemand anderes hat sich vor [duration] mit dieser E-Mail Adresse bei Gradido registriert.\n\
|
||||
Wenn du es warst, klicke bitte auf den Link: [link] um dein Konto zu aktivieren\n\
|
||||
oder kopiere den obigen Link in Dein Browserfenster.\n\
|
||||
\n\
|
||||
Mit freundlichen Grüßen\n\
|
||||
Dario, Gradido Server Admin\n\
|
||||
" };
|
||||
|
||||
const static char EmailText_emailVerificationOldElopageTransaction[] = { u8"\
|
||||
Hallo [first_name] [last_name],\n\
|
||||
\n\
|
||||
@ -132,6 +156,7 @@ Gradido Login-Server\n\
|
||||
mt.setParameter("charset", "utf-8");
|
||||
|
||||
const char* messageTemplate = nullptr;
|
||||
std::string content_string;
|
||||
|
||||
switch (mType) {
|
||||
case EMAIL_DEFAULT:
|
||||
@ -147,6 +172,8 @@ Gradido Login-Server\n\
|
||||
break;
|
||||
|
||||
case EMAIL_USER_VERIFICATION_CODE:
|
||||
case EMAIL_USER_VERIFICATION_CODE_RESEND:
|
||||
case EMAIL_USER_VERIFICATION_CODE_RESEND_AFTER_LONG_TIME:
|
||||
case EMAIL_USER_REGISTER_OLD_ELOPAGE:
|
||||
case EMAIL_ADMIN_USER_VERIFICATION_CODE:
|
||||
case EMAIL_ADMIN_USER_VERIFICATION_CODE_RESEND:
|
||||
@ -162,7 +189,13 @@ Gradido Login-Server\n\
|
||||
mailMessage->setSubject(langCatalog->gettext_str("Gradido: E-Mail Verification"));
|
||||
|
||||
messageTemplate = EmailText_emailVerification;
|
||||
if (mType == EMAIL_ADMIN_USER_VERIFICATION_CODE) {
|
||||
if (EMAIL_USER_VERIFICATION_CODE_RESEND == mType) {
|
||||
messageTemplate = EmailText_emailVerificationResend;
|
||||
}
|
||||
else if (EMAIL_USER_VERIFICATION_CODE_RESEND_AFTER_LONG_TIME == mType) {
|
||||
messageTemplate = EmailText_emailVerificationResendAfterLongTime;
|
||||
}
|
||||
else if (mType == EMAIL_ADMIN_USER_VERIFICATION_CODE) {
|
||||
messageTemplate = EmailText_adminEmailVerification;
|
||||
}
|
||||
else if (mType == EMAIL_ADMIN_USER_VERIFICATION_CODE_RESEND) {
|
||||
@ -172,14 +205,17 @@ Gradido Login-Server\n\
|
||||
messageTemplate = EmailText_emailVerificationOldElopageTransaction;
|
||||
}
|
||||
|
||||
mailMessage->addContent(
|
||||
new Poco::Net::StringPartSource(replaceUserNamesAndLink(
|
||||
langCatalog->gettext(messageTemplate),
|
||||
userTableModel->getFirstName(),
|
||||
userTableModel->getLastName(),
|
||||
mEmailVerificationCode->getLink()
|
||||
), mt.toString())
|
||||
content_string = replaceUserNamesAndLink(
|
||||
langCatalog->gettext(messageTemplate),
|
||||
userTableModel->getFirstName(),
|
||||
userTableModel->getLastName(),
|
||||
mEmailVerificationCode->getLink()
|
||||
);
|
||||
if (EMAIL_USER_VERIFICATION_CODE_RESEND_AFTER_LONG_TIME == mType) {
|
||||
content_string = replaceDuration(content_string, mEmailVerificationCode->getAge(), langCatalog);
|
||||
}
|
||||
mailMessage->addContent(new Poco::Net::StringPartSource(content_string, mt.toString()));
|
||||
|
||||
break;
|
||||
case EMAIL_USER_RESET_PASSWORD:
|
||||
if (userTableModel.isNull() || mUser->getModel()->getEmail() == "") {
|
||||
@ -292,6 +328,19 @@ Gradido Login-Server\n\
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string Email::replaceDuration(std::string src, Poco::Timespan duration, LanguageCatalog* lang)
|
||||
{
|
||||
static const char* functionName = "Email::replaceDuration";
|
||||
int findPos = src.find("[duration]");
|
||||
if (findPos != src.npos) {
|
||||
src.replace(findPos, 10, DataTypeConverter::convertTimespanToLocalizedString(duration, lang));
|
||||
}
|
||||
else {
|
||||
addError(new Error(functionName, "no duration placeholder found"));
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
EmailType Email::convertTypeFromInt(int type)
|
||||
{
|
||||
if (type >= (int)EMAIL_MAX || type <= 0) {
|
||||
|
||||
@ -24,17 +24,19 @@ namespace model {
|
||||
|
||||
enum EmailType
|
||||
{
|
||||
EMAIL_DEFAULT = 1,
|
||||
EMAIL_ERROR = 2,
|
||||
EMAIL_USER_VERIFICATION_CODE = 3,
|
||||
EMAIL_ADMIN_USER_VERIFICATION_CODE = 4,
|
||||
EMAIL_ADMIN_USER_VERIFICATION_CODE_RESEND = 5,
|
||||
EMAIL_USER_RESET_PASSWORD = 6,
|
||||
EMAIL_ADMIN_RESET_PASSWORD_REQUEST_WITHOUT_MEMORIZED_PASSPHRASE = 7,
|
||||
EMAIL_NOTIFICATION_TRANSACTION_CREATION = 8,
|
||||
EMAIL_NOTIFICATION_TRANSACTION_TRANSFER = 9,
|
||||
EMAIL_USER_REGISTER_OLD_ELOPAGE = 10,
|
||||
EMAIL_MAX = 11
|
||||
EMAIL_DEFAULT,
|
||||
EMAIL_ERROR,
|
||||
EMAIL_USER_VERIFICATION_CODE,
|
||||
EMAIL_USER_VERIFICATION_CODE_RESEND,
|
||||
EMAIL_USER_VERIFICATION_CODE_RESEND_AFTER_LONG_TIME,
|
||||
EMAIL_ADMIN_USER_VERIFICATION_CODE,
|
||||
EMAIL_ADMIN_USER_VERIFICATION_CODE_RESEND,
|
||||
EMAIL_USER_RESET_PASSWORD,
|
||||
EMAIL_ADMIN_RESET_PASSWORD_REQUEST_WITHOUT_MEMORIZED_PASSPHRASE,
|
||||
EMAIL_NOTIFICATION_TRANSACTION_CREATION,
|
||||
EMAIL_NOTIFICATION_TRANSACTION_TRANSFER,
|
||||
EMAIL_USER_REGISTER_OLD_ELOPAGE,
|
||||
EMAIL_MAX
|
||||
};
|
||||
|
||||
class Email: public ErrorList
|
||||
@ -57,6 +59,7 @@ namespace model {
|
||||
std::string replaceUserNamesAndLink(const char* src, const std::string& first_name, const std::string& last_name, const std::string& link);
|
||||
std::string replaceEmail(const char* src, const std::string& email);
|
||||
std::string replaceAmount(const char* src, Poco::Int64 gradido_cent);
|
||||
std::string replaceDuration(std::string src, Poco::Timespan duration, LanguageCatalog* lang);
|
||||
|
||||
AutoPtr<controller::EmailVerificationCode> mEmailVerificationCode;
|
||||
AutoPtr<controller::User> mUser;
|
||||
|
||||
@ -25,7 +25,7 @@ namespace model {
|
||||
}
|
||||
|
||||
EmailOptIn::EmailOptIn(const EmailOptInTuple& tuple)
|
||||
: ModelBase(tuple.get<0>()), mUserId(tuple.get<1>()), mEmailVerificationCode(tuple.get<2>()), mType(tuple.get<3>()), mResendCount(tuple.get<4>())
|
||||
: ModelBase(tuple.get<0>()), mUserId(tuple.get<1>()), mEmailVerificationCode(tuple.get<2>()), mType(tuple.get<3>()), mCreated(tuple.get<4>()), mResendCount(tuple.get<5>())
|
||||
{
|
||||
|
||||
}
|
||||
@ -53,9 +53,9 @@ namespace model {
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
|
||||
select << "SELECT id, user_id, verification_code, email_opt_in_type_id, resend_count FROM " << getTableName()
|
||||
select << "SELECT id, user_id, verification_code, email_opt_in_type_id, created, resend_count FROM " << getTableName()
|
||||
<< " where " << fieldName << " = ?"
|
||||
, into(mID), into(mUserId), into(mEmailVerificationCode), into(mType), into(mResendCount);
|
||||
, into(mID), into(mUserId), into(mEmailVerificationCode), into(mType), into(mCreated), into(mResendCount);
|
||||
|
||||
|
||||
return select;
|
||||
@ -76,7 +76,7 @@ namespace model {
|
||||
{
|
||||
Poco::Data::Statement select(session);
|
||||
|
||||
select << "SELECT id, user_id, verification_code, email_opt_in_type_id, resend_count FROM " << getTableName()
|
||||
select << "SELECT id, user_id, verification_code, email_opt_in_type_id, created, resend_count FROM " << getTableName()
|
||||
<< " where " << fieldName << " = ?";
|
||||
|
||||
|
||||
@ -90,7 +90,7 @@ namespace model {
|
||||
throw Poco::NullValueException("EmailOptIn::_loadFromDB fieldNames empty or contain only one field");
|
||||
}
|
||||
|
||||
select << "SELECT user_id, verification_code, email_opt_in_type_id, resend_count FROM " << getTableName()
|
||||
select << "SELECT user_id, verification_code, email_opt_in_type_id, created, resend_count FROM " << getTableName()
|
||||
<< " where " << fieldNames[0] << " = ? ";
|
||||
if (conditionType == MYSQL_CONDITION_AND) {
|
||||
for (int i = 1; i < fieldNames.size(); i++) {
|
||||
@ -106,7 +106,7 @@ namespace model {
|
||||
addError(new ParamError("EmailOptIn::_loadFromDB", "condition type not implemented", conditionType));
|
||||
}
|
||||
//<< " where " << fieldName << " = ?"
|
||||
select , into(mUserId), into(mEmailVerificationCode), into(mType), into(mResendCount);
|
||||
select , into(mUserId), into(mEmailVerificationCode), into(mType), into(mCreated), into(mResendCount);
|
||||
|
||||
|
||||
return select;
|
||||
|
||||
@ -17,7 +17,7 @@ namespace model {
|
||||
EMAIL_OPT_IN_REGISTER_DIRECT = 3
|
||||
};
|
||||
|
||||
typedef Poco::Tuple<int, int, Poco::UInt64, int, int> EmailOptInTuple;
|
||||
typedef Poco::Tuple<int, int, Poco::UInt64, int, Poco::DateTime, int> EmailOptInTuple;
|
||||
|
||||
class EmailOptIn : public ModelBase
|
||||
{
|
||||
@ -35,6 +35,7 @@ namespace model {
|
||||
inline Poco::UInt64 getCode() const { return mEmailVerificationCode; }
|
||||
inline int getUserId() const { return mUserId; }
|
||||
inline int getResendCount() const { Poco::ScopedLock<Poco::Mutex> _lock(mWorkMutex); return mResendCount; }
|
||||
inline Poco::DateTime getCreated() const { return mCreated; }
|
||||
inline EmailOptInType getType() const { return static_cast<EmailOptInType>(mType);}
|
||||
inline void setCode(Poco::UInt64 code) { mEmailVerificationCode = code; }
|
||||
inline void setUserId(int user_Id) { mUserId = user_Id; }
|
||||
@ -53,6 +54,7 @@ namespace model {
|
||||
// data type must be a multiple of 4
|
||||
Poco::UInt64 mEmailVerificationCode;
|
||||
int mType;
|
||||
Poco::DateTime mCreated;
|
||||
int mResendCount;
|
||||
|
||||
};
|
||||
|
||||
59
src/cpp/tasks/VerificationEmailResendTask.cpp
Normal file
59
src/cpp/tasks/VerificationEmailResendTask.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include "VerificationEmailResendTask.h"
|
||||
|
||||
#include "../controller/User.h"
|
||||
#include "../controller/EmailVerificationCode.h"
|
||||
|
||||
#include "../SingletonManager/EmailManager.h"
|
||||
|
||||
VerificationEmailResendTask::VerificationEmailResendTask(int userId)
|
||||
: mUserId(userId)
|
||||
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
VerificationEmailResendTask::~VerificationEmailResendTask()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
int VerificationEmailResendTask::run()
|
||||
{
|
||||
auto user = controller::User::create();
|
||||
if (1 == user->load(mUserId)) {
|
||||
auto model = user->getModel();
|
||||
// if email is checked, we can exit
|
||||
if (model->isEmailChecked()) {
|
||||
return 1;
|
||||
}
|
||||
auto email_verification = controller::EmailVerificationCode::load(mUserId, model::table::EMAIL_OPT_IN_REGISTER_DIRECT);
|
||||
if (nullptr == email_verification) {
|
||||
email_verification = controller::EmailVerificationCode::create(mUserId, model::table::EMAIL_OPT_IN_REGISTER_DIRECT);
|
||||
email_verification->getModel()->insertIntoDB(false);
|
||||
}
|
||||
auto em = EmailManager::getInstance();
|
||||
em->addEmail(new model::Email(email_verification, user, model::EMAIL_USER_VERIFICATION_CODE_RESEND));
|
||||
email_verification->getModel()->addResendCountAndUpdate();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
VerificationEmailResendTimerTask::VerificationEmailResendTimerTask(int userId)
|
||||
: mUserId(userId)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VerificationEmailResendTimerTask::~VerificationEmailResendTimerTask()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void VerificationEmailResendTimerTask::run()
|
||||
{
|
||||
UniLib::controller::TaskPtr verificationResendTask(new VerificationEmailResendTask(mUserId));
|
||||
verificationResendTask->scheduleTask(verificationResendTask);
|
||||
}
|
||||
37
src/cpp/tasks/VerificationEmailResendTask.h
Normal file
37
src/cpp/tasks/VerificationEmailResendTask.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef __GRADIDO_LOGIN_SERVER_VERIFICATION_EMAIL_RESEND_TIMER_TASK__H
|
||||
#define __GRADIDO_LOGIN_SERVER_VERIFICATION_EMAIL_RESEND_TIMER_TASK__H
|
||||
|
||||
#include "CPUTask.h"
|
||||
#include "Poco/Util/TimerTask.h"
|
||||
|
||||
class VerificationEmailResendTask : public UniLib::controller::CPUTask
|
||||
{
|
||||
public:
|
||||
VerificationEmailResendTask(int userId);
|
||||
~VerificationEmailResendTask();
|
||||
|
||||
|
||||
const char* getResourceType() const { return "VerificationEmailResendTask"; };
|
||||
|
||||
//! from Poco::Util::TimerTask, called from timer if the time is there
|
||||
//! load user from db, check if account is activated if not, send the email verification code a second time
|
||||
int run();
|
||||
|
||||
protected:
|
||||
int mUserId;
|
||||
|
||||
};
|
||||
|
||||
class VerificationEmailResendTimerTask : public Poco::Util::TimerTask
|
||||
{
|
||||
public:
|
||||
VerificationEmailResendTimerTask(int userId);
|
||||
~VerificationEmailResendTimerTask();
|
||||
|
||||
void run();
|
||||
|
||||
protected:
|
||||
int mUserId;
|
||||
};
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_VERIFICATION_EMAIL_RESEND_TIMER_TASK__H
|
||||
Loading…
x
Reference in New Issue
Block a user