mirror of
https://github.com/nodemailer/wildduck.git
synced 2024-12-26 01:40:48 +08:00
Merge branch 'master' of github.com:nodemailer/wildduck
This commit is contained in:
commit
5af8f24ddb
4 changed files with 121 additions and 107 deletions
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -1,5 +1,18 @@
|
|||
# Changelog
|
||||
|
||||
## [1.43.0](https://github.com/nodemailer/wildduck/compare/v1.42.6...v1.43.0) (2024-04-29)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **autoacme:** Allow setting up automatic ACME certificate generation ([cd8596a](https://github.com/nodemailer/wildduck/commit/cd8596a84d36f9870858f3fdc4249f2af42347d9))
|
||||
* **SNI:** Autogenerate TLS certificates for SNI ([40db519](https://github.com/nodemailer/wildduck/commit/40db519d9c08ebe588a6ce820f6287d4f52f038f))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **SNI:** delete expired autogenerated SNI certificate ([61c03e1](https://github.com/nodemailer/wildduck/commit/61c03e1725c68fcb0c41e505b4d8cb80b0d73d15))
|
||||
|
||||
## [1.42.6](https://github.com/nodemailer/wildduck/compare/v1.42.5...v1.42.6) (2024-04-22)
|
||||
|
||||
|
||||
|
|
|
@ -12,8 +12,11 @@ const tools = require('../tools');
|
|||
const Maildropper = require('../maildropper');
|
||||
const roles = require('../roles');
|
||||
const Transform = require('stream').Transform;
|
||||
const { sessSchema, sessIPSchema, booleanSchema } = require('../schemas');
|
||||
const { sessSchema, sessIPSchema, booleanSchema, metaDataSchema } = require('../schemas');
|
||||
const { preprocessAttachments } = require('../data-url');
|
||||
const { userId, mailboxId } = require('../schemas/request/general-schemas');
|
||||
const { AddressOptionalName, AddressOptionalNameArray, Header, Attachment, ReferenceWithAttachments } = require('../schemas/request/messages-schemas');
|
||||
const { successRes } = require('../schemas/response/general-schemas');
|
||||
|
||||
class StreamCollect extends Transform {
|
||||
constructor() {
|
||||
|
@ -620,113 +623,111 @@ module.exports = (db, server, messageHandler, userHandler, settingsHandler) => {
|
|||
const submitMessageWrapper = util.promisify(submitMessage);
|
||||
|
||||
server.post(
|
||||
{ name: 'send', path: '/users/:user/submit' },
|
||||
{
|
||||
name: 'send',
|
||||
path: '/users/:user/submit',
|
||||
tags: ['Submission'],
|
||||
summary: 'Submit a Message for Delivery',
|
||||
description: 'Use this method to send emails from a user account',
|
||||
validationObjs: {
|
||||
requestBody: {
|
||||
mailbox: mailboxId,
|
||||
from: AddressOptionalName.description('Addres for the From: header'),
|
||||
replyTo: AddressOptionalName.description('Address for the Reply-To: header'),
|
||||
to: Joi.array()
|
||||
.items(
|
||||
Joi.object({
|
||||
name: Joi.string().empty('').max(255).description('Name of the sender'),
|
||||
address: Joi.string().email({ tlds: false }).failover('').required().description('Address of the sender')
|
||||
}).$_setFlag('objectName', 'AddressOptionalName')
|
||||
)
|
||||
.description('Addresses for the To: header'),
|
||||
|
||||
cc: AddressOptionalNameArray.description('Addresses for the Cc: header'),
|
||||
|
||||
bcc: AddressOptionalNameArray.description('Addresses for the Bcc: header'),
|
||||
|
||||
headers: Joi.array()
|
||||
.items(Header)
|
||||
.description(
|
||||
'Custom headers for the message. If reference message is set then In-Reply-To and References headers are set automatically'
|
||||
),
|
||||
subject: Joi.string()
|
||||
.empty('')
|
||||
.max(2 * 1024)
|
||||
.description('Message subject. If not then resolved from Reference message'),
|
||||
text: Joi.string()
|
||||
.empty('')
|
||||
.max(1024 * 1024)
|
||||
.description('Plaintext message'),
|
||||
html: Joi.string()
|
||||
.empty('')
|
||||
.max(1024 * 1024)
|
||||
.description('HTML formatted message'),
|
||||
attachments: Joi.array().items(Attachment).description('Attachments for the message'),
|
||||
|
||||
meta: metaDataSchema.label('metaData').description('Optional metadata, must be an object or JSON formatted string'),
|
||||
sess: sessSchema,
|
||||
ip: sessIPSchema,
|
||||
reference: ReferenceWithAttachments.description(
|
||||
'Optional referenced email. If uploaded message is a reply draft and relevant fields are not provided then these are resolved from the message to be replied to'
|
||||
),
|
||||
// if true then treat this message as a draft
|
||||
isDraft: booleanSchema.default(false).description('Is the message a draft or not'),
|
||||
// if set then this message is based on a draft that should be deleted after processing
|
||||
draft: Joi.object()
|
||||
.keys({
|
||||
mailbox: mailboxId,
|
||||
id: Joi.number().required().description('Message ID')
|
||||
})
|
||||
.description('Draft message to base this one on'),
|
||||
sendTime: Joi.date().description('Send time'),
|
||||
uploadOnly: booleanSchema.default(false).description('If true only uploads the message but does not send it'),
|
||||
envelope: Joi.object()
|
||||
.keys({
|
||||
from: AddressOptionalName.description('Addres for the From: header'),
|
||||
to: Joi.array().items(
|
||||
Joi.object()
|
||||
.keys({
|
||||
name: Joi.string().empty('').max(255).description('Name of the sender'),
|
||||
address: Joi.string().email({ tlds: false }).required().description('Address of the sender')
|
||||
})
|
||||
.description('Addresses for the To: header')
|
||||
)
|
||||
})
|
||||
.description('Optional envelope')
|
||||
},
|
||||
queryParams: {},
|
||||
pathParams: {
|
||||
user: userId
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
description: 'Success',
|
||||
model: Joi.object({
|
||||
success: successRes,
|
||||
message: Joi.object({
|
||||
mailbox: Joi.string().required().description('Mailbox ID the message was stored to'),
|
||||
id: Joi.number().description('Message ID in the Mailbox').required(),
|
||||
queueId: Joi.string().required().description('Queue ID in MTA')
|
||||
})
|
||||
.required()
|
||||
.description('Information about submitted Message')
|
||||
.$_setFlag('objectName', 'MessageWithQueueId')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
tools.responseWrapper(async (req, res) => {
|
||||
res.charSet('utf-8');
|
||||
|
||||
const schema = Joi.object().keys({
|
||||
user: Joi.string().hex().lowercase().length(24).required(),
|
||||
const { pathParams, requestBody, queryParams } = req.route.spec.validationObjs;
|
||||
|
||||
mailbox: Joi.string().hex().lowercase().length(24),
|
||||
|
||||
reference: Joi.object().keys({
|
||||
mailbox: Joi.string().hex().lowercase().length(24).required(),
|
||||
id: Joi.number().required(),
|
||||
action: Joi.string().valid('reply', 'replyAll', 'forward').required()
|
||||
}),
|
||||
|
||||
// if true then treat this message as a draft
|
||||
isDraft: booleanSchema.default(false),
|
||||
|
||||
// if set then this message is based on a draft that should be deleted after processing
|
||||
draft: Joi.object().keys({
|
||||
mailbox: Joi.string().hex().lowercase().length(24).required(),
|
||||
id: Joi.number().required()
|
||||
}),
|
||||
|
||||
uploadOnly: booleanSchema.default(false),
|
||||
|
||||
sendTime: Joi.date(),
|
||||
|
||||
envelope: Joi.object().keys({
|
||||
from: Joi.object().keys({
|
||||
name: Joi.string().empty('').max(255),
|
||||
address: Joi.string().email({ tlds: false }).required()
|
||||
}),
|
||||
to: Joi.array().items(
|
||||
Joi.object().keys({
|
||||
name: Joi.string().empty('').max(255),
|
||||
address: Joi.string().email({ tlds: false }).required()
|
||||
})
|
||||
)
|
||||
}),
|
||||
|
||||
from: Joi.object().keys({
|
||||
name: Joi.string().empty('').max(255),
|
||||
address: Joi.string().email({ tlds: false }).required()
|
||||
}),
|
||||
|
||||
replyTo: Joi.object().keys({
|
||||
name: Joi.string().empty('').max(255),
|
||||
address: Joi.string().email({ tlds: false }).required()
|
||||
}),
|
||||
|
||||
to: Joi.array().items(
|
||||
Joi.object().keys({
|
||||
name: Joi.string().empty('').max(255),
|
||||
address: Joi.string().email({ tlds: false }).required()
|
||||
})
|
||||
),
|
||||
|
||||
cc: Joi.array().items(
|
||||
Joi.object().keys({
|
||||
name: Joi.string().empty('').max(255),
|
||||
address: Joi.string().email({ tlds: false }).required()
|
||||
})
|
||||
),
|
||||
|
||||
bcc: Joi.array().items(
|
||||
Joi.object().keys({
|
||||
name: Joi.string().empty('').max(255),
|
||||
address: Joi.string().email({ tlds: false }).required()
|
||||
})
|
||||
),
|
||||
|
||||
headers: Joi.array().items(
|
||||
Joi.object().keys({
|
||||
key: Joi.string().empty('').max(255),
|
||||
value: Joi.string()
|
||||
.empty('')
|
||||
.max(100 * 1024)
|
||||
})
|
||||
),
|
||||
|
||||
subject: Joi.string()
|
||||
.empty('')
|
||||
.max(2 * 1024),
|
||||
text: Joi.string()
|
||||
.empty('')
|
||||
.max(1024 * 1024),
|
||||
html: Joi.string()
|
||||
.empty('')
|
||||
.max(1024 * 1024),
|
||||
|
||||
attachments: Joi.array().items(
|
||||
Joi.object().keys({
|
||||
filename: Joi.string().empty('').max(255),
|
||||
|
||||
contentType: Joi.string().empty('').max(255),
|
||||
contentTransferEncoding: Joi.string().empty('').trim().lowercase(),
|
||||
contentDisposition: Joi.string().empty('').trim().lowercase().valid('inline', 'attachment'),
|
||||
cid: Joi.string().empty('').max(255),
|
||||
|
||||
encoding: Joi.string().empty('').default('base64'),
|
||||
content: Joi.string().required()
|
||||
})
|
||||
),
|
||||
meta: Joi.object().unknown(true),
|
||||
sess: sessSchema,
|
||||
ip: sessIPSchema
|
||||
const schema = Joi.object({
|
||||
...pathParams,
|
||||
...requestBody,
|
||||
...queryParams
|
||||
});
|
||||
|
||||
// extract embedded attachments from HTML
|
||||
|
|
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "wildduck",
|
||||
"version": "1.42.6",
|
||||
"version": "1.43.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "wildduck",
|
||||
"version": "1.42.6",
|
||||
"version": "1.43.0",
|
||||
"license": "EUPL-1.2",
|
||||
"dependencies": {
|
||||
"@fidm/x509": "1.2.1",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "wildduck",
|
||||
"version": "1.42.6",
|
||||
"version": "1.43.0",
|
||||
"description": "IMAP/POP3 server built with Node.js and MongoDB",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
|
|
Loading…
Reference in a new issue