Files
JetCore/__smtpsend.h
Brad ArantandClaude Sonnet 5 b8f7793773 Add global music player, invoicing/payment system, account subpages, mail account admin, and the qualityiron.vegas Jet 2.0 port
Jet interpreter (Tag.cpp, __call.cpp, __imap*.cpp/h, __smtpsend.cpp/h,
__imapemptyfolder.cpp/h - new): assorted parser/tag fixes found across
this work - a stray literal-tag-in-comment and backslash-quote parser
corruption class, a dangling-pointer fix, a __call.cpp fd leak, IMAP
folder-management tags, multi-account/per-host IMAP support, and a
smtpsend Message-ID fix.

barant.com site (jetc/barant-site/):
- A site-wide persistent music player (header band, playlist/queue,
  stereo FFT EQ, session-persisted state) fed by new library/
  ianslibrary/music song-list subpages.
- /account split into info/phones/invoices subpages; a full invoicing
  and Square payment system (create/edit/copy/pay/email invoice);
  admin invoice management and mail-account management subpages.
- /services split into overview/hosting/siptrunking/documents
  subpages, retiring the old standalone pages.
- SIPPHONE.tag: a Jet 2.0 WebRTC softphone tag.
- main.css/spa.js/email.js: the SPA loading indicator, the music
  player band styling, and assorted fixes accumulated alongside this
  work.

qualityiron-site/: the qualityiron.vegas job/contractor/customer/
document management app, ported from its original Jet 1.4 codebase to
Jet 2.0 as barant.coms APIServers second multi-tenant site.

wcwc/wcwc.jet: the WCWC site Jet source (wcwc.jtc build output not
included).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-06 17:42:01 +00:00

71 lines
2.6 KiB
C++

#ifndef ____smtpsend_h__
# define ____smtpsend_h__
# include "Tag.h"
# include "ZString.h"
# include "MString.h"
# include <openssl/ssl.h>
# include <string>
namespace jet {
///
/// <smtpsend config="./email.cfg" user="..." password="..."
/// to="..." subject="..." html="...">
///
/// One-shot authenticated SMTP submission to BARANTMAIL's own
/// implicit-TLS submission port (config key "smtpPort" - matches
/// barantmail.cfg's smtpTLS.port, :465, the same implicit-TLS style
/// as IMAP's :993 - no STARTTLS negotiation). Connects, TLS-
/// handshakes, AUTH LOGIN with the SAME mailbox credentials already
/// used by <imap> (so the message goes out authenticated as the
/// actual connected mailbox, not the site's own transactional-mail
/// identity - see barant.tag's separate <email> tag for that), then
/// MAIL FROM/RCPT TO/DATAs a freshly-built RFC 5322 message
/// (Date/From/To/Subject/MIME headers, HTML body), then QUITs. The
/// authenticated user IS the From address - SMTP submission
/// requires MAIL FROM to match the authenticated identity anyway, so
/// there's no separate "from" keyword.
///
/// No connection pooling, unlike __imap - composing mail is rare
/// enough that a fresh connect/auth/send/close per message is fine.
///
/// Throws coreutils::Exception (401 for a bad login, 502 for any
/// other connect/protocol/rejected-recipient failure) on any
/// failure - same convention as __imap.
///
class __smtpsend : public Tag {
public:
__smtpsend(coreutils::ZString &in, coreutils::MString &parentOut, Global &global, Tag *parent, Tag *local);
private:
SSL_CTX *ctx = nullptr;
SSL *ssl = nullptr;
int fd = -1;
std::string recvBuffer;
size_t recvPos = 0;
void sendLine(const std::string &line);
char readByte();
std::string readLine();
// Reads one (possibly multi-line, "250-text"/"250 text"
// continuation-marked) SMTP reply and returns its 3-digit code;
// throws if the code's first digit doesn't match expectedCode's.
int readReply(int expectedCode);
void closeConnection();
static std::string base64Encode(const std::string &s);
static std::string rfc2822Date();
static std::string generateMessageId(const std::string &from);
// Builds the full RFC 5322 message (headers + dot-stuffed body)
// handed to SMTP's DATA command.
static std::string buildMessage(const std::string &from, const std::string &to,
const std::string &subject, const std::string &html);
};
}
#endif