I think it works now?
This commit is contained in:
parent
549d3a5a98
commit
62bb829ff7
7 changed files with 255 additions and 41 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
./node_modules
|
13
Dockerfile
Normal file
13
Dockerfile
Normal 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
|
83
index.js
83
index.js
|
@ -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.");
|
||||
}
|
||||
try {
|
||||
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}`;
|
||||
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
|
||||
}));
|
||||
});
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
||||
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
|
||||
}));
|
||||
}).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
package-lock.json
generated
Normal file
164
package-lock.json
generated
Normal 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="
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
templates/index.js
Normal file
11
templates/index.js
Normal 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
testing/testTemplate.js
Normal file
16
testing/testTemplate.js
Normal 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…
Reference in a new issue