Rewrote Frontend
This commit is contained in:
		
							
								
								
									
										21
									
								
								backend/SMTPMail-drogon-master/LICENSE
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								backend/SMTPMail-drogon-master/LICENSE
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
MIT License
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2020 ihmc3jn09hk
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
SOFTWARE.
 | 
			
		||||
							
								
								
									
										79
									
								
								backend/SMTPMail-drogon-master/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								backend/SMTPMail-drogon-master/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
			
		||||
# SMTPMail-drogon
 | 
			
		||||
Simple Mail for the Drogon framework.
 | 
			
		||||
 | 
			
		||||
It is made as a plugin for the [drogon](https://github.com/an-tao/drogon) framework.
 | 
			
		||||
It can be included into the drogon build with little
 | 
			
		||||
modification of the class declaration.
 | 
			
		||||
## Updates 
 | 
			
		||||
- **[ 13-06-2022 ] Fixed vulnerability issues reported by [Sam](https://snoopysecurity.github.io/about).**
 | 
			
		||||
- [ 13-09-2021 ] Added [HTML content support](https://github.com/ihmc3jn09hk/SMTPMail-drogon/pull/1).
 | 
			
		||||
- [ 23-12-2020 ] Added DNS support.
 | 
			
		||||
 | 
			
		||||
## Acknowledgement
 | 
			
		||||
* The implementation takes SMTPClient for Qt from [kelvins](https://github.com/kelvins/SMTPClient) as reference.
 | 
			
		||||
* There requires a delay SSL encryption from the Tcp-socket (named TcpClient in trantor/drogon) and the major
 | 
			
		||||
author of drogon [reponsed](https://github.com/an-tao/drogon/issues/346) quickly.
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
Download to the plugin directory of the target drogon app, E.g. ~/drogon-app/plugins
 | 
			
		||||
```bash
 | 
			
		||||
$ git clone https://github.com/ihmc3jn09hk/SMTPMail-drogon.git
 | 
			
		||||
$ cp SMTPMail-drogon/SMTPMail.* ~/drogon-app/plugins
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
* _Be aware of add the plugin into the config.json. Set the "name" field to "SMTPMail"_
 | 
			
		||||
 | 
			
		||||
Add the reference header and get the plugin from the app(), E.g.
 | 
			
		||||
 | 
			
		||||
```c++
 | 
			
		||||
...
 | 
			
		||||
#include "../plugins/SMTPMail.h"
 | 
			
		||||
...
 | 
			
		||||
 | 
			
		||||
//Inside some function, E.g. A controller function.
 | 
			
		||||
...
 | 
			
		||||
//Send an email
 | 
			
		||||
auto *smtpmailPtr = app().getPlugin<SMTPMail>();
 | 
			
		||||
auto id = smtpmailPtr->sendEmail(
 | 
			
		||||
          "127.0.0.1",                  //The server IP/DNS
 | 
			
		||||
          587,                          //The port
 | 
			
		||||
          "mailer@something.com",       //Who send the email
 | 
			
		||||
          "receiver@otherthing.com",    //Send to whom
 | 
			
		||||
          "Testing SMTPMail Function",  //Email Subject/Title
 | 
			
		||||
          "Hello from drogon plugin",   //Content
 | 
			
		||||
          "mailer@something.com",       //Login user
 | 
			
		||||
          "123456",                     //User password
 | 
			
		||||
          false                         //Is HTML content
 | 
			
		||||
          );
 | 
			
		||||
...
 | 
			
		||||
//Or get noted when email is sent
 | 
			
		||||
...
 | 
			
		||||
void callback(const std::string &msg)
 | 
			
		||||
{
 | 
			
		||||
  LOG_INFO << msg; /*Output e.g. "EMail sent. ID : 96ESERVDDFH17588ECF0C7B00326E3"*/
 | 
			
		||||
  /*Do whatever you like*/
 | 
			
		||||
}
 | 
			
		||||
...
 | 
			
		||||
auto *smtpmailPtr = app().getPlugin<SMTPMail>();
 | 
			
		||||
auto id = smtpmailPtr->sendEmail(
 | 
			
		||||
          "127.0.0.1",                  //The server IP/DNS
 | 
			
		||||
          587,                          //The port
 | 
			
		||||
          "mailer@something.com",       //Who send the email
 | 
			
		||||
          "receiver@otherthing.com",    //Send to whom
 | 
			
		||||
          "Testing SMTPMail Function",  //Email Subject/Title
 | 
			
		||||
          "Hello from drogon plugin",   //Content
 | 
			
		||||
          "mailer@something.com",       //Login user
 | 
			
		||||
          "123456",                     //User password
 | 
			
		||||
          false,                        //Is HTML content
 | 
			
		||||
          callback                      //Callback
 | 
			
		||||
          );
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
$ cd ~/drogon-app/build
 | 
			
		||||
$ make
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Licence
 | 
			
		||||
* Feel free to use, thanks to open-source.
 | 
			
		||||
* For the sake of concern on commercial usage, a simple licence is included in each of the files.
 | 
			
		||||
							
								
								
									
										400
									
								
								backend/SMTPMail-drogon-master/SMTPMail.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										400
									
								
								backend/SMTPMail-drogon-master/SMTPMail.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,400 @@
 | 
			
		||||
/**
 | 
			
		||||
*
 | 
			
		||||
* SMTPMail.cc *
 | 
			
		||||
*
 | 
			
		||||
* This plugin is for SMTP mail delivery for the Drogon web-framework.
 | 
			
		||||
Implementation
 | 
			
		||||
* reference from the project "SMTPClient" with Qt5 by kelvins. Please check out
 | 
			
		||||
* https://github.com/kelvins/SMTPClient.
 | 
			
		||||
 | 
			
		||||
Feel free to use the code. For the sake of any concern, the following licence is
 | 
			
		||||
attached.
 | 
			
		||||
 | 
			
		||||
 Copyright 2020 ihmc3jn09hk
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
the Software without restriction, including without limitation the rights to
 | 
			
		||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "SMTPMail.h"
 | 
			
		||||
#include <drogon/HttpAppFramework.h>
 | 
			
		||||
#include <drogon/utils/Utilities.h>
 | 
			
		||||
#include <trantor/net/EventLoopThread.h>
 | 
			
		||||
#include <trantor/net/TcpClient.h>
 | 
			
		||||
 | 
			
		||||
using namespace drogon;
 | 
			
		||||
using namespace trantor;
 | 
			
		||||
 | 
			
		||||
struct EMail {
 | 
			
		||||
  enum states {
 | 
			
		||||
    Init,
 | 
			
		||||
    HandShake,
 | 
			
		||||
    Tls,
 | 
			
		||||
    Auth,
 | 
			
		||||
    User,
 | 
			
		||||
    Pass,
 | 
			
		||||
    Mail,
 | 
			
		||||
    Rcpt,
 | 
			
		||||
    Data,
 | 
			
		||||
    Body,
 | 
			
		||||
    Quit,
 | 
			
		||||
    Close
 | 
			
		||||
  };
 | 
			
		||||
  std::string m_from;
 | 
			
		||||
  std::string m_to;
 | 
			
		||||
  std::string m_subject;
 | 
			
		||||
  std::string m_content;
 | 
			
		||||
  std::string m_user;
 | 
			
		||||
  std::string m_passwd;
 | 
			
		||||
  states m_status;
 | 
			
		||||
  std::string m_uuid;
 | 
			
		||||
  bool m_isHTML{false};
 | 
			
		||||
  std::shared_ptr<trantor::TcpClient> m_socket;
 | 
			
		||||
 | 
			
		||||
  EMail(std::string from, std::string to, std::string subject,
 | 
			
		||||
        std::string content, std::string user, std::string passwd, bool isHTML,
 | 
			
		||||
        std::shared_ptr<trantor::TcpClient> socket)
 | 
			
		||||
      : m_from(std::move(from)), m_to(std::move(to)),
 | 
			
		||||
        m_subject(std::move(subject)), m_content(std::move(content)),
 | 
			
		||||
        m_user(std::move(user)), m_passwd(std::move(passwd)),
 | 
			
		||||
        m_socket(std::move(socket)), m_isHTML(isHTML),
 | 
			
		||||
        m_uuid(drogon::utils::getUuid()) {
 | 
			
		||||
    m_status = Init;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ~EMail() = default;
 | 
			
		||||
 | 
			
		||||
  static std::unordered_map<std::string, std::shared_ptr<EMail>>
 | 
			
		||||
      m_emails; // Container for processing emails
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
std::unordered_map<std::string, std::shared_ptr<EMail>> EMail::m_emails;
 | 
			
		||||
 | 
			
		||||
void SMTPMail::initAndStart(const Json::Value &config) {
 | 
			
		||||
  /// Initialize and start the plugin
 | 
			
		||||
  LOG_INFO << "SMTPMail initialized and started";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SMTPMail::shutdown() {
 | 
			
		||||
  /// Shutdown the plugin
 | 
			
		||||
  LOG_INFO << "STMPMail shutdown";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void messagesHandle(const trantor::TcpConnectionPtr &connPtr,
 | 
			
		||||
                    trantor::MsgBuffer *msg,
 | 
			
		||||
                    const std::shared_ptr<EMail> &email,
 | 
			
		||||
                    const std::function<void(const std::string &msg)> &cb) {
 | 
			
		||||
  std::string receivedMsg;
 | 
			
		||||
  while (msg->readableBytes() > 0) {
 | 
			
		||||
    std::string buf(msg->peek(), msg->readableBytes());
 | 
			
		||||
    receivedMsg.append(buf);
 | 
			
		||||
    //        LOG_INFO << buf;
 | 
			
		||||
    msg->retrieveAll();
 | 
			
		||||
  }
 | 
			
		||||
  LOG_TRACE << "receive: " << receivedMsg;
 | 
			
		||||
  std::string responseCode(receivedMsg.begin(), receivedMsg.begin() + 3);
 | 
			
		||||
  //    std::string responseMsg(receivedMsg.begin() + 4, receivedMsg.end());
 | 
			
		||||
 | 
			
		||||
  if (email->m_status == EMail::Init && responseCode == "220") {
 | 
			
		||||
    std::string outMsg;
 | 
			
		||||
    trantor::MsgBuffer out;
 | 
			
		||||
 | 
			
		||||
    outMsg.append("EHLO smtpclient.qw");
 | 
			
		||||
    outMsg.append("\r\n");
 | 
			
		||||
 | 
			
		||||
    out.append(outMsg.data(), outMsg.size());
 | 
			
		||||
 | 
			
		||||
    connPtr->send(std::move(out));
 | 
			
		||||
 | 
			
		||||
    email->m_status = EMail::HandShake;
 | 
			
		||||
  } else if (email->m_status == EMail::HandShake && responseCode == "220") {
 | 
			
		||||
    std::string outMsg;
 | 
			
		||||
    trantor::MsgBuffer out;
 | 
			
		||||
 | 
			
		||||
    outMsg.append("EHLO smtpclient.qw");
 | 
			
		||||
    outMsg.append("\r\n");
 | 
			
		||||
 | 
			
		||||
    out.append(outMsg.data(), outMsg.size());
 | 
			
		||||
 | 
			
		||||
    connPtr->startClientEncryption(
 | 
			
		||||
        [connPtr, out]() {
 | 
			
		||||
          // LOG_TRACE << "SSL established";
 | 
			
		||||
          connPtr->send(out);
 | 
			
		||||
        },
 | 
			
		||||
        false, false);
 | 
			
		||||
 | 
			
		||||
    email->m_status = EMail::Auth;
 | 
			
		||||
  } else if (email->m_status == EMail::HandShake && responseCode == "250") {
 | 
			
		||||
    std::string outMsg;
 | 
			
		||||
    trantor::MsgBuffer out;
 | 
			
		||||
 | 
			
		||||
    outMsg.append("STARTTLS");
 | 
			
		||||
    outMsg.append("\r\n");
 | 
			
		||||
 | 
			
		||||
    out.append(outMsg.data(), outMsg.size());
 | 
			
		||||
 | 
			
		||||
    connPtr->send(std::move(out));
 | 
			
		||||
 | 
			
		||||
    email->m_status = EMail::HandShake;
 | 
			
		||||
  } else if (email->m_status == EMail::Auth && responseCode == "250") {
 | 
			
		||||
    trantor::MsgBuffer out;
 | 
			
		||||
    std::string outMsg;
 | 
			
		||||
 | 
			
		||||
    outMsg.append("AUTH LOGIN");
 | 
			
		||||
    outMsg.append("\r\n");
 | 
			
		||||
 | 
			
		||||
    out.append(outMsg.data(), outMsg.size());
 | 
			
		||||
 | 
			
		||||
    connPtr->send(std::move(out));
 | 
			
		||||
 | 
			
		||||
    email->m_status = EMail::User;
 | 
			
		||||
  } else if (email->m_status == EMail::User && responseCode == "334") {
 | 
			
		||||
    trantor::MsgBuffer out;
 | 
			
		||||
    std::string outMsg;
 | 
			
		||||
 | 
			
		||||
    std::string secret(email->m_user);
 | 
			
		||||
 | 
			
		||||
    // outMsg.append(base64_encode(reinterpret_cast<const unsigned
 | 
			
		||||
    // char*>(secret.c_str()), secret.length()));
 | 
			
		||||
    outMsg.append(drogon::utils::base64Encode(
 | 
			
		||||
        reinterpret_cast<const unsigned char *>(secret.c_str()),
 | 
			
		||||
        secret.length()));
 | 
			
		||||
 | 
			
		||||
    outMsg.append("\r\n");
 | 
			
		||||
 | 
			
		||||
    out.append(outMsg.data(), outMsg.size());
 | 
			
		||||
 | 
			
		||||
    connPtr->send(std::move(out));
 | 
			
		||||
 | 
			
		||||
    email->m_status = EMail::Pass;
 | 
			
		||||
  } else if (email->m_status == EMail::Pass && responseCode == "334") {
 | 
			
		||||
    trantor::MsgBuffer out;
 | 
			
		||||
    std::string outMsg;
 | 
			
		||||
 | 
			
		||||
    std::string secret(email->m_passwd);
 | 
			
		||||
 | 
			
		||||
    outMsg.append(drogon::utils::base64Encode(
 | 
			
		||||
        reinterpret_cast<const unsigned char *>(secret.c_str()),
 | 
			
		||||
        secret.length()));
 | 
			
		||||
    outMsg.append("\r\n");
 | 
			
		||||
 | 
			
		||||
    out.append(outMsg.data(), outMsg.size());
 | 
			
		||||
 | 
			
		||||
    connPtr->send(std::move(out));
 | 
			
		||||
 | 
			
		||||
    email->m_status = EMail::Mail;
 | 
			
		||||
  } else if (email->m_status == EMail::Mail && responseCode == "235") {
 | 
			
		||||
    trantor::MsgBuffer out;
 | 
			
		||||
    std::string outMsg;
 | 
			
		||||
 | 
			
		||||
    outMsg.append("MAIL FROM:<");
 | 
			
		||||
    outMsg.append(email->m_from);
 | 
			
		||||
    outMsg.append(">\r\n");
 | 
			
		||||
 | 
			
		||||
    out.append(outMsg.data(), outMsg.size());
 | 
			
		||||
 | 
			
		||||
    connPtr->send(std::move(out));
 | 
			
		||||
 | 
			
		||||
    email->m_status = EMail::Rcpt;
 | 
			
		||||
  } else if (email->m_status == EMail::Rcpt && responseCode == "250") {
 | 
			
		||||
    trantor::MsgBuffer out;
 | 
			
		||||
    std::string outMsg;
 | 
			
		||||
 | 
			
		||||
    outMsg.append("RCPT TO:<");
 | 
			
		||||
    outMsg.append(email->m_to);
 | 
			
		||||
    outMsg.append(">\r\n");
 | 
			
		||||
 | 
			
		||||
    out.append(outMsg.data(), outMsg.size());
 | 
			
		||||
 | 
			
		||||
    connPtr->send(std::move(out));
 | 
			
		||||
 | 
			
		||||
    email->m_status = EMail::Data;
 | 
			
		||||
  } else if (email->m_status == EMail::Data && responseCode == "250") {
 | 
			
		||||
    trantor::MsgBuffer out;
 | 
			
		||||
    std::string outMsg;
 | 
			
		||||
 | 
			
		||||
    outMsg.append("DATA");
 | 
			
		||||
    outMsg.append("\r\n");
 | 
			
		||||
 | 
			
		||||
    out.append(outMsg.data(), outMsg.size());
 | 
			
		||||
 | 
			
		||||
    connPtr->send(std::move(out));
 | 
			
		||||
 | 
			
		||||
    email->m_status = EMail::Body;
 | 
			
		||||
  } else if (email->m_status == EMail::Body && responseCode == "354") {
 | 
			
		||||
    trantor::MsgBuffer out;
 | 
			
		||||
    std::string outMsg;
 | 
			
		||||
    std::time_t t = std::time(nullptr);
 | 
			
		||||
    char buf[100];
 | 
			
		||||
    std::strftime(buf, 100, "%a, %d %b %Y %T %z",  std::localtime(&t));
 | 
			
		||||
 | 
			
		||||
    outMsg.append("To: " + email->m_to + "\r\n");
 | 
			
		||||
    outMsg.append("From: " + email->m_from + "\r\n");
 | 
			
		||||
    outMsg.append("Date: " + std::string(buf) + "\r\n");
 | 
			
		||||
    if (email->m_isHTML) {
 | 
			
		||||
      outMsg.append("Content-Type: text/html;\r\n");
 | 
			
		||||
    }
 | 
			
		||||
    outMsg.append("Subject: " + email->m_subject + "\r\n\r\n");
 | 
			
		||||
 | 
			
		||||
    outMsg.append(email->m_content);
 | 
			
		||||
    outMsg.append("\r\n.\r\n");
 | 
			
		||||
 | 
			
		||||
    out.append(outMsg.data(), outMsg.size());
 | 
			
		||||
 | 
			
		||||
    connPtr->send(std::move(out));
 | 
			
		||||
 | 
			
		||||
    email->m_status = EMail::Quit;
 | 
			
		||||
  } else if (email->m_status == EMail::Quit && responseCode == "250") {
 | 
			
		||||
    trantor::MsgBuffer out;
 | 
			
		||||
    std::string outMsg;
 | 
			
		||||
 | 
			
		||||
    outMsg.append("QUIT");
 | 
			
		||||
    outMsg.append("\r\n");
 | 
			
		||||
 | 
			
		||||
    out.append(outMsg.data(), outMsg.size());
 | 
			
		||||
 | 
			
		||||
    connPtr->send(std::move(out));
 | 
			
		||||
 | 
			
		||||
    email->m_status = EMail::Close;
 | 
			
		||||
  } else if (email->m_status == EMail::Close) {
 | 
			
		||||
    /*Callback here for succeed delivery is probable*/
 | 
			
		||||
    cb("EMail sent. ID : " + email->m_uuid);
 | 
			
		||||
    return;
 | 
			
		||||
  } else {
 | 
			
		||||
    email->m_status = EMail::Close;
 | 
			
		||||
    /*Callback here for notification is probable*/
 | 
			
		||||
    cb(receivedMsg);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string
 | 
			
		||||
SMTPMail::sendEmail(const std::string &mailServer, const uint16_t &port,
 | 
			
		||||
                    const std::string &from, const std::string &to,
 | 
			
		||||
                    const std::string &subject, const std::string &content,
 | 
			
		||||
                    const std::string &user, const std::string &passwd,
 | 
			
		||||
                    bool isHTML,
 | 
			
		||||
                    const std::function<void(const std::string &)> &cb) {
 | 
			
		||||
  if (mailServer.empty() || from.empty() || to.empty() || subject.empty() ||
 | 
			
		||||
      user.empty() || passwd.empty()) {
 | 
			
		||||
    LOG_WARN << "Invalid input(s) - "
 | 
			
		||||
             << "\nServer : " << mailServer << "\nPort : " << port
 | 
			
		||||
             << "\nfrom : " << from << "\nto : " << to
 | 
			
		||||
             << "\nsubject : " << subject << "\nuser : " << user
 | 
			
		||||
             << "\npasswd : " << passwd;
 | 
			
		||||
    return {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static auto hasLineBreak = [](const std::string &msg) {
 | 
			
		||||
    if (std::string::npos != msg.find_first_of("\n") ||
 | 
			
		||||
        std::string::npos != msg.find_first_of("\r")) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  if (hasLineBreak(from)) {
 | 
			
		||||
    LOG_WARN << "Invalid \"FROM\" data : " << from;
 | 
			
		||||
    return {};
 | 
			
		||||
  }
 | 
			
		||||
  if (hasLineBreak(to)) {
 | 
			
		||||
    LOG_WARN << "Invalid \"TO\" data : " << to;
 | 
			
		||||
    return {};
 | 
			
		||||
  }
 | 
			
		||||
  if (hasLineBreak(subject)) {
 | 
			
		||||
    LOG_WARN << "Invalid \"SUBJECT\" data : " << subject.data();
 | 
			
		||||
    return {};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  LOG_TRACE << "New TcpClient : " << mailServer << ":" << port;
 | 
			
		||||
 | 
			
		||||
  // Create the email
 | 
			
		||||
  auto email = std::make_shared<EMail>(from, to, subject, content, user, passwd,
 | 
			
		||||
                                       isHTML, nullptr);
 | 
			
		||||
 | 
			
		||||
  auto resolver = app().getResolver();
 | 
			
		||||
  resolver->resolve(
 | 
			
		||||
      mailServer, [email, port, cb](const trantor::InetAddress &addr) {
 | 
			
		||||
        constexpr size_t defaultLoopIdA = 10;
 | 
			
		||||
        constexpr size_t defaultLoopIdB = 9;
 | 
			
		||||
        auto loopA = app().getIOLoop(defaultLoopIdA);
 | 
			
		||||
        auto loopB = app().getIOLoop(defaultLoopIdB);
 | 
			
		||||
        
 | 
			
		||||
        if ( loopA == loopB ) {
 | 
			
		||||
          LOG_WARN << "Please provide at least 2 threads for this plugin";
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto loop = loopA->isInLoopThread() ? loopB : loopA;
 | 
			
		||||
        
 | 
			
		||||
        assert(loop);                    // Should never be null
 | 
			
		||||
        trantor::InetAddress addr_(addr.toIp(), port, false);
 | 
			
		||||
        auto tcpSocket =
 | 
			
		||||
            std::make_shared<trantor::TcpClient>(loop, addr_, "SMTPMail");
 | 
			
		||||
 | 
			
		||||
        email->m_socket = tcpSocket;
 | 
			
		||||
 | 
			
		||||
        std::weak_ptr<EMail> email_wptr = email;
 | 
			
		||||
 | 
			
		||||
        EMail::m_emails.emplace(email->m_uuid,
 | 
			
		||||
                                email); // Assuming there is no uuid collision
 | 
			
		||||
        tcpSocket->setConnectionCallback(
 | 
			
		||||
            [email_wptr](const trantor::TcpConnectionPtr &connPtr) {
 | 
			
		||||
              auto email_ptr = email_wptr.lock();
 | 
			
		||||
              if (!email_ptr) {
 | 
			
		||||
                LOG_WARN << "EMail pointer gone";
 | 
			
		||||
                return;
 | 
			
		||||
              }
 | 
			
		||||
              if (connPtr->connected()) {
 | 
			
		||||
                // send request;
 | 
			
		||||
                LOG_TRACE << "Connection established!";
 | 
			
		||||
              } else {
 | 
			
		||||
                LOG_TRACE << "Connection disconnect";
 | 
			
		||||
                EMail::m_emails.erase(
 | 
			
		||||
                    email_ptr->m_uuid); // Remove the email in list
 | 
			
		||||
                // thisPtr->onError(std::string("ReqResult::NetworkFailure"));
 | 
			
		||||
              }
 | 
			
		||||
            });
 | 
			
		||||
        tcpSocket->setConnectionErrorCallback([email_wptr]() {
 | 
			
		||||
          auto email_ptr = email_wptr.lock();
 | 
			
		||||
          if (!email_ptr) {
 | 
			
		||||
            LOG_ERROR << "EMail pointer gone";
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          // can't connect to server
 | 
			
		||||
          LOG_ERROR << "Bad Server address";
 | 
			
		||||
          EMail::m_emails.erase(email_ptr->m_uuid); // Remove the email in list
 | 
			
		||||
          // thisPtr->onError(std::string("ReqResult::BadServerAddress"));
 | 
			
		||||
        });
 | 
			
		||||
        auto cb_(cb ? cb : [](const std::string &msg) {
 | 
			
		||||
          LOG_INFO << "Default email callback : " << msg;
 | 
			
		||||
        });
 | 
			
		||||
        tcpSocket->setMessageCallback(
 | 
			
		||||
            [email_wptr, cb_](const trantor::TcpConnectionPtr &connPtr,
 | 
			
		||||
                              trantor::MsgBuffer *msg) {
 | 
			
		||||
              auto email_ptr = email_wptr.lock();
 | 
			
		||||
              if (!email_ptr) {
 | 
			
		||||
                LOG_ERROR << "EMail pointer gone";
 | 
			
		||||
                return;
 | 
			
		||||
              }
 | 
			
		||||
              // email->m_socket->disconnect();
 | 
			
		||||
              messagesHandle(connPtr, msg, email_ptr, cb_);
 | 
			
		||||
            });
 | 
			
		||||
        tcpSocket->connect(); // Start trying to send the email
 | 
			
		||||
      });
 | 
			
		||||
  return email->m_uuid;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										63
									
								
								backend/SMTPMail-drogon-master/SMTPMail.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								backend/SMTPMail-drogon-master/SMTPMail.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 *  SMTPMail.h
 | 
			
		||||
 *
 | 
			
		||||
 * This plugin is for SMTP mail delievery for the Drogon web-framework.
 | 
			
		||||
Implementation
 | 
			
		||||
 * reference from the project "SMTPClient" with Qt5 by kelvins. Please check out
 | 
			
		||||
 * https://github.com/kelvins/SMTPClient.
 | 
			
		||||
 | 
			
		||||
Copyright 2020 ihmc3jn09hk
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
 | 
			
		||||
this software and associated documentation files (the "Software"), to deal in
 | 
			
		||||
the Software without restriction, including without limitation the rights to
 | 
			
		||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 | 
			
		||||
the Software, and to permit persons to whom the Software is furnished to do so,
 | 
			
		||||
subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 | 
			
		||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 | 
			
		||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 | 
			
		||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 | 
			
		||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <drogon/plugins/Plugin.h>
 | 
			
		||||
 | 
			
		||||
class SMTPMail : public drogon::Plugin<SMTPMail> {
 | 
			
		||||
public:
 | 
			
		||||
  SMTPMail() = default;
 | 
			
		||||
  /// This method must be called by drogon to initialize and start the plugin.
 | 
			
		||||
  /// It must be implemented by the user.
 | 
			
		||||
  void initAndStart(const Json::Value &config) override;
 | 
			
		||||
 | 
			
		||||
  /// This method must be called by drogon to shutdown the plugin.
 | 
			
		||||
  /// It must be implemented by the user.
 | 
			
		||||
  void shutdown() override;
 | 
			
		||||
 | 
			
		||||
  /** Send an email
 | 
			
		||||
   * return : An ID of the email.
 | 
			
		||||
   */
 | 
			
		||||
  std::string sendEmail(
 | 
			
		||||
      const std::string
 | 
			
		||||
          &mailServer, // Mail server address/dns E.g. 127.0.0.1/smtp.mail.com
 | 
			
		||||
      const uint16_t &port,       // Port  E.g. 587
 | 
			
		||||
      const std::string &from,    // Send from whom E.g. drogon@gmail.com
 | 
			
		||||
      const std::string &to,      // Reciever       E.g. drogon@yahoo.com
 | 
			
		||||
      const std::string &subject, // The email title/subject
 | 
			
		||||
      const std::string &content, // The email content.
 | 
			
		||||
      const std::string &user,    // User      (Usually same as "from")
 | 
			
		||||
      const std::string &passwd,  // Password
 | 
			
		||||
      bool isHTML,                // content type
 | 
			
		||||
      const std::function<void(const std::string &)> &cb = {}
 | 
			
		||||
      // The callback for email sent notification
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user