Gabe Farrell 2 years ago
commit c3788cc413

3
.gitignore vendored

@ -0,0 +1,3 @@
.env
*.env
node_modules/*

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

@ -0,0 +1,23 @@
{
"name": "mailer",
"version": "1.0.0",
"description": "E-Mailer microservice for the Talgo Cloud infrastructure.",
"main": "./src/index.js",
"repository": "github.com/talgo-cloud/Mailer",
"license": "MIT",
"private": true,
"dependencies": {
"@aws-sdk/client-ses": "^3.465.0",
"@aws-sdk/client-sesv2": "^3.465.0",
"aws-sdk": "^2.1507.0",
"express": "^4.18.2",
"max-listeners-exceeded-warning": "^0.0.1",
"nodemon": "^3.0.1",
"pug": "^3.0.2",
"squirrelly": "^9.0.0"
},
"type": "module",
"scripts": {
"dev": ". ./.env && node ./src/index.js"
}
}

@ -0,0 +1,19 @@
import express from 'express'
const app = express()
import router from './routes.js'
import { EventEmitter } from 'events'
EventEmitter.defaultMaxListeners = 15;
const port = process.env.PORT || 3000
// middleware
app.use(express.json())
app.use(express.urlencoded({extended: true}))
// routes
app.use(router);
app.listen(port, () => {
console.log('Mailer listening at http://127.0.0.1:' + port)
})

@ -0,0 +1,31 @@
// Load the AWS SDK for Node.js
import { SESv2Client, SendEmailCommand } from "@aws-sdk/client-sesv2"; // ES Modules import
const client = new SESv2Client();
export default function sendEmail(mailData) {
const input = { // SendEmailRequest
FromEmailAddress: mailData.from,
Destination: { // Destination
ToAddresses: [ // EmailAddressList
mailData.to,
],
},
Content: { // EmailContent
Simple: { // Message
Subject: { // Content
Data: mailData.subject, // required
Charset: 'utf-8',
},
Body: { // Body
Html: {
Data: mailData.body, // required
Charset: 'utf-8',
},
},
},
},
};
const command = new SendEmailCommand(input);
return client.send(command);
}

@ -0,0 +1,70 @@
import express from 'express'
const router = new express.Router();
import mailer from './mailer.js'
import sqrl from 'squirrelly'
import fs from 'fs'
router.post('/email', (req, res) => {
console.log(req.body)
let emailTemplate = ''
let mailData = {
body: '',
to: req.body.to,
from: '',
subject: '',
}
console.log(req.Headers)
// property validation
let errList = []
if (!req.body.to) {
errList.push({"to": "valid email address is required"})
}
// if (!req.body.from) {
// errList.push({"from": "valid email address is required"})
// }
// if (!req.body.subject) {
// errList.push({"subject": "non-empty string expected"})
// }
if (!req.body.hasOwnProperty('template_type')) {
errList.push({"template_type": "a value must be provided, even an empty string"})
}
if (errList.length > 0) {
res.status(400).json({ errors: errList }).end()
return
}
switch(req.body.template_type) {
case 'verification_valid':
mailData.subject = 'Verify your Talgo Cloud email address'
emailTemplate = './templates/verification.html'
mailData.from = '"Talgo Cloud" <accounts@talgo.cc>'
break;
case 'recovery_valid':
mailData.subject = 'Recover your Talgo Cloud account'
emailTemplate = './templates/recovery.html'
mailData.from = '"Talgo Cloud" <accounts@talgo.cc>'
break;
default:
mailData.subject = req.body.subject
emailTemplate = './templates/default.html'
mailData.from = req.body.from
break;
}
mailData.body = sqrl.render(fs.readFileSync(emailTemplate).toString(), req.body)
mailer(mailData).then((data) => {
console.log(data)
res.status(200).end()
}).catch((err) => {
console.log(err)
res.status(500).end()
})
})
// {"template_type": "verification_valid", "to":"gabe@mnrva.dev", "verification_url":"https://google.com"}
export default router

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div style="font-family: Arial, Helvetica, sans-serif; background-color: #eee; padding: 3em; max-width:550px;">
<div style="text-align: center;">
<div style="background-color: white; border-radius: 5px; font-size: 16px;">
<div style="height: 56px; background-color: #f41f4e; padding:0.5em; text-align: center; border-top-right-radius: 5px; border-top-left-radius: 5px;">
<img src="https://i.postimg.cc/L8gd5SBt/logo-45h.png" style="padding-top: 7px;"/>
</div>
<div style="padding: 4%; overflow:auto; color: #777;">
{{@foreach(it.data) => key, val}}
{{key}}, {{val}}<br>
{{/foreach}}
</div>
</div>
<p style="color: #888; font-size: 14px;">
&copy; 2023 Talgo Cloud LLC. All rights reserved.
</p>
</div>
</div>
</body>
</html>

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div style="font-family: Arial, Helvetica, sans-serif; background-color: #eee; padding: 3em; max-width:550px;">
<div style="text-align: center;">
<div style="background-color: white; border-radius: 5px; font-size: 16px;">
<div style="height: 56px; background-color: #f41f4e; padding:0.5em; text-align: center; border-top-right-radius: 5px; border-top-left-radius: 5px;">
<img src="https://i.postimg.cc/L8gd5SBt/logo-45h.png" style="padding-top: 7px;"/>
</div>
<div style="padding: 4%; overflow:auto; color: #777;">
<h1 style="margin: 0.5em 0em 1em 0em; font-weight: bold; color: #333">Recover your Account</h1>
<p style="padding: 0px 2em;">
We recieved a request to recover your Talgo Cloud account.
Click the link below to enter account recovery.
The link is valid for 15 minutes.
</p>
<a type="button" href="{{it.recovery_url}}" style="background-color: #f41f4e; border: none; border-radius: 5px; padding: 1em; color: white; font-style: bold; font-weight: bold; font-size: 16px; text-decoration: none; display: block; width: 81%; text-align: center; margin: 0em 2em;" target="_blank">
Reset password
</a>
<div style="font-size: 14px;">
<hr style="width: 10%;border:0;margin:0px auth;width:10%;height:2px;background:#ddd;">
<p>
Or, copy and paste this link into your browser:
</p>
<a style="word-wrap: break-word; color: #f41f4e" href="{{it.recovery_url}}">
{{it.recovery_url}}
</a>
<p style="color: #aaa; font-style: italic; margin-top: 2.5em;">If you did not request this email, you can safely delete it.</p>
</div>
</div>
</div>
<p style="color: #888; font-size: 14px;">
&copy; 2023 Talgo Cloud LLC. All rights reserved.
</p>
</div>
</div>
</body>
</html>

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div style="font-family: Arial, Helvetica, sans-serif; background-color: #eee; padding: 3em; max-width:550px;">
<div style="text-align: center;">
<div style="background-color: white; border-radius: 5px; font-size: 16px;">
<div style="height: 56px; background-color: #f41f4e; padding:0.5em; text-align: center; border-top-right-radius: 5px; border-top-left-radius: 5px;">
<img src="https://i.postimg.cc/L8gd5SBt/logo-45h.png" style="padding-top: 7px;"/>
</div>
<div style="padding: 4%; overflow:auto; color: #777;">
<h1 style="margin: 0.2em 0em 0.5em 0em; font-weight: bold; color: #333">Welcome to Talgo</h1>
<p style="padding: 0px 2em;">
You're almost ready to start using Talgo to boost your
app to the next level. Use the code below to verify your email address.
</p>
<p style="padding: 0em; color: black; font-weight: bold; font-size: 22px; text-align: center;">
{{it.verification_code}}
</p>
<div style="font-size: 14px;">
<hr style="width: 10%;border:0;margin:0px auth;width:10%;height:2px;background:#ddd;">
<p style="color: #aaa; font-style: italic; margin-top: 2.5em;">If you did not request this email, you can safely delete it.</p>
</div>
</div>
</div>
<p style="color: #888; font-size: 14px;">
&copy; 2023 Talgo Cloud LLC. All rights reserved.
</p>
</div>
</div>
</body>
</html>

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="font-family: Arial, Helvetica, sans-serif; ">
<div style="height: 56px; background-color: #f41f4e; padding:0.5em;">
<!-- <h1 style="font-family: Verdana, Geneva, Tahoma, sans-serif; color: white; padding-left: 1em; padding-top: 8px; margin:0px;">talgo</h1> -->
<img src="../assets/logo.png" style="height: 60px; padding-left: 2em;"/>
</div>
<div style="max-width: 600px; padding-left: 2em; overflow:auto; ">
<h1>Welcome to Talgo!</h1>
<p>
This is the contents of a test email sent to welcome you to our
service. Even though there is no actually valuable information
here, we hope you still like the message.
</p>
<button style="background-color: #f41f4e; border: none; border-radius: 5px; padding: 1em; color: white; font-style: bold; font-weight: bold; font-size: 16px;" style:hover="">Click Me!</button>
<p>
Or if that doesn't work, copy and paste this link into your
browser:
</p>
<a style="word-wrap: break-word;" href="https://gosuimg.com/accounts/verify?token=VGhpcyBpcyBhIHJlYWxseSBjb29sIHN0cmluZw.V293LCBhbm90aGVyIHN0cmluZz8/IFdlIGFyZSBlYXRpbmcgZ29vZCB0b25pZ2h0IQ.QW5kIG9uZSBmaW5hbCBzdHJpbmcu">
https://accounts.talgo.cc/verify?token=VGhpcyBpcyBhIHJlYWxseSBjb29sIHN0cmluZw.V293LCBhbm90aGVyIHN0cmluZz8/IFdlIGFyZSBlYXRpbmcgZ29vZCB0b25pZ2h0IQ.QW5kIG9uZSBmaW5hbCBzdHJpbmcu
</a>
<p>
After clicking that button, absolutely nothing will happen.
The only thing that happens when you click that button
is the small amount of dopamine that gets sent straight into
your amygdala when you click buttons. Enjoy the service!
</p>
<hr>
<p style="color: #888; font-size: 14px;">
&copy; 2023 Talgo Cloud LLC <br>
If you hate us and never want to talk to us again, <a href="/unsubscribe">unsubscribe</a>. <br>
</p>
</div>
</body>
<style>
button:hover {
cursor: pointer;
}
</style>
</html>
<p style="padding: 0px 2em;">
You're almost ready to start using Talgo to boost your
app to the next level. Use the code below to verify your email address.
</p>
<p style="padding: 1em; color: black; font-weight: bold; font-size: 22px; text-align: center;">
{{it.verification_code}}
</p>

@ -0,0 +1,8 @@
{
"compilerOptions": {
"outDir": "./built",
"allowJs": true,
"target": "es5"
},
"include": ["./src/**/*"]
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save