commit
c3788cc413
@ -0,0 +1,3 @@
|
||||
.env
|
||||
*.env
|
||||
node_modules/*
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
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;">
|
||||
© 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;">
|
||||
© 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;">
|
||||
© 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;">
|
||||
© 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
Loading…
Reference in new issue