Skip to content
Permalink
Browse files

built backend email system

  • Loading branch information...
pascal-triangle committed Jan 8, 2019
1 parent 6927a88 commit 227f89a974245962122c3f662817a4faac5fd439
@@ -0,0 +1 @@
We sent %ACCOUNT% to %PUBLIC_KEY%.
@@ -0,0 +1 @@
We sent you a PASA!
@@ -0,0 +1 @@
A payment of %AMOUNT% %SYMBOL% has been sent to %ACCOUNT% with payload %PAYMENT_ID%.
@@ -0,0 +1 @@
We sent you a payment!
@@ -0,0 +1,122 @@
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Simple Transactional Email</title>
<style>
/* -------------------------------------
RESPONSIVE AND MOBILE FRIENDLY STYLES
------------------------------------- */
@media only screen and (max-width: 620px) {
table[class=body] h1 {
font-size: 28px !important;
margin-bottom: 10px !important;
}
table[class=body] p,
table[class=body] ul,
table[class=body] ol,
table[class=body] td,
table[class=body] span,
table[class=body] a {
font-size: 16px !important;
}
table[class=body] .wrapper,
table[class=body] .article {
padding: 10px !important;
}
table[class=body] .content {
padding: 0 !important;
}
table[class=body] .container {
padding: 0 !important;
width: 100% !important;
}
table[class=body] .main {
border-left-width: 0 !important;
border-radius: 0 !important;
border-right-width: 0 !important;
}
table[class=body] .img-responsive {
height: auto !important;
max-width: 100% !important;
width: auto !important;
}
}
/* -------------------------------------
PRESERVE THESE STYLES IN THE HEAD
------------------------------------- */
@media all {
.ExternalClass {
width: 100%;
}
.ExternalClass,
.ExternalClass p,
.ExternalClass span,
.ExternalClass font,
.ExternalClass td,
.ExternalClass div {
line-height: 100%;
}
.apple-link a {
color: inherit !important;
font-family: inherit !important;
font-size: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
text-decoration: none !important;
}
}
</style>
</head>
<body class="" style="background-color: #f6f6f6; font-family: sans-serif; -webkit-font-smoothing: antialiased; font-size: 14px; line-height: 1.4; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;">
<table border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background-color: #f6f6f6;">
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">&nbsp;</td>
<td class="container" style="font-family: sans-serif; font-size: 14px; vertical-align: top; display: block; Margin: 0 auto; max-width: 580px; padding: 10px; width: 580px;">
<div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; max-width: 580px; padding: 10px;">

<!-- START CENTERED WHITE CONTAINER -->
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">This is preheader text. Some clients will show this text as a preview.</span>
<table class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background: #ffffff; border-radius: 3px;">

<!-- START MAIN CONTENT AREA -->
<tr>
<td class="wrapper" style="font-family: sans-serif; font-size: 14px; vertical-align: top; box-sizing: border-box; padding: 20px;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
<tr>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">You've received a message from %POOL_NAME%,</p>
<p style="font-family: sans-serif; font-size: 14px; font-weight: normal; margin: 0; Margin-bottom: 15px;">%MESSAGE%</p>
</td>
</tr>
</table>
</td>
</tr>

<!-- END MAIN CONTENT AREA -->
</table>

<!-- START FOOTER -->
<div class="footer" style="clear: both; Margin-top: 10px; text-align: center; width: 100%;">
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
<tr>
<td class="content-block" style="font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; font-size: 12px; color: #999999; text-align: center;">
<span class="apple-link" style="color: #999999; font-size: 12px; text-align: center;">%POOL_NAME%</span>
<br>%POOL_HOST%
</td>
</tr>
</table>
</div>
<!-- END FOOTER -->

<!-- END CENTERED WHITE CONTAINER -->
</div>
</td>
<td style="font-family: sans-serif; font-size: 14px; vertical-align: top;">&nbsp;</td>
</tr>
</table>
</body>
</html>
@@ -0,0 +1,5 @@
You've received a message from %POOL_NAME%,

%MESSAGE%

%POOL_NAME% - %POOL_HOST
@@ -0,0 +1 @@
This is a test notification from the pool.
@@ -0,0 +1 @@
Test Notification!
@@ -0,0 +1 @@
Your worker %WORKER_NAME% has been banned. It was connected from ip address: %IP% and was mining to account %ACCOUNT%.
@@ -0,0 +1 @@
Worker %WORKER_NAME% banned
@@ -0,0 +1 @@
Your worker %WORKER_NAME% is now connected from ip address: %IP% and is mining to account %ACCOUNT%.
@@ -0,0 +1 @@
Worker %WORKER_NAME% connected
@@ -0,0 +1 @@
Your worker %WORKER_NAME% has stopped submitting hashes on %LAST_HASH%. It was connected from ip address: %IP% and was mining to account %ACCOUNT%.
@@ -0,0 +1 @@
Worker %WORKER_NAME% stopped hashing
@@ -0,0 +1,201 @@
/**
* Free Pascal Pool
* https://github.com/
*
* Notifications system
**/

var fs = require("fs");
var path = require("path");
var utils = require("./utils.js");

var nodemailer = require("nodemailer");
var mailgun = require("mailgun.js");

/**
* Initialize log system
**/
var logSystem = "notifications";
require("./exceptionWriter.js")(logSystem);

/**
* Load notification templates, and use a watcher to look for changed files
**/
var templateDir = "./email_templates";
var templates = {};

if(fs.existsSync(templateDir)) {
fs.readdirSync(templateDir).forEach(function(file, index) {
var template = file.substring(0, file.indexOf("."));
var extension = file.substring(file.indexOf("."));
if(/^[a-zA-Z0-9_]+$/.test(template)) {
var contents = fs.readFileSync(path.join(templateDir, file), 'utf8');
if(!templates.hasOwnProperty(template)) {
templates[template] = {};
}
templates[template][extension=='.txt'?'subject':'body'] = contents;
}
});
}

fs.watch(templateDir, {}, (eventType, file) => {
var template = file.substring(0, file.indexOf("."));
var extension = file.substring(file.indexOf("."));
if(/^[a-zA-Z0-9_]+$/.test(template)) {
var contents = fs.readFileSync(path.join(templateDir, file), 'utf8');
if(!templates.hasOwnProperty(template)) {
templates[template] = {};
}
templates[template][extension=='.txt'?'subject':'body'] = contents;
}
});

/**
* Send miner notification
**/
exports.sendToMiner = function(miner, id, variables) {
// Set custom variables
variables = setCustomVariables(variables);

// Send email
if (config.email && config.email.enabled) {
var subject = getEmailSubject(id, variables);
var content = getEmailContent(id, variables);
if (!content || content === "") {
log("info", logSystem, "Notification disabled for %s: empty email content.", [id]);
return;
}

redisClient.zrevrangebyscore(
redisPrefix + ":worker_passwords:" + miner,
"+inf",
"(" + (Math.floor(Date.now() / 1000) - (60 * 60)),
function(error, result) {
if(!Array.isArray(result)) {
return;
}
for(var i = 0; i < result.length; i++) {
var email = result[i];
sendEmail(email, subject, content);
}
}
);
}
}


/**
* Send email notification to a specific email address
**/
exports.sendToEmail = function(email, id, variables) {
// Set custom variables
variables = setCustomVariables(variables);

// Send notification
if (config.email && config.email.enabled) {
var subject = getEmailSubject(id, variables);
var content = getEmailContent(id, variables);
if (!content || content === "") {
log("info", logSystem, "Notification disabled for %s: empty email content.", [id]);
return;
}

sendEmail(email, subject, content);
}
}

/**
* Email helper functions
**/

// Get email subject
function getEmailSubject(id, variables) {
return replaceVariables(templates[id].subject, variables) || "";
}

// Get email content
function getEmailContent(id, variables) {
var message = templates[id].body || "";
if(!message || message === "") return "";

var content = message;
if(config.email.useHTML) {
if(templates.template.body) {
content = templates.template.body.replace(/%MESSAGE%/g, message);
}
} else {
if(templates.template.subject) {
content = templates.template.subject.replace(/%MESSAGE%/g, message);
}
}
content = replaceVariables(content, variables);
return content;
}

function sendEmail(email, subject, content) {
// Return error if no destination email address
if(!email) {
log("warn", logSystem, "Unable to send e-mail: no destination email.");
return ;
}

// Set content data
var messageData = {
from: config.email.fromAddress,
to: email,
subject: subject
};

if(config.email.useHTML) {
messageData.html = content;
} else {
messageData.text = content;
}


// Get email transport
var transportMode = config.email.transport;
var transportCfg = config.email[transportMode] ? config.email[transportMode] : {};

if(transportMode === "mailgun") {
var mg = mailgun.client({username: "api", key: transportCfg.key});
mg.messages.create(transportCfg.domain, messageData);
log("info", logSystem, "E-mail sent to %s: %s", [messageData.to, messageData.subject]);
} else {
transportCfg["transport"] = transportMode;
var transporter = nodemailer.createTransport(transportCfg);
transporter.sendMail(messageData, function(error){
if(error){
log("error", logSystem, "Unable to send e-mail to %s: %s", [messageData.to, error.toString()]);
} else {
log("info", logSystem, "E-mail sent to %s: %s", [email, subject]);
}
});
}
}

/**
* Handle variables in texts
**/

// Set custom variables
function setCustomVariables(variables) {
if(!variables) variables = {};
variables["TIME"] = utils.dateFormat(Date.now(), "yyyy-mm-dd HH:MM:ss Z");
variables["COIN"] = config.coin || "";
variables["SYMBOL"] = config.symbol || "";
variables["POOL_NAME"] = config.poolName || "";
variables["POOL_HOST"] = config.poolHost || "";
return variables;
}

// Replace variables in a string
function replaceVariables(string, variables) {
if(!string) return "";
if(variables) {
for(var varName in variables) {
string = string.replace(new RegExp("%"+varName+"%", "g"), variables[varName]);
}
}
return string;
}
@@ -8,6 +8,8 @@
var crypto = require("crypto");
var bignum = require("bignum");

var dateFormat = require('dateformat');
exports.dateFormat = dateFormat;

exports.validateLogin = function(login) {

0 comments on commit 227f89a

Please sign in to comment.
You can’t perform that action at this time.