Browse Source

I think it works now?

master
John Shaver 1 year ago
parent
commit
62bb829ff7
7 changed files with 255 additions and 41 deletions
  1. 1
    0
      .gitignore
  2. 13
    0
      Dockerfile
  3. 46
    37
      index.js
  4. 164
    0
      package-lock.json
  5. 4
    4
      templater.js
  6. 11
    0
      templates/index.js
  7. 16
    0
      testing/testTemplate.js

+ 1
- 0
.gitignore View File

@@ -0,0 +1 @@
./node_modules

+ 13
- 0
Dockerfile View File

@@ -0,0 +1,13 @@
FROM node:10.6-alpine
RUN mkdir /app
RUN chown node:node /app
WORKDIR /app
run apk add --no-cache python2 g++ make git curl
RUN yarn global add Haraka express
USER node
RUN haraka -i /app
RUN echo webmailer >> /app/config/plugins
RUN echo "listen=[::0]:8080" >> /app/config/http.ini
RUN echo "listen=[::0]:2525" >> /app/config/smtp.ini
COPY testing/testTemplate.js /app/plugins/webmailer/templates/testTemplate.js
CMD haraka -c /app

+ 46
- 37
index.js View File

@@ -3,58 +3,67 @@ let fs = require('fs');
let bodyParser = require('body-parser');
let outbound;

let getTemplates = require('./templater');
let getTemplates = require('./templates');
let errorSender = require('./errorSender');
exports.register = function() {
outbound = this.haraka_require('./outbound');
let plugin = this;
this.register_hook('hook_init_http', function(next, server) {
this.register_hook('init_http', 'initExpress');
}

exports.initExpress = function(next, server) {
server.http.app.use('/webSend', setupRoutes(server.http.express.Router()));
server.http.app.get('/test', (req, res) => res.send("HELLO!"));
plugin.loginfo(server.http.app._router.stack);
next();
});
}
next();
};

function setupRoutes(app) {
app.use(bodyParser.json());
app.use(errorSender);

app.post('/template', function(req, res) {
if(!req.body) {
return res.sendError(400, "No body provided.");
}

let {to, from, template, headers} = req.body;
if(!template) {
return res.sendError(400, "No template name provided.");
}
return getTemplates.then(function(templates) {
let emailText = `From: ${from}\nTo: ${to}`;
if(headers) {
headers.forEach(function(header) {
emailText += `\n${header}`;
});
}
try {
let [subject, body] = `\n\n${templates[template](req.body)}\n`;
emailText += `\nSubject: ${subject}\n\n${body}`;
} catch (err) {
console.error("Error building email from template: ", err);
res.sendError(err.httpStatus || 400, err.userMessage || "Error parsing template");
try {
if(!req.body) {
return res.sendError(400, "No body provided.");
}

outbound.send_email(from, to, emailText, function(code, message) {
console.log(`Queue mail result code: ${code} msg: ${msg}`);
res.type("json").send(JSON.stringigy({
code,
message
}));
let {to, from, template, headers} = req.body;
if(!template) {
console.error("Template not found in: ", req.body);
return res.sendError(400, "No template name provided.");
}
return getTemplates().then(function(templates) {
if(!templates[template]) {
return res.sendError(400, `Template not found in ${JSON.stringify(templates)}`);
}
let emailText = `From: ${from}\nTo: ${to}`;
if(headers) {
headers.forEach(function(header) {
emailText += `\n${header}`;
});
}
try {
let {subject, message} = templates[template](req.body);
emailText += `\nSubject: ${subject}\n\n${message}`;
} catch (err) {
console.error("Error building email from template: ", err);
res.sendError(err.httpStatus || 400, err.userMessage || "Error parsing template");
}
outbound.send_email(from, to, emailText, function(code, message) {
console.log(`Queue mail result code: ${code} msg: ${message}`);
res.type("json").send(JSON.stringify({
code,
message
}));
});
}).catch(function(err) {
console.error("Error loading templates:", err);
res.sendError(500, "Server Error");
throw(e);
});
}).catch(function(err) {
console.error("Error loading templates:", err);
} catch(e) {
res.sendError(500, "Server Error");
});
throw(e);
}
});
return app;

+ 164
- 0
package-lock.json View File

@@ -0,0 +1,164 @@
{
"name": "haraka-plugin-webmailer",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"body-parser": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
"requires": {
"bytes": "3.1.0",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "~1.1.2",
"http-errors": "1.7.2",
"iconv-lite": "0.4.24",
"on-finished": "~2.3.0",
"qs": "6.7.0",
"raw-body": "2.4.0",
"type-is": "~1.6.17"
}
},
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
},
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"http-errors": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.3",
"setprototypeof": "1.1.1",
"statuses": ">= 1.5.0 < 2",
"toidentifier": "1.0.0"
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"lodash.escape": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz",
"integrity": "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg="
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
},
"mime-db": {
"version": "1.40.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
"integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA=="
},
"mime-types": {
"version": "2.1.24",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
"integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
"requires": {
"mime-db": "1.40.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
"requires": {
"ee-first": "1.1.1"
}
},
"qs": {
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
},
"raw-body": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
"integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
"requires": {
"bytes": "3.1.0",
"http-errors": "1.7.2",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
}
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"setprototypeof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
},
"statuses": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
},
"type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
"requires": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
}
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
}
}
}

+ 4
- 4
templater.js View File

@@ -2,10 +2,10 @@ let escape = require("lodash.escape");

module.exports = function(strings) {
//first element is the strings, don't need it
let args = arguments.slice(1);
let args = Array.prototype.slice.call(arguments,1);

//first element will be the initial value
return strings.slice(1).reduce(function(result, string, i) {
return result + escape(args[i]) + string;
}, strings[0]);
return strings.reduce(function(result, string, i) {
return result + escape(args[i-1]) + string;
});
};

+ 11
- 0
templates/index.js View File

@@ -0,0 +1,11 @@
let fs = require('fs');
let templateFiles = fs.readdirSync(__dirname, "utf8").filter(
x => x[0] !== "." && x !== "index.js"
);

let templates = templateFiles.reduce((obj, file) => { obj[file.split(".")[0]] = require(`./${file}`); return obj;}, {});

module.exports = function() {
//I might want to make this asynchronous very soon
return Promise.resolve(templates);
};

+ 16
- 0
testing/testTemplate.js View File

@@ -0,0 +1,16 @@
let templater = require('../templater');

module.exports = function({params}) {
let message = templater`Hello ${params.name},

I am writing to inform you that I am testing a templated email. I have tested it ${params.times} times.

${params.valediction},

${params.senderName}
`;

let subject = "New message from webmailer program!";
return {subject, message};
}


Loading…
Cancel
Save