From 8801d91ee7348dd5be9a429c17a60197a8ae626c Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 10 Jul 2020 09:47:31 +0200 Subject: [PATCH] check more detailed for email verification code resend, fix double send on register, fix double send in case of multiple email verification codes for user in db --- src/cpp/SingletonManager/EmailManager.cpp | 3 +++ src/cpp/controller/User.cpp | 27 ++++++++++++++++--- src/cpp/model/Session.cpp | 2 +- src/cpp/tasks/VerificationEmailResendTask.cpp | 4 +++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/cpp/SingletonManager/EmailManager.cpp b/src/cpp/SingletonManager/EmailManager.cpp index dc6f6bdbd..2c83bebd9 100644 --- a/src/cpp/SingletonManager/EmailManager.cpp +++ b/src/cpp/SingletonManager/EmailManager.cpp @@ -111,6 +111,9 @@ int EmailManager::ThreadFunction() if (email->draft(&mailMessage, catalogs[lang_code])) { mailClientSession.sendMessage(mailMessage); + // add for debugginh + auto user_model = email->getUser()->getModel(); + printf("send email to %s\n", user_model->getEmail().data()); } else { // error drafting email, shouldn't happend diff --git a/src/cpp/controller/User.cpp b/src/cpp/controller/User.cpp index 9b59a2609..da5291052 100644 --- a/src/cpp/controller/User.cpp +++ b/src/cpp/controller/User.cpp @@ -326,7 +326,9 @@ namespace controller { select << "select u.id, v.created from users as u " << "LEFT JOIN email_opt_in as v ON(u.id = v.user_id) " << "where u.email_checked = ? " - << "AND v.resend_count <= ?", Poco::Data::Keywords::use(email_checked), Poco::Data::Keywords::use(resend_count), Poco::Data::Keywords::into(results) + << "AND v.resend_count <= ? " + << "ORDER BY u.id, v.created " , + Poco::Data::Keywords::use(email_checked), Poco::Data::Keywords::use(resend_count), Poco::Data::Keywords::into(results) ; int result_count = 0; try { @@ -344,22 +346,41 @@ namespace controller { int count_scheduled_at_once = 0; int count_scheduled = 0; + int last_user_id = 0; + // add 1 for resend task scheduled at once + // add 2 for resend task scheduled in the future + // reset if new user_id came up + int scheduledResendTask = 0; + // results sorted by user_id + //printf("results count: %d\n", results.size()); for (auto it = results.begin(); it != results.end(); it++) { auto user_id = it->get<0>(); auto created = it->get<1>(); + //auto created_str = Poco::DateTimeFormatter::format(created, "%f.%m.%y %H:%M"); + //printf("user_id: %d, created: %s\n", user_id, created_str.data()); + + if (user_id != last_user_id) { + assert(user_id > last_user_id); + last_user_id = user_id; + scheduledResendTask = 0; + } + if (scheduledResendTask == 3) continue; + auto age = now - created; // older than 7 days, schedule at once - if (age.days() > 7) { + if (age.days() > 7 && !(scheduledResendTask & 1)) { UniLib::controller::TaskPtr verificationResendTask(new VerificationEmailResendTask(user_id)); verificationResendTask->scheduleTask(verificationResendTask); count_scheduled_at_once++; + scheduledResendTask |= 1; } // younger than 7 days, schedule for created + 7 days - else { + else if(!(scheduledResendTask & 2)) { auto runDateTime = created + Poco::Timespan(7, 0, 0, 0, 0); ServerConfig::g_CronJobsTimer.schedule(new VerificationEmailResendTimerTask(user_id), Poco::Timestamp(runDateTime.timestamp())); count_scheduled++; + scheduledResendTask |= 2; } } if (count_scheduled_at_once) printf("scheduled %d verification email resend at once\n", count_scheduled_at_once); diff --git a/src/cpp/model/Session.cpp b/src/cpp/model/Session.cpp index 4b7db35a3..0139309cf 100644 --- a/src/cpp/model/Session.cpp +++ b/src/cpp/model/Session.cpp @@ -378,7 +378,7 @@ bool Session::createUserDirect(const std::string& first_name, const std::string& email_verification->getModel()->insertIntoDB(false); auto _7days_later = Poco::DateTime() + Poco::Timespan(7, 0, 0, 0, 0); - ServerConfig::g_CronJobsTimer.schedule(new VerificationEmailResendTimerTask(user_id), Poco::Timestamp(_7days_later.microsecond())); + ServerConfig::g_CronJobsTimer.schedule(new VerificationEmailResendTimerTask(user_id), Poco::Timestamp(_7days_later.timestamp())); email_manager->addEmail(new model::Email(email_verification, mNewUser, model::EMAIL_USER_VERIFICATION_CODE)); diff --git a/src/cpp/tasks/VerificationEmailResendTask.cpp b/src/cpp/tasks/VerificationEmailResendTask.cpp index f11e36c69..f72c1527c 100644 --- a/src/cpp/tasks/VerificationEmailResendTask.cpp +++ b/src/cpp/tasks/VerificationEmailResendTask.cpp @@ -33,6 +33,10 @@ int VerificationEmailResendTask::run() email_verification = controller::EmailVerificationCode::create(mUserId, model::table::EMAIL_OPT_IN_REGISTER_DIRECT); email_verification->getModel()->insertIntoDB(false); } + else if (email_verification->getModel()->getResendCount() > 1) { + // if email was already send maybe by another process, we can exit + return 1; + } else { email_verification->getModel()->addResendCountAndUpdate(); }