Add Visione backend foundation

This commit is contained in:
gabdevele
2026-06-02 19:22:00 +02:00 Unverified
commit 580789ac83
52 changed files with 5008 additions and 0 deletions
+119
View File
@@ -0,0 +1,119 @@
#include "common/Email.h"
#include <drogon/drogon.h>
#include <array>
#include <cstring>
#include <string>
#include <netdb.h>
#include <sys/socket.h>
#include <unistd.h>
namespace visione::email
{
namespace
{
std::string configString(const std::string &key, const std::string &fallback)
{
const auto &mail = drogon::app().getCustomConfig()["mail"];
return mail.get(key, fallback).asString();
}
int configInt(const std::string &key, int fallback)
{
const auto &mail = drogon::app().getCustomConfig()["mail"];
return mail.get(key, fallback).asInt();
}
bool readResponse(int socket)
{
std::array<char, 512> buffer{};
const auto count = recv(socket, buffer.data(), buffer.size() - 1, 0);
return count > 0 && buffer[0] >= '2' && buffer[0] <= '3';
}
bool sendLine(int socket, const std::string &line)
{
const auto payload = line + "\r\n";
return send(socket, payload.data(), payload.size(), 0) ==
static_cast<ssize_t>(payload.size());
}
bool sendCommand(int socket, const std::string &line)
{
return sendLine(socket, line) && readResponse(socket);
}
} // namespace
bool EmailService::sendOtp(const std::string &to, const std::string &code) const
{
const auto host = configString("smtp_host", "127.0.0.1");
const auto port = std::to_string(configInt("smtp_port", 1025));
const auto from = configString("from", "[email protected]");
addrinfo hints{};
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
addrinfo *addresses = nullptr;
if (getaddrinfo(host.c_str(), port.c_str(), &hints, &addresses) != 0)
{
return false;
}
int smtp = -1;
for (auto *address = addresses; address != nullptr; address = address->ai_next)
{
smtp = socket(address->ai_family, address->ai_socktype, address->ai_protocol);
if (smtp < 0)
{
continue;
}
if (connect(smtp, address->ai_addr, address->ai_addrlen) == 0)
{
break;
}
close(smtp);
smtp = -1;
}
freeaddrinfo(addresses);
if (smtp < 0)
{
return false;
}
const auto closeSocket = [&smtp]() {
if (smtp >= 0)
{
close(smtp);
smtp = -1;
}
};
if (!readResponse(smtp) || !sendCommand(smtp, "HELO visione.local") ||
!sendCommand(smtp, "MAIL FROM:<" + from + ">") ||
!sendCommand(smtp, "RCPT TO:<" + to + ">") ||
!sendCommand(smtp, "DATA"))
{
closeSocket();
return false;
}
const std::string body =
"From: Visione <" + from + ">\r\n"
"To: " + to + "\r\n"
"Subject: Codice OTP Visione\r\n"
"Content-Type: text/plain; charset=UTF-8\r\n"
"\r\n"
"Il tuo codice OTP per Visione e': " + code + "\r\n"
"Scade tra 10 minuti.\r\n"
".";
const auto ok = sendCommand(smtp, body) && sendCommand(smtp, "QUIT");
closeSocket();
return ok;
}
} // namespace visione::email