refactor: normalize email calls

This commit is contained in:
KernelDeimos 2024-04-29 17:34:10 -04:00
parent 8cad610a54
commit c44028f413
8 changed files with 122 additions and 132 deletions

View File

@ -0,0 +1,2 @@
### `vscode`
- `es6-string-html`

14
package-lock.json generated
View File

@ -5276,6 +5276,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/dedent": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz",
"integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==",
"peerDependencies": {
"babel-plugin-macros": "^3.1.0"
},
"peerDependenciesMeta": {
"babel-plugin-macros": {
"optional": true
}
}
},
"node_modules/deep-eql": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz",
@ -10859,6 +10872,7 @@
"composite-error": "^1.0.2",
"compression": "^1.7.4",
"cookie-parser": "^1.4.6",
"dedent": "^1.5.3",
"express": "^4.18.2",
"file-type": "^18.5.0",
"form-data": "^4.0.0",

View File

@ -28,6 +28,7 @@
"composite-error": "^1.0.2",
"compression": "^1.7.4",
"cookie-parser": "^1.4.6",
"dedent": "^1.5.3",
"express": "^4.18.2",
"file-type": "^18.5.0",
"form-data": "^4.0.0",

View File

@ -195,6 +195,9 @@ const install = async ({ services, app }) => {
const { EdgeRateLimitService } = require('./services/abuse-prevention/EdgeRateLimitService');
services.registerService('edge-rate-limit', EdgeRateLimitService);
const { Emailservice } = require('./services/EmailService');
services.registerService('email', Emailservice);
}
const install_legacy = async ({ services }) => {
@ -206,7 +209,6 @@ const install_legacy = async ({ services }) => {
const { OperationTraceService } = require('./services/OperationTraceService');
const { WSPushService } = require('./services/WSPushService');
const { ReferralCodeService } = require('./services/ReferralCodeService');
const { Emailservice } = require('./services/EmailService');
const { ClientOperationService } = require('./services/ClientOperationService');
const { EngPortalService } = require('./services/EngPortalService');
const { AppInformationService } = require('./services/AppInformationService');
@ -220,7 +222,6 @@ const install_legacy = async ({ services }) => {
services.registerService('operationTrace', OperationTraceService);
services.registerService('__event-push-ws', WSPushService);
services.registerService('referral-code', ReferralCodeService);
services.registerService('email', Emailservice);
services.registerService('file-cache', FileCacheService);
services.registerService('client-operation', ClientOperationService);
services.registerService('app-information', AppInformationService);

View File

@ -1547,56 +1547,16 @@ async function generate_system_fsentries(user){
}
function send_email_verification_code(email_confirm_code, email){
const nodemailer = require("nodemailer");
// send email notif
let transporter = nodemailer.createTransport({
host: config.smtp_server,
port: config.smpt_port,
secure: true, // STARTTLS
auth: {
user: config.smtp_username,
pass: config.smtp_password,
},
});
transporter.sendMail({
from: '"Puter" no-reply@puter.com', // sender address
to: email, // list of receivers
subject: `${hyphenize_confirm_code(email_confirm_code)} is your confirmation code`, // Subject line
html: `<p>Hi there,</p>
<p><strong>${hyphenize_confirm_code(email_confirm_code)}</strong> is your email confirmation code.</p>
<p>Sincerely,</p>
<p>Puter</p>
`,
});
const svc_email = Context.get('services').get('email');
svc_email.send_email({ email }, 'email_verification_code', {
code: hyphenize_confirm_code(email_confirm_code),
})
}
function send_email_verification_token(email_confirm_token, email, user_uuid){
const nodemailer = require("nodemailer");
// send email notif
let transporter = nodemailer.createTransport({
host: config.smtp_server,
port: config.smpt_port,
secure: true, // STARTTLS
auth: {
user: config.smtp_username,
pass: config.smtp_password,
},
});
let link = `${config.origin}/confirm-email-by-token?user_uuid=${user_uuid}&token=${email_confirm_token}`;
transporter.sendMail({
from: '"Puter" no-reply@puter.com', // sender address
to: email, // list of receivers
subject: `Please confirm your email`, // Subject line
html: `<p>Hi there,</p>
<p>Please confirm your email address using this link: <strong><a href="${link}">${link}</a></strong>.</p>
<p>Sincerely,</p>
<p>Puter</p>
`,
});
const svc_email = Context.get('services').get('email');
const link = `${config.origin}/confirm-email-by-token?user_uuid=${user_uuid}&token=${email_confirm_token}`;
svc_email.send_email({ email }, 'email_verification_link', { link });
}
async function generate_random_username(){

View File

@ -71,20 +71,8 @@ router.post('/contactUs', auth, express.json(), async (req, res, next)=>{
let user = await get_user({id: req.user.id});
// send email to support
const nodemailer = require("nodemailer");
// send email notif
let transporter = nodemailer.createTransport({
host: config.smtp_server,
port: config.smpt_port,
secure: true, // STARTTLS
auth: {
user: config.smtp_username,
pass: config.smtp_password,
},
});
transporter.sendMail({
const svc_email = req.services.get('email');
svc_email.sendMail({
from: '"Puter" no-reply@puter.com', // sender address
to: 'support@puter.com', // list of receivers
replyTo: user.email === null ? undefined : user.email,

View File

@ -86,31 +86,12 @@ router.post('/send-pass-recovery-email', express.json(), body_parser_error_handl
);
invalidate_cached_user(user);
// prepare email
let transporter = nodemailer.createTransport({
host: config.smtp_server,
port: config.smpt_port,
secure: true, // STARTTLS
auth: {
user: config.smtp_username,
pass: config.smtp_password,
},
});
// create link
const rec_link = config.origin + '/action/set-new-password?user=' + user.uuid + '&token=' + token;
// send email
transporter.sendMail({
from: 'no-reply@puter.com', // sender address
to: user.email, // list of receivers
subject: "Password Recovery", // Subject line
html: `
<p>Hi there,</p>
<p>A password recovery request was issued for your account, please follow the link below to reset your password:</p>
<p><a href="${rec_link}">${rec_link}</a></p>
<p>Sincerely,</p>
<p>Puter</p>`,
const svc_email = req.services.get('email');
await svc_email.send_email({ email: user.email }, 'email_password_recovery', {
link: rec_link,
});
// Send response

View File

@ -16,30 +16,22 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { AdvancedBase } = require("@heyputer/puter-js-common");
class Emailservice extends AdvancedBase {
static MODULES = {
nodemailer: require('nodemailer'),
handlebars: require('handlebars'),
};
const BaseService = require('./BaseService');
constructor ({ services, config }) {
super();
this.config = config;
this.templates = {
'new-referral': {
subject: `You've made a referral!`,
html: `<p>Hi there,</p>
<p>A new user has used your referral code. Enjoy an extra {{storage_increase}} of storage, on the house!</p>
<p>Sincerely,</p>
<p>Puter</p>
`,
},
'approved-for-listing': {
subject: '\u{1f389} Your app has been approved for listing!',
html: `
const TEMPLATES = {
'new-referral': {
subject: `You've made a referral!`,
html: `
<p>Hi there,</p>
<p>A new user has used your referral code. Enjoy an extra {{storage_increase}} of storage, on the house!</p>
<p>Sincerely,</p>
<p>Puter</p>
`,
},
'approved-for-listing': {
subject: '\u{1f389} Your app has been approved for listing!',
html: `
<p>Hi there,</p>
<p>
Exciting news! <a href="https://puter.com/app/{{app_name}}">{{app_title}}</a> is now approved and live on <a href="https://puter.com/app/app-center" target="_blank">Puter App Center</a>. It's now ready for users worldwide to discover and enjoy.
@ -51,11 +43,11 @@ Exciting news! <a href="https://puter.com/app/{{app_name}}">{{app_title}}</a> is
<p>Best,<br />
The Puter Team
</p>
`,
},
'email_change_request': {
subject: '\u{1f4dd} Confirm your email change',
html: `
`,
},
'email_change_request': {
subject: '\u{1f4dd} Confirm your email change',
html: `
<p>Hi there,</p>
<p>
We received a request to link this email to the user "{{username}}" on Puter. If you made this request, please click the link below to confirm the change. If you did not make this request, please ignore this email.
@ -64,59 +56,110 @@ We received a request to link this email to the user "{{username}}" on Puter. If
<p>
<a href="{{confirm_url}}">Confirm email change</a>
</p>
`,
},
'email_change_notification': {
subject: '\u{1f4dd} Notification of email change',
html: `
`,
},
'email_change_notification': {
subject: '\u{1f4dd} Notification of email change',
html: `
<p>Hi there,</p>
<p>
We're sending an email to let you know about a change to your account.
We have sent a confirmation to "{{new_email}}" to confirm an email change request.
If this was not you, please contact support@puter.com immediately.
</p>
`,
},
};
`,
},
'email_verification_code': {
subject: `{{code}} is your confirmation code`,
html: /*html*/`
<p>Hi there,</p>
<p><strong>{{code}}</strong> is your email confirmation code.</p>
<p>Sincerely,</p>
<p>Puter</p>
`
},
'email_verification_link': {
subject: `Please confirm your email`,
html: /*html*/`
<p>Hi there,</p>
<p>Please confirm your email address using this link: <strong><a href="{{link}}">{{link}}</a></strong>.</p>
<p>Sincerely,</p>
<p>Puter</p>
`
},
'email_password_recovery': {
subject: `Password Recovery`,
html: /*html*/`
<p>Hi there,</p>
<p>A password recovery request was issued for your account, please follow the link below to reset your password:</p>
<p><a href="{{link}}">{{link}}</a></p>
<p>Sincerely,</p>
<p>Puter</p>
`,
},
}
class Emailservice extends BaseService {
static MODULES = {
nodemailer: require('nodemailer'),
handlebars: require('handlebars'),
dedent: require('dedent'),
};
_construct () {
this.templates = TEMPLATES;
this.template_fns = {};
for ( const k in this.templates ) {
const template = this.templates[k];
this.template_fns[k] = values => {
const html = this.modules.handlebars.compile(template.html);
const subject = this.modules.handlebars.compile(template.subject);
const html =
this.modules.handlebars.compile(
this.modules.dedent(template.html));
return {
...template,
subject: subject(values),
html: html(values),
};
}
}
}
async send_email (user, template, values) {
const config = this.config;
_init () {
console.log('the config', this.config);
}
get_transport_ () {
const nodemailer = this.modules.nodemailer;
let transporter = nodemailer.createTransport({
host: config.smtp_server,
port: config.smpt_port,
secure: true, // STARTTLS
auth: {
user: config.smtp_username,
pass: config.smtp_password,
},
});
const config = { ...this.config };
delete config.engine;
let transport = nodemailer.createTransport(config);
return transport;
}
async send_email (user, template, values) {
const email = user.email;
const template_fn = this.template_fns[template];
const { subject, html } = template_fn(values);
const transporter = this.get_transport_();
transporter.sendMail({
from: '"Puter" no-reply@puter.com', // sender address
to: email, // list of receivers
subject, html,
});
}
// simple passthrough to nodemailer
sendMail (params) {
const transporter = this.get_transport_();
transporter.sendMail(params);
}
}
module.exports = {