Some updates, working towards supporting automation send smtp email also removing the styling template, adding to base.
This commit is contained in:
parent
075b00b534
commit
7736869148
|
@ -15,5 +15,6 @@ module.exports = {
|
||||||
MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,
|
MINIO_ACCESS_KEY: process.env.MINIO_ACCESS_KEY,
|
||||||
MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,
|
MINIO_SECRET_KEY: process.env.MINIO_SECRET_KEY,
|
||||||
MINIO_URL: process.env.MINIO_URL,
|
MINIO_URL: process.env.MINIO_URL,
|
||||||
|
INTERNAL_KEY: process.env.INTERNAL_KEY,
|
||||||
isTest,
|
isTest,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ const { Cookies } = require("../constants")
|
||||||
const database = require("../db")
|
const database = require("../db")
|
||||||
const { getCookie, clearCookie } = require("../utils")
|
const { getCookie, clearCookie } = require("../utils")
|
||||||
const { StaticDatabases } = require("../db/utils")
|
const { StaticDatabases } = require("../db/utils")
|
||||||
|
const env = require("../environment")
|
||||||
|
|
||||||
const PARAM_REGEX = /\/:(.*?)\//g
|
const PARAM_REGEX = /\/:(.*?)\//g
|
||||||
|
|
||||||
|
@ -35,10 +36,14 @@ module.exports = (noAuthPatterns = [], opts) => {
|
||||||
return next()
|
return next()
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
const apiKey = ctx.request.headers["x-budibase-api-key"]
|
||||||
// check the actual user is authenticated first
|
// check the actual user is authenticated first
|
||||||
const authCookie = getCookie(ctx, Cookies.Auth)
|
const authCookie = getCookie(ctx, Cookies.Auth)
|
||||||
|
|
||||||
if (authCookie) {
|
// this is an internal request, no user made it
|
||||||
|
if (apiKey && apiKey === env.INTERNAL_KEY) {
|
||||||
|
ctx.isAuthenticated = true
|
||||||
|
} else if (authCookie) {
|
||||||
try {
|
try {
|
||||||
const db = database.getDB(StaticDatabases.GLOBAL.name)
|
const db = database.getDB(StaticDatabases.GLOBAL.name)
|
||||||
const user = await db.get(authCookie.userId)
|
const user = await db.get(authCookie.userId)
|
||||||
|
|
|
@ -6,14 +6,11 @@ const randomString = require("randomstring")
|
||||||
|
|
||||||
const FILE_PATH = path.resolve("./.env")
|
const FILE_PATH = path.resolve("./.env")
|
||||||
|
|
||||||
function getContents(port, hostingKey) {
|
function getContents(port) {
|
||||||
return `
|
return `
|
||||||
# Use the main port in the builder for your self hosting URL, e.g. localhost:10000
|
# Use the main port in the builder for your self hosting URL, e.g. localhost:10000
|
||||||
MAIN_PORT=${port}
|
MAIN_PORT=${port}
|
||||||
|
|
||||||
# Use this password when configuring your self hosting settings
|
|
||||||
HOSTING_KEY=${hostingKey}
|
|
||||||
|
|
||||||
# This section contains all secrets pertaining to the system
|
# This section contains all secrets pertaining to the system
|
||||||
JWT_SECRET=${randomString.generate()}
|
JWT_SECRET=${randomString.generate()}
|
||||||
MINIO_ACCESS_KEY=${randomString.generate()}
|
MINIO_ACCESS_KEY=${randomString.generate()}
|
||||||
|
@ -21,6 +18,7 @@ MINIO_SECRET_KEY=${randomString.generate()}
|
||||||
COUCH_DB_PASSWORD=${randomString.generate()}
|
COUCH_DB_PASSWORD=${randomString.generate()}
|
||||||
COUCH_DB_USER=${randomString.generate()}
|
COUCH_DB_USER=${randomString.generate()}
|
||||||
REDIS_PASSWORD=${randomString.generate()}
|
REDIS_PASSWORD=${randomString.generate()}
|
||||||
|
INTERNAL_KEY=${randomString.generate()}
|
||||||
|
|
||||||
# This section contains variables that do not need to be altered under normal circumstances
|
# This section contains variables that do not need to be altered under normal circumstances
|
||||||
APP_PORT=4002
|
APP_PORT=4002
|
||||||
|
@ -33,7 +31,6 @@ BUDIBASE_ENVIRONMENT=PRODUCTION`
|
||||||
|
|
||||||
module.exports.filePath = FILE_PATH
|
module.exports.filePath = FILE_PATH
|
||||||
module.exports.ConfigMap = {
|
module.exports.ConfigMap = {
|
||||||
HOSTING_KEY: "key",
|
|
||||||
MAIN_PORT: "port",
|
MAIN_PORT: "port",
|
||||||
}
|
}
|
||||||
module.exports.QUICK_CONFIG = {
|
module.exports.QUICK_CONFIG = {
|
||||||
|
@ -42,18 +39,13 @@ module.exports.QUICK_CONFIG = {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.make = async (inputs = {}) => {
|
module.exports.make = async (inputs = {}) => {
|
||||||
const hostingKey =
|
|
||||||
inputs.key ||
|
|
||||||
(await string(
|
|
||||||
"Please input the password you'd like to use as your hosting key: "
|
|
||||||
))
|
|
||||||
const hostingPort =
|
const hostingPort =
|
||||||
inputs.port ||
|
inputs.port ||
|
||||||
(await number(
|
(await number(
|
||||||
"Please enter the port on which you want your installation to run: ",
|
"Please enter the port on which you want your installation to run: ",
|
||||||
10000
|
10000
|
||||||
))
|
))
|
||||||
const fileContents = getContents(hostingPort, hostingKey)
|
const fileContents = getContents(hostingPort)
|
||||||
fs.writeFileSync(FILE_PATH, fileContents)
|
fs.writeFileSync(FILE_PATH, fileContents)
|
||||||
console.log(
|
console.log(
|
||||||
success(
|
success(
|
||||||
|
|
|
@ -39,6 +39,7 @@ async function init() {
|
||||||
COUCH_DB_URL: "http://budibase:budibase@localhost:10000/db/",
|
COUCH_DB_URL: "http://budibase:budibase@localhost:10000/db/",
|
||||||
REDIS_URL: "localhost:6379",
|
REDIS_URL: "localhost:6379",
|
||||||
WORKER_URL: "http://localhost:4002",
|
WORKER_URL: "http://localhost:4002",
|
||||||
|
INTERNAL_KEY: "budibase",
|
||||||
JWT_SECRET: "testsecret",
|
JWT_SECRET: "testsecret",
|
||||||
REDIS_PASSWORD: "budibase",
|
REDIS_PASSWORD: "budibase",
|
||||||
MINIO_ACCESS_KEY: "budibase",
|
MINIO_ACCESS_KEY: "budibase",
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
const sendEmail = require("./steps/sendEmail")
|
const sendEmail = require("./steps/sendgridEmail")
|
||||||
const createRow = require("./steps/createRow")
|
const createRow = require("./steps/createRow")
|
||||||
const updateRow = require("./steps/updateRow")
|
const updateRow = require("./steps/updateRow")
|
||||||
const deleteRow = require("./steps/deleteRow")
|
const deleteRow = require("./steps/deleteRow")
|
||||||
|
|
|
@ -2,7 +2,7 @@ module.exports.definition = {
|
||||||
description: "Send an email",
|
description: "Send an email",
|
||||||
tagline: "Send email to {{inputs.to}}",
|
tagline: "Send email to {{inputs.to}}",
|
||||||
icon: "ri-mail-open-line",
|
icon: "ri-mail-open-line",
|
||||||
name: "Send Email",
|
name: "Send Email (SendGrid)",
|
||||||
type: "ACTION",
|
type: "ACTION",
|
||||||
stepId: "SEND_EMAIL",
|
stepId: "SEND_EMAIL",
|
||||||
inputs: {},
|
inputs: {},
|
|
@ -34,6 +34,7 @@ module.exports = {
|
||||||
USE_QUOTAS: process.env.USE_QUOTAS,
|
USE_QUOTAS: process.env.USE_QUOTAS,
|
||||||
REDIS_URL: process.env.REDIS_URL,
|
REDIS_URL: process.env.REDIS_URL,
|
||||||
REDIS_PASSWORD: process.env.REDIS_PASSWORD,
|
REDIS_PASSWORD: process.env.REDIS_PASSWORD,
|
||||||
|
INTERNAL_KEY: process.env.INTERNAL_KEY,
|
||||||
// environment
|
// environment
|
||||||
NODE_ENV: process.env.NODE_ENV,
|
NODE_ENV: process.env.NODE_ENV,
|
||||||
JEST_WORKER_ID: process.env.JEST_WORKER_ID,
|
JEST_WORKER_ID: process.env.JEST_WORKER_ID,
|
||||||
|
@ -53,7 +54,6 @@ module.exports = {
|
||||||
BUDIBASE_API_KEY: process.env.BUDIBASE_API_KEY,
|
BUDIBASE_API_KEY: process.env.BUDIBASE_API_KEY,
|
||||||
USERID_API_KEY: process.env.USERID_API_KEY,
|
USERID_API_KEY: process.env.USERID_API_KEY,
|
||||||
DEPLOYMENT_CREDENTIALS_URL: process.env.DEPLOYMENT_CREDENTIALS_URL,
|
DEPLOYMENT_CREDENTIALS_URL: process.env.DEPLOYMENT_CREDENTIALS_URL,
|
||||||
HOSTING_KEY: process.env.HOSTING_KEY,
|
|
||||||
_set(key, value) {
|
_set(key, value) {
|
||||||
process.env[key] = value
|
process.env[key] = value
|
||||||
module.exports[key] = value
|
module.exports[key] = value
|
||||||
|
|
|
@ -26,7 +26,7 @@ function request(ctx, request) {
|
||||||
? JSON.stringify(request.body)
|
? JSON.stringify(request.body)
|
||||||
: request.body
|
: request.body
|
||||||
}
|
}
|
||||||
if (ctx.headers) {
|
if (ctx && ctx.headers) {
|
||||||
request.headers.cookie = ctx.headers.cookie
|
request.headers.cookie = ctx.headers.cookie
|
||||||
}
|
}
|
||||||
return request
|
return request
|
||||||
|
@ -34,6 +34,19 @@ function request(ctx, request) {
|
||||||
|
|
||||||
exports.request = request
|
exports.request = request
|
||||||
|
|
||||||
|
exports.sendSmtpEmail = async (to, from, contents) => {
|
||||||
|
const response = await fetch(
|
||||||
|
checkSlashesInUrl(env.WORKER_URL + `/api/`),
|
||||||
|
request(null, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"x-budibase-api-key": env.INTERNAL_KEY,
|
||||||
|
},
|
||||||
|
body: {},
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
exports.getDeployedApps = async ctx => {
|
exports.getDeployedApps = async ctx => {
|
||||||
if (!env.SELF_HOSTED) {
|
if (!env.SELF_HOSTED) {
|
||||||
throw "Can only check apps for self hosted environments"
|
throw "Can only check apps for self hosted environments"
|
||||||
|
|
|
@ -8,6 +8,7 @@ async function init() {
|
||||||
SELF_HOSTED: 1,
|
SELF_HOSTED: 1,
|
||||||
PORT: 4002,
|
PORT: 4002,
|
||||||
JWT_SECRET: "testsecret",
|
JWT_SECRET: "testsecret",
|
||||||
|
INTERNAL_KEY: "budibase",
|
||||||
MINIO_ACCESS_KEY: "budibase",
|
MINIO_ACCESS_KEY: "budibase",
|
||||||
MINIO_SECRET_KEY: "budibase",
|
MINIO_SECRET_KEY: "budibase",
|
||||||
COUCH_DB_USER: "budibase",
|
COUCH_DB_USER: "budibase",
|
||||||
|
|
|
@ -27,7 +27,6 @@ const TemplateTypes = {
|
||||||
|
|
||||||
const EmailTemplatePurpose = {
|
const EmailTemplatePurpose = {
|
||||||
BASE: "base",
|
BASE: "base",
|
||||||
STYLES: "styles",
|
|
||||||
PASSWORD_RECOVERY: "password_recovery",
|
PASSWORD_RECOVERY: "password_recovery",
|
||||||
INVITATION: "invitation",
|
INVITATION: "invitation",
|
||||||
WELCOME: "welcome",
|
WELCOME: "welcome",
|
||||||
|
@ -38,7 +37,6 @@ const TemplateBindings = {
|
||||||
PLATFORM_URL: "platformUrl",
|
PLATFORM_URL: "platformUrl",
|
||||||
COMPANY: "company",
|
COMPANY: "company",
|
||||||
LOGO_URL: "logoUrl",
|
LOGO_URL: "logoUrl",
|
||||||
STYLES: "styles",
|
|
||||||
BODY: "body",
|
BODY: "body",
|
||||||
INVITE_URL: "inviteUrl",
|
INVITE_URL: "inviteUrl",
|
||||||
EMAIL: "email",
|
EMAIL: "email",
|
||||||
|
@ -51,15 +49,11 @@ const TemplateBindings = {
|
||||||
CURRENT_DATE: "currentDate",
|
CURRENT_DATE: "currentDate",
|
||||||
RESET_CODE: "resetCode",
|
RESET_CODE: "resetCode",
|
||||||
INVITE_CODE: "inviteCode",
|
INVITE_CODE: "inviteCode",
|
||||||
|
CONTENTS: "contents",
|
||||||
}
|
}
|
||||||
|
|
||||||
const TemplateMetadata = {
|
const TemplateMetadata = {
|
||||||
[TemplateTypes.EMAIL]: [
|
[TemplateTypes.EMAIL]: [
|
||||||
{
|
|
||||||
name: "Styling",
|
|
||||||
purpose: EmailTemplatePurpose.STYLES,
|
|
||||||
bindings: ["url", "company", "companyUrl", "styles", "body"],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "Base Format",
|
name: "Base Format",
|
||||||
purpose: EmailTemplatePurpose.BASE,
|
purpose: EmailTemplatePurpose.BASE,
|
||||||
|
@ -76,6 +70,7 @@ const TemplateMetadata = {
|
||||||
{
|
{
|
||||||
name: "Custom",
|
name: "Custom",
|
||||||
purpose: EmailTemplatePurpose.CUSTOM,
|
purpose: EmailTemplatePurpose.CUSTOM,
|
||||||
|
bindings: ["contents"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,426 @@
|
||||||
<meta name="supported-color-schemes" content="light dark" />
|
<meta name="supported-color-schemes" content="light dark" />
|
||||||
<title></title>
|
<title></title>
|
||||||
<style type="text/css" rel="stylesheet" media="all">
|
<style type="text/css" rel="stylesheet" media="all">
|
||||||
{{ styles }}
|
@import url('https://fonts.googleapis.com/css2?family=Source+Sans+Pro&display=swap');
|
||||||
|
|
||||||
|
body {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
-webkit-text-size-adjust: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #3869D4;
|
||||||
|
}
|
||||||
|
|
||||||
|
a img {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preheader {
|
||||||
|
display: none !important;
|
||||||
|
visibility: hidden;
|
||||||
|
mso-hide: all;
|
||||||
|
font-size: 1px;
|
||||||
|
line-height: 1px;
|
||||||
|
max-height: 0;
|
||||||
|
max-width: 0;
|
||||||
|
opacity: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Type ------------------------------ */
|
||||||
|
|
||||||
|
body,
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
font-family: "Source Sans Pro", Helvetica, Arial, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin-top: 0;
|
||||||
|
color: #333333;
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-top: 0;
|
||||||
|
color: #333333;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
color: #333333;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
td,
|
||||||
|
th {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p,
|
||||||
|
ul,
|
||||||
|
ol,
|
||||||
|
blockquote {
|
||||||
|
margin: .4em 0 1.1875em;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.625;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.sub {
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Utilities ------------------------------ */
|
||||||
|
|
||||||
|
.align-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buttons ------------------------------ */
|
||||||
|
|
||||||
|
.button {
|
||||||
|
background-color: #3869D4;
|
||||||
|
border-top: 10px solid #3869D4;
|
||||||
|
border-right: 18px solid #3869D4;
|
||||||
|
border-bottom: 10px solid #3869D4;
|
||||||
|
border-left: 18px solid #3869D4;
|
||||||
|
display: inline-block;
|
||||||
|
color: #FFF;
|
||||||
|
text-decoration: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16);
|
||||||
|
-webkit-text-size-adjust: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button--green {
|
||||||
|
background-color: #22BC66;
|
||||||
|
border-top: 10px solid #22BC66;
|
||||||
|
border-right: 18px solid #22BC66;
|
||||||
|
border-bottom: 10px solid #22BC66;
|
||||||
|
border-left: 18px solid #22BC66;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button--red {
|
||||||
|
background-color: #FF6136;
|
||||||
|
border-top: 10px solid #FF6136;
|
||||||
|
border-right: 18px solid #FF6136;
|
||||||
|
border-bottom: 10px solid #FF6136;
|
||||||
|
border-left: 18px solid #FF6136;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 500px) {
|
||||||
|
.button {
|
||||||
|
width: 100% !important;
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attribute list ------------------------------ */
|
||||||
|
|
||||||
|
.attributes {
|
||||||
|
margin: 0 0 21px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attributes_content {
|
||||||
|
background-color: #F4F4F7;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attributes_item {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Related Items ------------------------------ */
|
||||||
|
|
||||||
|
.related {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 25px 0 0 0;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.related_item {
|
||||||
|
padding: 10px 0;
|
||||||
|
color: #CBCCCF;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.related_item-title {
|
||||||
|
display: block;
|
||||||
|
margin: .5em 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.related_item-thumb {
|
||||||
|
display: block;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.related_heading {
|
||||||
|
border-top: 1px solid #CBCCCF;
|
||||||
|
text-align: center;
|
||||||
|
padding: 25px 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Discount Code ------------------------------ */
|
||||||
|
|
||||||
|
.discount {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 24px;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
background-color: #F4F4F7;
|
||||||
|
border: 2px dashed #CBCCCF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.discount_heading {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.discount_body {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Social Icons ------------------------------ */
|
||||||
|
|
||||||
|
.social {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social td {
|
||||||
|
padding: 0;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.social_icon {
|
||||||
|
height: 20px;
|
||||||
|
margin: 0 8px 10px 8px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Data table ------------------------------ */
|
||||||
|
|
||||||
|
.purchase {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 35px 0;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.purchase_content {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 25px 0 0 0;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.purchase_item {
|
||||||
|
padding: 10px 0;
|
||||||
|
color: #51545E;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.purchase_heading {
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px solid #EAEAEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
.purchase_heading p {
|
||||||
|
margin: 0;
|
||||||
|
color: #85878E;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.purchase_footer {
|
||||||
|
padding-top: 15px;
|
||||||
|
border-top: 1px solid #EAEAEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
.purchase_total {
|
||||||
|
margin: 0;
|
||||||
|
text-align: right;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.purchase_total--label {
|
||||||
|
padding: 0 15px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #FFF;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-content {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Masthead ----------------------- */
|
||||||
|
|
||||||
|
.email-masthead {
|
||||||
|
padding: 25px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-masthead_logo {
|
||||||
|
width: 94px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-masthead_name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #A8AAAF;
|
||||||
|
text-decoration: none;
|
||||||
|
text-shadow: 0 1px 0 white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Body ------------------------------ */
|
||||||
|
|
||||||
|
.email-body {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-body_inner {
|
||||||
|
width: 570px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
-premailer-width: 570px;
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-footer {
|
||||||
|
width: 570px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0;
|
||||||
|
-premailer-width: 570px;
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-footer p {
|
||||||
|
color: #A8AAAF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body-action {
|
||||||
|
width: 100%;
|
||||||
|
margin: 30px auto;
|
||||||
|
padding: 0;
|
||||||
|
-premailer-width: 100%;
|
||||||
|
-premailer-cellpadding: 0;
|
||||||
|
-premailer-cellspacing: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body-sub {
|
||||||
|
margin-top: 25px;
|
||||||
|
padding-top: 25px;
|
||||||
|
border-top: 1px solid #EAEAEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-cell {
|
||||||
|
padding: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Media Queries ------------------------------ */
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
.email-body_inner,
|
||||||
|
.email-footer {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
body {
|
||||||
|
background-color: #333333 !important;
|
||||||
|
color: #FFF !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
p,
|
||||||
|
ul,
|
||||||
|
ol,
|
||||||
|
blockquote,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
span,
|
||||||
|
.purchase_item {
|
||||||
|
color: #FFF !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attributes_content,
|
||||||
|
.discount {
|
||||||
|
background-color: #222 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-masthead_name {
|
||||||
|
text-shadow: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
color-scheme: light dark;
|
||||||
|
supported-color-schemes: light dark;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<!--[if mso]>
|
<!--[if mso]>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
<tr>
|
||||||
|
<td class="email-body" width="570" cellpadding="0" cellspacing="0">
|
||||||
|
<table class="email-body_inner" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
|
||||||
|
<!-- Body content -->
|
||||||
|
<tr>
|
||||||
|
<td class="content-cell">
|
||||||
|
<div class="f-fallback">
|
||||||
|
{{ contents }}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
|
@ -17,10 +17,10 @@ exports.EmailTemplates = {
|
||||||
join(__dirname, "invitation.hbs")
|
join(__dirname, "invitation.hbs")
|
||||||
),
|
),
|
||||||
[EmailTemplatePurpose.BASE]: readStaticFile(join(__dirname, "base.hbs")),
|
[EmailTemplatePurpose.BASE]: readStaticFile(join(__dirname, "base.hbs")),
|
||||||
[EmailTemplatePurpose.STYLES]: readStaticFile(join(__dirname, "style.hbs")),
|
|
||||||
[EmailTemplatePurpose.WELCOME]: readStaticFile(
|
[EmailTemplatePurpose.WELCOME]: readStaticFile(
|
||||||
join(__dirname, "welcome.hbs")
|
join(__dirname, "welcome.hbs")
|
||||||
),
|
),
|
||||||
|
[EmailTemplatePurpose.CUSTOM]: readStaticFile(join(__dirname, "custom.hbs")),
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.addBaseTemplates = (templates, type = null) => {
|
exports.addBaseTemplates = (templates, type = null) => {
|
||||||
|
|
|
@ -1,408 +0,0 @@
|
||||||
/* Based on templates: https://github.com/wildbit/postmark-templates/blob/master/templates/plain */
|
|
||||||
/* Base ------------------------------ */
|
|
||||||
|
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Source+Sans+Pro&display=swap');
|
|
||||||
body {
|
|
||||||
width: 100% !important;
|
|
||||||
height: 100%;
|
|
||||||
margin: 0;
|
|
||||||
-webkit-text-size-adjust: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #3869D4;
|
|
||||||
}
|
|
||||||
|
|
||||||
a img {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
word-break: break-word;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preheader {
|
|
||||||
display: none !important;
|
|
||||||
visibility: hidden;
|
|
||||||
mso-hide: all;
|
|
||||||
font-size: 1px;
|
|
||||||
line-height: 1px;
|
|
||||||
max-height: 0;
|
|
||||||
max-width: 0;
|
|
||||||
opacity: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
/* Type ------------------------------ */
|
|
||||||
|
|
||||||
body,
|
|
||||||
td,
|
|
||||||
th {
|
|
||||||
font-family: "Source Sans Pro", Helvetica, Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
margin-top: 0;
|
|
||||||
color: #333333;
|
|
||||||
font-size: 22px;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
margin-top: 0;
|
|
||||||
color: #333333;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
margin-top: 0;
|
|
||||||
color: #333333;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
td,
|
|
||||||
th {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p,
|
|
||||||
ul,
|
|
||||||
ol,
|
|
||||||
blockquote {
|
|
||||||
margin: .4em 0 1.1875em;
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 1.625;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.sub {
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
/* Utilities ------------------------------ */
|
|
||||||
|
|
||||||
.align-right {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.align-left {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.align-center {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
/* Buttons ------------------------------ */
|
|
||||||
|
|
||||||
.button {
|
|
||||||
background-color: #3869D4;
|
|
||||||
border-top: 10px solid #3869D4;
|
|
||||||
border-right: 18px solid #3869D4;
|
|
||||||
border-bottom: 10px solid #3869D4;
|
|
||||||
border-left: 18px solid #3869D4;
|
|
||||||
display: inline-block;
|
|
||||||
color: #FFF;
|
|
||||||
text-decoration: none;
|
|
||||||
border-radius: 3px;
|
|
||||||
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16);
|
|
||||||
-webkit-text-size-adjust: none;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button--green {
|
|
||||||
background-color: #22BC66;
|
|
||||||
border-top: 10px solid #22BC66;
|
|
||||||
border-right: 18px solid #22BC66;
|
|
||||||
border-bottom: 10px solid #22BC66;
|
|
||||||
border-left: 18px solid #22BC66;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button--red {
|
|
||||||
background-color: #FF6136;
|
|
||||||
border-top: 10px solid #FF6136;
|
|
||||||
border-right: 18px solid #FF6136;
|
|
||||||
border-bottom: 10px solid #FF6136;
|
|
||||||
border-left: 18px solid #FF6136;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 500px) {
|
|
||||||
.button {
|
|
||||||
width: 100% !important;
|
|
||||||
text-align: center !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Attribute list ------------------------------ */
|
|
||||||
|
|
||||||
.attributes {
|
|
||||||
margin: 0 0 21px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attributes_content {
|
|
||||||
background-color: #F4F4F7;
|
|
||||||
padding: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.attributes_item {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
/* Related Items ------------------------------ */
|
|
||||||
|
|
||||||
.related {
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 25px 0 0 0;
|
|
||||||
-premailer-width: 100%;
|
|
||||||
-premailer-cellpadding: 0;
|
|
||||||
-premailer-cellspacing: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.related_item {
|
|
||||||
padding: 10px 0;
|
|
||||||
color: #CBCCCF;
|
|
||||||
font-size: 15px;
|
|
||||||
line-height: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.related_item-title {
|
|
||||||
display: block;
|
|
||||||
margin: .5em 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.related_item-thumb {
|
|
||||||
display: block;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.related_heading {
|
|
||||||
border-top: 1px solid #CBCCCF;
|
|
||||||
text-align: center;
|
|
||||||
padding: 25px 0 10px;
|
|
||||||
}
|
|
||||||
/* Discount Code ------------------------------ */
|
|
||||||
|
|
||||||
.discount {
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 24px;
|
|
||||||
-premailer-width: 100%;
|
|
||||||
-premailer-cellpadding: 0;
|
|
||||||
-premailer-cellspacing: 0;
|
|
||||||
background-color: #F4F4F7;
|
|
||||||
border: 2px dashed #CBCCCF;
|
|
||||||
}
|
|
||||||
|
|
||||||
.discount_heading {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.discount_body {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 15px;
|
|
||||||
}
|
|
||||||
/* Social Icons ------------------------------ */
|
|
||||||
|
|
||||||
.social {
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.social td {
|
|
||||||
padding: 0;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.social_icon {
|
|
||||||
height: 20px;
|
|
||||||
margin: 0 8px 10px 8px;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
/* Data table ------------------------------ */
|
|
||||||
|
|
||||||
.purchase {
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 35px 0;
|
|
||||||
-premailer-width: 100%;
|
|
||||||
-premailer-cellpadding: 0;
|
|
||||||
-premailer-cellspacing: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.purchase_content {
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 25px 0 0 0;
|
|
||||||
-premailer-width: 100%;
|
|
||||||
-premailer-cellpadding: 0;
|
|
||||||
-premailer-cellspacing: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.purchase_item {
|
|
||||||
padding: 10px 0;
|
|
||||||
color: #51545E;
|
|
||||||
font-size: 15px;
|
|
||||||
line-height: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.purchase_heading {
|
|
||||||
padding-bottom: 8px;
|
|
||||||
border-bottom: 1px solid #EAEAEC;
|
|
||||||
}
|
|
||||||
|
|
||||||
.purchase_heading p {
|
|
||||||
margin: 0;
|
|
||||||
color: #85878E;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.purchase_footer {
|
|
||||||
padding-top: 15px;
|
|
||||||
border-top: 1px solid #EAEAEC;
|
|
||||||
}
|
|
||||||
|
|
||||||
.purchase_total {
|
|
||||||
margin: 0;
|
|
||||||
text-align: right;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.purchase_total--label {
|
|
||||||
padding: 0 15px 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: #FFF;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.email-wrapper {
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
-premailer-width: 100%;
|
|
||||||
-premailer-cellpadding: 0;
|
|
||||||
-premailer-cellspacing: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.email-content {
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
-premailer-width: 100%;
|
|
||||||
-premailer-cellpadding: 0;
|
|
||||||
-premailer-cellspacing: 0;
|
|
||||||
}
|
|
||||||
/* Masthead ----------------------- */
|
|
||||||
|
|
||||||
.email-masthead {
|
|
||||||
padding: 25px 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.email-masthead_logo {
|
|
||||||
width: 94px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.email-masthead_name {
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #A8AAAF;
|
|
||||||
text-decoration: none;
|
|
||||||
text-shadow: 0 1px 0 white;
|
|
||||||
}
|
|
||||||
/* Body ------------------------------ */
|
|
||||||
|
|
||||||
.email-body {
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
-premailer-width: 100%;
|
|
||||||
-premailer-cellpadding: 0;
|
|
||||||
-premailer-cellspacing: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.email-body_inner {
|
|
||||||
width: 570px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0;
|
|
||||||
-premailer-width: 570px;
|
|
||||||
-premailer-cellpadding: 0;
|
|
||||||
-premailer-cellspacing: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.email-footer {
|
|
||||||
width: 570px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0;
|
|
||||||
-premailer-width: 570px;
|
|
||||||
-premailer-cellpadding: 0;
|
|
||||||
-premailer-cellspacing: 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.email-footer p {
|
|
||||||
color: #A8AAAF;
|
|
||||||
}
|
|
||||||
|
|
||||||
.body-action {
|
|
||||||
width: 100%;
|
|
||||||
margin: 30px auto;
|
|
||||||
padding: 0;
|
|
||||||
-premailer-width: 100%;
|
|
||||||
-premailer-cellpadding: 0;
|
|
||||||
-premailer-cellspacing: 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.body-sub {
|
|
||||||
margin-top: 25px;
|
|
||||||
padding-top: 25px;
|
|
||||||
border-top: 1px solid #EAEAEC;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-cell {
|
|
||||||
padding: 35px;
|
|
||||||
}
|
|
||||||
/*Media Queries ------------------------------ */
|
|
||||||
|
|
||||||
@media only screen and (max-width: 600px) {
|
|
||||||
.email-body_inner,
|
|
||||||
.email-footer {
|
|
||||||
width: 100% !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
body {
|
|
||||||
background-color: #333333 !important;
|
|
||||||
color: #FFF !important;
|
|
||||||
}
|
|
||||||
p,
|
|
||||||
ul,
|
|
||||||
ol,
|
|
||||||
blockquote,
|
|
||||||
h1,
|
|
||||||
h2,
|
|
||||||
h3,
|
|
||||||
span,
|
|
||||||
.purchase_item {
|
|
||||||
color: #FFF !important;
|
|
||||||
}
|
|
||||||
.attributes_content,
|
|
||||||
.discount {
|
|
||||||
background-color: #222 !important;
|
|
||||||
}
|
|
||||||
.email-masthead_name {
|
|
||||||
text-shadow: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
|
||||||
color-scheme: light dark;
|
|
||||||
supported-color-schemes: light dark;
|
|
||||||
}
|
|
|
@ -28,8 +28,8 @@ module.exports = {
|
||||||
SALT_ROUNDS: process.env.SALT_ROUNDS,
|
SALT_ROUNDS: process.env.SALT_ROUNDS,
|
||||||
REDIS_URL: process.env.REDIS_URL,
|
REDIS_URL: process.env.REDIS_URL,
|
||||||
REDIS_PASSWORD: process.env.REDIS_PASSWORD,
|
REDIS_PASSWORD: process.env.REDIS_PASSWORD,
|
||||||
|
INTERNAL_KEY: process.env.INTERNAL_KEY,
|
||||||
/* TODO: to remove - once deployment removed */
|
/* TODO: to remove - once deployment removed */
|
||||||
SELF_HOST_KEY: process.env.SELF_HOST_KEY,
|
|
||||||
COUCH_DB_USERNAME: process.env.COUCH_DB_USERNAME,
|
COUCH_DB_USERNAME: process.env.COUCH_DB_USERNAME,
|
||||||
COUCH_DB_PASSWORD: process.env.COUCH_DB_PASSWORD,
|
COUCH_DB_PASSWORD: process.env.COUCH_DB_PASSWORD,
|
||||||
_set(key, value) {
|
_set(key, value) {
|
||||||
|
|
|
@ -54,16 +54,14 @@ async function buildEmail(purpose, email, user) {
|
||||||
if (FULL_EMAIL_PURPOSES.indexOf(purpose) === -1) {
|
if (FULL_EMAIL_PURPOSES.indexOf(purpose) === -1) {
|
||||||
throw `Unable to build an email of type ${purpose}`
|
throw `Unable to build an email of type ${purpose}`
|
||||||
}
|
}
|
||||||
let [base, styles, body] = await Promise.all([
|
let [base, body] = await Promise.all([
|
||||||
getTemplateByPurpose(TYPE, EmailTemplatePurpose.BASE),
|
getTemplateByPurpose(TYPE, EmailTemplatePurpose.BASE),
|
||||||
getTemplateByPurpose(TYPE, EmailTemplatePurpose.STYLES),
|
|
||||||
getTemplateByPurpose(TYPE, purpose),
|
getTemplateByPurpose(TYPE, purpose),
|
||||||
])
|
])
|
||||||
if (!base || !styles || !body) {
|
if (!base || !body) {
|
||||||
throw "Unable to build email, missing base components"
|
throw "Unable to build email, missing base components"
|
||||||
}
|
}
|
||||||
base = base.contents
|
base = base.contents
|
||||||
styles = styles.contents
|
|
||||||
body = body.contents
|
body = body.contents
|
||||||
|
|
||||||
// if there is a link code needed this will retrieve it
|
// if there is a link code needed this will retrieve it
|
||||||
|
@ -75,11 +73,9 @@ async function buildEmail(purpose, email, user) {
|
||||||
}
|
}
|
||||||
|
|
||||||
body = await processString(body, context)
|
body = await processString(body, context)
|
||||||
styles = await processString(styles, context)
|
|
||||||
// this should now be the complete email HTML
|
// this should now be the complete email HTML
|
||||||
return processString(base, {
|
return processString(base, {
|
||||||
...context,
|
...context,
|
||||||
styles,
|
|
||||||
body,
|
body,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -117,11 +113,17 @@ exports.isEmailConfigured = async (groupId = null) => {
|
||||||
* @param {string} email The email address to send to.
|
* @param {string} email The email address to send to.
|
||||||
* @param {string} purpose The purpose of the email being sent (e.g. reset password).
|
* @param {string} purpose The purpose of the email being sent (e.g. reset password).
|
||||||
* @param {string|undefined} groupId If finer grain controls being used then this will lookup config for group.
|
* @param {string|undefined} groupId If finer grain controls being used then this will lookup config for group.
|
||||||
* @param {object|undefined} user if sending to an existing user the object can be provided, this is used in the context.
|
* @param {object|undefined} user If sending to an existing user the object can be provided, this is used in the context.
|
||||||
|
* @param {string|undefined} from If sending from an address that is not what is configured in the SMTP config.
|
||||||
|
* @param {string|undefined} contents If sending a custom email then can supply contents which will be added to it.
|
||||||
* @return {Promise<object>} returns details about the attempt to send email, e.g. if it is successful; based on
|
* @return {Promise<object>} returns details about the attempt to send email, e.g. if it is successful; based on
|
||||||
* nodemailer response.
|
* nodemailer response.
|
||||||
*/
|
*/
|
||||||
exports.sendEmail = async (email, purpose, { groupId, user } = {}) => {
|
exports.sendEmail = async (
|
||||||
|
email,
|
||||||
|
purpose,
|
||||||
|
{ groupId, user, from, contents } = {}
|
||||||
|
) => {
|
||||||
const db = new CouchDB(GLOBAL_DB)
|
const db = new CouchDB(GLOBAL_DB)
|
||||||
const config = await getSmtpConfiguration(db, groupId)
|
const config = await getSmtpConfiguration(db, groupId)
|
||||||
if (!config) {
|
if (!config) {
|
||||||
|
@ -129,7 +131,7 @@ exports.sendEmail = async (email, purpose, { groupId, user } = {}) => {
|
||||||
}
|
}
|
||||||
const transport = createSMTPTransport(config)
|
const transport = createSMTPTransport(config)
|
||||||
const message = {
|
const message = {
|
||||||
from: config.from,
|
from: from || config.from,
|
||||||
subject: config.subject,
|
subject: config.subject,
|
||||||
to: email,
|
to: email,
|
||||||
html: await buildEmail(purpose, email, user),
|
html: await buildEmail(purpose, email, user),
|
||||||
|
|
Loading…
Reference in New Issue