From cfa3fde43667aafb0d546cbbe2f69bf88df7345f Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Mon, 3 Feb 2025 13:11:29 -0500 Subject: [PATCH] dev: error handling and text encoding --- .../src/modules/mail/UserSendMailService.js | 40 +++++++++++++++++-- src/puter-js/src/modules/Email.js | 13 +++++- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/src/backend/src/modules/mail/UserSendMailService.js b/src/backend/src/modules/mail/UserSendMailService.js index dc3ec30d2..67a678b13 100644 --- a/src/backend/src/modules/mail/UserSendMailService.js +++ b/src/backend/src/modules/mail/UserSendMailService.js @@ -1,5 +1,7 @@ +const APIError = require("../../api/APIError"); const BaseService = require("../../services/BaseService"); const { Context } = require("../../util/context"); +const validator = require('validator') class UserSendMailService extends BaseService { async ['__on_driver.register.interfaces'] () { @@ -18,7 +20,10 @@ class UserSendMailService extends BaseService { subject: { type: 'string', }, - html: { + body: { + type: 'string', + }, + encoding: { type: 'string', }, }, @@ -29,7 +34,7 @@ class UserSendMailService extends BaseService { } static IMPLEMENTS = { 'puter-send-mail': { - async send ({ to, subject, html }) { + async send ({ to, subject, body, encoding }) { const actor = Context.get('actor'); const svc_email = this.services.get('email'); @@ -37,11 +42,40 @@ class UserSendMailService extends BaseService { throw new Error('Only users can send email.'); } const user = actor.type.user; + + encoding = encoding ?? 'html'; + if ( ! ['html', 'text'].includes(encoding) ) { + throw APIError.create('field_invalid', null, { + key: 'encoding', + expected: 'html or text', + got: encoding, + }); + } + + if ( ! validator.isEmail(to) ) { + throw APIError.create('field_invalid', null, { + key: 'to', + expected: 'a valid email address', + got: to, + }); + } + + // We're going to disallow subject lines over or including 998, + // as nobody would ever do this unless they're trying to + // exploit a faulty email client. + if ( subject.length >= 998 ) { + throw APIError.create('field_too_long', null, { + key: 'subject', + max_length: 997, + }); + } const transporter = svc_email.get_transport_(); const o = { from: `${user.username}@${this.config.domain}`, // sender address - to, subject, html, + to, + subject, + [encoding === 'html' ? 'html' : 'text']: body, }; await transporter.sendMail(o); } diff --git a/src/puter-js/src/modules/Email.js b/src/puter-js/src/modules/Email.js index d1720abbe..7114b0fca 100644 --- a/src/puter-js/src/modules/Email.js +++ b/src/puter-js/src/modules/Email.js @@ -45,17 +45,26 @@ class Email{ throw ({message: 'Arguments are required', code: 'arguments_required'}); } + let opt_i = 0; if(typeof args[0] === 'object'){ options = args[0]; + opt_i = 1; }else{ options = { to: args[0], subject: args[1], - html: args[2] + body: args[2] + } + opt_i = 3; + } + + for ( const opt of args.slice(opt_i) ) { + if ( typeof opt === 'object' ) { + Object.assign(options, opt); } } - return utils.make_driver_method(['to', 'subject', 'html'], 'temp-email', 'send').call(this, options); + return utils.make_driver_method(['to', 'subject', 'body'], 'puter-send-mail', undefined, 'send').call(this, options); } }