diff --git a/docs/api/openapi.yml b/docs/api/openapi.yml index 00df5003..336052a5 100644 --- a/docs/api/openapi.yml +++ b/docs/api/openapi.yml @@ -1421,7 +1421,7 @@ paths: tags: - Messages summary: Upload Message - description: 'This method allows to upload either an RFC822 formatted message or a message structure to a mailbox. Raw message is stored unmodified, no headers are added or removed. If you want to generate the uploaded message from strucutred data fields, then do not use the raw property.' + description: 'This method allows to upload either an RFC822 formatted message or a message structure to a mailbox. Raw message is stored unmodified, no headers are added or removed. If you want to generate the uploaded message from structured data fields, then do not use the raw property.' operationId: uploadMessage requestBody: content: diff --git a/lib/api/addresses.js b/lib/api/addresses.js index f7c27031..ee7be053 100644 --- a/lib/api/addresses.js +++ b/lib/api/addresses.js @@ -7,6 +7,7 @@ const ObjectID = require('mongodb').ObjectID; const tools = require('../tools'); const consts = require('../consts'); const roles = require('../roles'); +const libmime = require('libmime'); const { nextPageCursorSchema, previousPageCursorSchema, pageNrSchema, sessSchema, sessIPSchema, booleanSchema, metaDataSchema } = require('../schemas'); const log = require('npmlog'); const isemail = require('isemail'); @@ -1199,11 +1200,22 @@ module.exports = (db, server, userHandler) => { res.json({ success: true, - results: addresses.map(addressData => ({ - id: addressData._id.toString(), - name: addressData.name || false, - address: addressData.address - })) + results: addresses.map(addressData => { + let name = addressData.name || false; + try { + // try to decode + if (name) { + name = libmime.decodeWords(name); + } + } catch (E) { + // ignore + } + return { + id: addressData._id.toString(), + name: addressData.name || false, + address: addressData.address + }; + }) }); return next(); diff --git a/lib/api/messages.js b/lib/api/messages.js index 459c0fed..302036a8 100644 --- a/lib/api/messages.js +++ b/lib/api/messages.js @@ -1805,7 +1805,11 @@ module.exports = (db, server, messageHandler, userHandler, storageHandler) => { let envelope = compiled.getEnvelope(); let envelopeFrom = envelope.from; - envelope.from = data.from.address = await validateFromAddress(userData, envelopeFrom); + + if (result.value.draft) { + // override From addresses for drafts + envelope.from = data.from.address = await validateFromAddress(userData, envelopeFrom); + } if (!result.value.to && !envelope.to.length && referencedMessage && ['reply', 'replyAll'].includes(result.value.reference.action)) { envelope.to = envelope.to.concat(parseAddresses(referencedMessage.replyTo || [])).concat(parseAddresses(referencedMessage.replyCc || [])); diff --git a/lib/message-handler.js b/lib/message-handler.js index 7023d59c..b30b18fa 100644 --- a/lib/message-handler.js +++ b/lib/message-handler.js @@ -150,6 +150,12 @@ class MessageHandler { let updates = { updated: new Date() }; if (addr.name) { updates.name = addr.name; + try { + // try to decode + updates.name = libmime.decodeWords(updates.name); + } catch (E) { + // ignore + } } await this.database.collection('addressregister').findOneAndUpdate( @@ -514,6 +520,7 @@ class MessageHandler { } let parsed = messageData.mimeTree && messageData.mimeTree.parsedHeader; + if (parsed) { let keyList = mailboxData.specialUse === '\\Sent' ? ['to', 'cc', 'bcc'] : ['from']; for (let key of keyList) { diff --git a/package.json b/package.json index 093f5691..471e88b5 100644 --- a/package.json +++ b/package.json @@ -16,20 +16,20 @@ "author": "Andris Reinman", "license": "EUPL-1.2", "devDependencies": { - "ajv": "7.2.3", + "ajv": "8.1.0", "chai": "4.3.4", "docsify-cli": "4.4.3", - "eslint": "7.22.0", + "eslint": "7.24.0", "eslint-config-nodemailer": "1.2.0", - "eslint-config-prettier": "8.1.0", + "eslint-config-prettier": "8.2.0", "grunt": "1.3.0", - "grunt-cli": "1.4.1", + "grunt-cli": "1.4.2", "grunt-eslint": "23.0.0", "grunt-mocha-test": "0.13.3", "grunt-shell-spawn": "0.4.0", "grunt-wait": "0.3.0", "imapflow": "1.0.56", - "mailparser": "3.1.0", + "mailparser": "3.2.0", "mocha": "8.3.2", "request": "2.88.2", "supertest": "6.1.3" @@ -37,7 +37,7 @@ "dependencies": { "@phc/pbkdf2": "1.1.14", "accesscontrol": "2.2.1", - "argon2-browser": "1.15.3", + "argon2-browser": "1.15.4", "axios": "0.21.1", "base32.js": "0.1.0", "bcryptjs": "2.4.3", @@ -49,10 +49,10 @@ "humanname": "0.2.2", "iconv-lite": "0.6.2", "ioredfour": "1.0.2-ioredis-03", - "ioredis": "4.24.4", + "ioredis": "4.26.0", "isemail": "3.2.0", "joi": "17.4.0", - "js-yaml": "4.0.0", + "js-yaml": "4.1.0", "key-fingerprint": "1.1.0", "libbase64": "1.2.1", "libmime": "5.0.0", @@ -60,7 +60,7 @@ "mailsplit": "5.0.1", "mobileconfig": "2.3.1", "mongo-cursor-pagination": "7.4.0", - "mongodb": "3.6.5", + "mongodb": "3.6.6", "mongodb-extended-json": "1.11.0", "node-forge": "0.10.0", "nodemailer": "6.5.0", diff --git a/test/api-test.js b/test/api-test.js index fd5e6a94..3f4908d1 100644 --- a/test/api-test.js +++ b/test/api-test.js @@ -466,9 +466,15 @@ describe('API tests', function () { it('should POST /users/:user/mailboxes/:mailbox/messages with text and html', async () => { const message = { from: { - name: 'test tester', - address: 'testuser@example.com' + name: 'test töster', + address: 'bestöser@öxample.com' }, + to: [ + { + name: 'best böster', + address: 'bestöser2@öxample.com' + } + ], subject: 'hello world', text: 'Hello hello world!', html: '

Hello hello world!

' @@ -559,5 +565,10 @@ describe('API tests', function () { const deleteResponse = await server.delete(`/users/${userId}/outbound/${submitResponse.body.queueId}`).expect(200); expect(deleteResponse.body.deleted).to.equal(2); }); + + it('should GET /users/:user/addressregister', async () => { + const response = await server.get(`/users/${userId}/addressregister?query=best`); + expect(response.body.results[0].name).to.equal('test töster'); + }); }); });