mirror of
https://github.com/nodemailer/wildduck.git
synced 2025-03-01 02:15:15 +08:00
Added tests for sending messages to LMTP
This commit is contained in:
parent
34e551497c
commit
b53ae97938
7 changed files with 684 additions and 1 deletions
|
@ -1,6 +1,7 @@
|
|||
# If enabled then Wild Duck exposes a LMTP interface for pushing messages to mail store
|
||||
enabled=true
|
||||
port=2424
|
||||
|
||||
# by default bind to localhost only
|
||||
host="127.0.0.1"
|
||||
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
"grunt-shell-spawn": "^0.3.10",
|
||||
"grunt-wait": "^0.1.0",
|
||||
"icedfrisby": "^1.4.0",
|
||||
"mocha": "^4.0.1"
|
||||
"mailparser": "^2.1.0",
|
||||
"mocha": "^4.0.1",
|
||||
"request": "^2.83.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"addressparser": "1.0.1",
|
||||
|
|
502
test/filtering-test.js
Normal file
502
test/filtering-test.js
Normal file
|
@ -0,0 +1,502 @@
|
|||
/*eslint no-unused-expressions: 0, prefer-arrow-callback: 0, no-console: 0 */
|
||||
/* global before */
|
||||
|
||||
'use strict';
|
||||
|
||||
const crypto = require('crypto');
|
||||
//const util = require('util');
|
||||
const chai = require('chai');
|
||||
const request = require('request');
|
||||
const fs = require('fs');
|
||||
|
||||
//const nodemailer = require('nodemailer');
|
||||
//const imapHandler = require('../lib/handler/imap-handler');
|
||||
//const userHandler = require('../lib/handler/user-handler');
|
||||
const simpleParser = require('mailparser').simpleParser;
|
||||
const nodemailer = require('nodemailer');
|
||||
|
||||
const transporter = nodemailer.createTransport({
|
||||
lmtp: true,
|
||||
host: 'localhost',
|
||||
port: 2424,
|
||||
logger: false,
|
||||
debug: false,
|
||||
tls: {
|
||||
rejectUnauthorized: false
|
||||
}
|
||||
});
|
||||
|
||||
const expect = chai.expect;
|
||||
chai.config.includeStack = true;
|
||||
|
||||
const URL = 'http://localhost:8080';
|
||||
const user2PubKey = fs.readFileSync(__dirname + '/fixtures/user2-public.key', 'utf-8');
|
||||
const user3PubKey = fs.readFileSync(__dirname + '/fixtures/user3-public.key', 'utf-8');
|
||||
|
||||
describe('Send multiple messages', function() {
|
||||
this.timeout(100 * 1000); // eslint-disable-line
|
||||
|
||||
let userIds = [];
|
||||
|
||||
before(done => {
|
||||
request.post(
|
||||
URL + '/users',
|
||||
{
|
||||
json: {
|
||||
username: 'user1',
|
||||
password: 'secretpass',
|
||||
address: 'user1@example.com',
|
||||
name: 'user1'
|
||||
}
|
||||
},
|
||||
(err, meta, response) => {
|
||||
expect(err).to.not.exist;
|
||||
expect(response.success).to.be.true;
|
||||
userIds.push(response.id);
|
||||
request.post(
|
||||
URL + '/users',
|
||||
{
|
||||
json: {
|
||||
username: 'user2',
|
||||
password: 'secretpass',
|
||||
address: 'user2@example.com',
|
||||
name: 'user2',
|
||||
pubKey: user2PubKey,
|
||||
encryptMessages: true
|
||||
}
|
||||
},
|
||||
(err, meta, response) => {
|
||||
expect(err).to.not.exist;
|
||||
expect(response.success).to.be.true;
|
||||
userIds.push(response.id);
|
||||
request.post(
|
||||
URL + '/users',
|
||||
{
|
||||
json: {
|
||||
username: 'user3',
|
||||
password: 'secretpass',
|
||||
address: 'user3@example.com',
|
||||
name: 'user3',
|
||||
pubKey: user3PubKey,
|
||||
encryptMessages: true
|
||||
}
|
||||
},
|
||||
(err, meta, response) => {
|
||||
expect(err).to.not.exist;
|
||||
expect(response.success).to.be.true;
|
||||
userIds.push(response.id);
|
||||
request.post(
|
||||
URL + '/users',
|
||||
{
|
||||
json: {
|
||||
username: 'user4',
|
||||
password: 'secretpass',
|
||||
address: 'user4@example.com',
|
||||
name: 'user4',
|
||||
pubKey: user2PubKey,
|
||||
encryptMessages: false
|
||||
}
|
||||
},
|
||||
(err, meta, response) => {
|
||||
expect(err).to.not.exist;
|
||||
expect(response.success).to.be.true;
|
||||
userIds.push(response.id);
|
||||
request.post(
|
||||
URL + '/users',
|
||||
{
|
||||
json: {
|
||||
username: 'user5',
|
||||
password: 'secretpass',
|
||||
address: 'user5@example.com',
|
||||
name: 'user5'
|
||||
}
|
||||
},
|
||||
(err, meta, response) => {
|
||||
expect(err).to.not.exist;
|
||||
expect(response.success).to.be.true;
|
||||
userIds.push(response.id);
|
||||
done();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('Should have users set', done => {
|
||||
expect(userIds.length).to.equal(5);
|
||||
done();
|
||||
});
|
||||
|
||||
it('Send mail to all users', done => {
|
||||
let recipients = ['user1@example.com', 'user2@example.com', 'user3@example.com', 'user4@example.com', 'user5@example.com'];
|
||||
let subject = 'Test ööö message [' + Date.now() + ']';
|
||||
transporter.sendMail(
|
||||
{
|
||||
envelope: {
|
||||
from: 'andris@kreata.ee',
|
||||
to: recipients
|
||||
},
|
||||
|
||||
headers: {
|
||||
// set to Yes to send this message to Junk folder
|
||||
'x-rspamd-spam': 'No'
|
||||
},
|
||||
|
||||
from: 'Kärbes 🐧 <andris@kreata.ee>',
|
||||
to: recipients.map((rcpt, i) => ({ name: 'User #' + (i + 1), address: rcpt })),
|
||||
subject,
|
||||
text: 'Hello world! Current time is ' + new Date().toString(),
|
||||
html:
|
||||
'<p>Hello world! Current time is <em>' +
|
||||
new Date().toString() +
|
||||
'</em> <img src="cid:note@example.com"/> <img src="http://www.neti.ee/img/neti-logo-2015-1.png"></p>',
|
||||
attachments: [
|
||||
// attachment as plaintext
|
||||
{
|
||||
filename: 'notes.txt',
|
||||
content: 'Some notes about this e-mail',
|
||||
contentType: 'text/plain' // optional, would be detected from the filename
|
||||
},
|
||||
|
||||
// Small Binary Buffer attachment, should be kept with message
|
||||
{
|
||||
filename: 'image.png',
|
||||
content: new Buffer(
|
||||
'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/' +
|
||||
'//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U' +
|
||||
'g9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC',
|
||||
'base64'
|
||||
),
|
||||
|
||||
cid: 'note@example.com' // should be as unique as possible
|
||||
},
|
||||
|
||||
// Large Binary Buffer attachment, should be kept separately
|
||||
{
|
||||
path: __dirname + '/../examples/swan.jpg',
|
||||
filename: 'swän.jpg'
|
||||
}
|
||||
]
|
||||
},
|
||||
(err, info) => {
|
||||
expect(err).to.not.exist;
|
||||
expect(info.accepted).to.deep.equal(['user1@example.com', 'user2@example.com', 'user3@example.com', 'user4@example.com', 'user5@example.com']);
|
||||
|
||||
let getFirstMessage = (userId, callback) => {
|
||||
request(URL + '/users/' + userId + '/mailboxes', { json: true }, (err, meta, response) => {
|
||||
expect(err).to.not.exist;
|
||||
expect(response.success).to.be.true;
|
||||
let inbox = response.results.find(mbox => mbox.path === 'INBOX');
|
||||
request(URL + '/users/' + userId + '/mailboxes/' + inbox.id + '/messages', { json: true }, (err, meta, response) => {
|
||||
expect(err).to.not.exist;
|
||||
expect(response.success).to.be.true;
|
||||
|
||||
let message = response.results[0];
|
||||
expect(message).to.exist;
|
||||
|
||||
request(URL + '/users/' + userId + '/mailboxes/' + inbox.id + '/messages/' + message.id, { json: true }, (err, meta, message) => {
|
||||
expect(err).to.not.exist;
|
||||
|
||||
let processAttachments = next => {
|
||||
let pos = 0;
|
||||
let getAttachments = () => {
|
||||
if (pos >= message.attachments.length) {
|
||||
return next();
|
||||
}
|
||||
let attachment = message.attachments[pos++];
|
||||
request(URL + attachment.url, { encoding: null }, (err, meta, raw) => {
|
||||
expect(err).to.not.exist;
|
||||
attachment.raw = raw;
|
||||
setImmediate(getAttachments);
|
||||
});
|
||||
};
|
||||
setImmediate(getAttachments);
|
||||
};
|
||||
|
||||
processAttachments(() => {
|
||||
request(
|
||||
URL + '/users/' + userId + '/mailboxes/' + inbox.id + '/messages/' + message.id + '/message.eml',
|
||||
(err, meta, raw) => {
|
||||
expect(err).to.not.exist;
|
||||
|
||||
message.raw = raw;
|
||||
|
||||
simpleParser(raw, (err, parsed) => {
|
||||
expect(err).to.not.exist;
|
||||
message.parsed = parsed;
|
||||
callback(null, message);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
let checkNormalUsers = next => {
|
||||
let npos = 0;
|
||||
let nusers = [1, 4, 5];
|
||||
let checkUser = () => {
|
||||
if (npos >= nusers.length) {
|
||||
return next();
|
||||
}
|
||||
let user = nusers[npos++];
|
||||
getFirstMessage(userIds[user - 1], (err, message) => {
|
||||
expect(err).to.not.exist;
|
||||
expect(message.subject).to.equal(subject);
|
||||
expect(message.attachments.length).to.equal(3);
|
||||
expect(message.parsed.attachments.length).to.equal(3);
|
||||
for (let i = 0; i < message.attachments.length; i++) {
|
||||
let hashA = crypto
|
||||
.createHash('md5')
|
||||
.update(message.attachments[i].raw)
|
||||
.digest('hex');
|
||||
let hashB = crypto
|
||||
.createHash('md5')
|
||||
.update(message.parsed.attachments[i].content)
|
||||
.digest('hex');
|
||||
expect(hashA).equal(hashB);
|
||||
}
|
||||
expect(message.parsed.to.value).deep.equal([
|
||||
{ address: 'user1@example.com', name: 'User #1' },
|
||||
{ address: 'user2@example.com', name: 'User #2' },
|
||||
{ address: 'user3@example.com', name: 'User #3' },
|
||||
{ address: 'user4@example.com', name: 'User #4' },
|
||||
{ address: 'user5@example.com', name: 'User #5' }
|
||||
]);
|
||||
expect(message.parsed.headers.get('delivered-to').value[0].address).equal('user' + user + '@example.com');
|
||||
|
||||
setImmediate(checkUser);
|
||||
});
|
||||
};
|
||||
setImmediate(checkUser);
|
||||
};
|
||||
|
||||
let checkEncryptedUsers = next => {
|
||||
let npos = 0;
|
||||
let nusers = [2, 3];
|
||||
let checkUser = () => {
|
||||
if (npos >= nusers.length) {
|
||||
return next();
|
||||
}
|
||||
let user = nusers[npos++];
|
||||
getFirstMessage(userIds[user - 1], (err, message) => {
|
||||
expect(err).to.not.exist;
|
||||
|
||||
expect(message.subject).to.equal(subject);
|
||||
expect(message.parsed.to.value).deep.equal([
|
||||
{ address: 'user1@example.com', name: 'User #1' },
|
||||
{ address: 'user2@example.com', name: 'User #2' },
|
||||
{ address: 'user3@example.com', name: 'User #3' },
|
||||
{ address: 'user4@example.com', name: 'User #4' },
|
||||
{ address: 'user5@example.com', name: 'User #5' }
|
||||
]);
|
||||
expect(message.parsed.headers.get('delivered-to').value[0].address).equal('user' + user + '@example.com');
|
||||
expect(message.parsed.attachments.length).equal(2);
|
||||
expect(message.parsed.attachments[0].contentType).equal('application/pgp-encrypted');
|
||||
expect(message.parsed.attachments[0].content.toString()).equal('Version: 1\r\n');
|
||||
expect(message.parsed.attachments[1].contentType).equal('application/octet-stream');
|
||||
expect(message.parsed.attachments[1].filename).equal('encrypted.asc');
|
||||
expect(message.parsed.attachments[1].size).gte(1000000);
|
||||
setImmediate(checkUser);
|
||||
});
|
||||
};
|
||||
setImmediate(checkUser);
|
||||
};
|
||||
|
||||
checkNormalUsers(() => checkEncryptedUsers(() => done()));
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('Send should send mail to spam', done => {
|
||||
let recipients = ['user1@example.com', 'user2@example.com', 'user3@example.com', 'user4@example.com', 'user5@example.com'];
|
||||
let subject = 'Test ööö message [' + Date.now() + ']';
|
||||
transporter.sendMail(
|
||||
{
|
||||
envelope: {
|
||||
from: 'andris@kreata.ee',
|
||||
to: recipients
|
||||
},
|
||||
|
||||
headers: {
|
||||
// set to Yes to send this message to Junk folder
|
||||
'x-rspamd-spam': 'Yes'
|
||||
},
|
||||
|
||||
from: 'Kärbes 🐧 <andris@kreata.ee>',
|
||||
to: recipients.map((rcpt, i) => ({ name: 'User #' + (i + 1), address: rcpt })),
|
||||
subject,
|
||||
text: 'Hello world! Current time is ' + new Date().toString(),
|
||||
html:
|
||||
'<p>Hello world! Current time is <em>' +
|
||||
new Date().toString() +
|
||||
'</em> <img src="cid:note@example.com"/> <img src="http://www.neti.ee/img/neti-logo-2015-1.png"></p>',
|
||||
attachments: [
|
||||
// attachment as plaintext
|
||||
{
|
||||
filename: 'notes.txt',
|
||||
content: 'Some notes about this e-mail',
|
||||
contentType: 'text/plain' // optional, would be detected from the filename
|
||||
},
|
||||
|
||||
// Small Binary Buffer attachment, should be kept with message
|
||||
{
|
||||
filename: 'image.png',
|
||||
content: new Buffer(
|
||||
'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/' +
|
||||
'//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U' +
|
||||
'g9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC',
|
||||
'base64'
|
||||
),
|
||||
|
||||
cid: 'note@example.com' // should be as unique as possible
|
||||
},
|
||||
|
||||
// Large Binary Buffer attachment, should be kept separately
|
||||
{
|
||||
path: __dirname + '/../examples/swan.jpg',
|
||||
filename: 'swän.jpg'
|
||||
}
|
||||
]
|
||||
},
|
||||
(err, info) => {
|
||||
expect(err).to.not.exist;
|
||||
expect(info.accepted).to.deep.equal(['user1@example.com', 'user2@example.com', 'user3@example.com', 'user4@example.com', 'user5@example.com']);
|
||||
|
||||
let getFirstMessage = (userId, callback) => {
|
||||
request(URL + '/users/' + userId + '/mailboxes', { json: true }, (err, meta, response) => {
|
||||
expect(err).to.not.exist;
|
||||
expect(response.success).to.be.true;
|
||||
|
||||
let inbox = response.results.find(mbox => mbox.specialUse === '\\Junk');
|
||||
request(URL + '/users/' + userId + '/mailboxes/' + inbox.id + '/messages', { json: true }, (err, meta, response) => {
|
||||
expect(err).to.not.exist;
|
||||
expect(response.success).to.be.true;
|
||||
|
||||
let message = response.results[0];
|
||||
expect(message).to.exist;
|
||||
|
||||
request(URL + '/users/' + userId + '/mailboxes/' + inbox.id + '/messages/' + message.id, { json: true }, (err, meta, message) => {
|
||||
expect(err).to.not.exist;
|
||||
|
||||
let processAttachments = next => {
|
||||
let pos = 0;
|
||||
let getAttachments = () => {
|
||||
if (pos >= message.attachments.length) {
|
||||
return next();
|
||||
}
|
||||
let attachment = message.attachments[pos++];
|
||||
request(URL + attachment.url, { encoding: null }, (err, meta, raw) => {
|
||||
expect(err).to.not.exist;
|
||||
attachment.raw = raw;
|
||||
setImmediate(getAttachments);
|
||||
});
|
||||
};
|
||||
setImmediate(getAttachments);
|
||||
};
|
||||
|
||||
processAttachments(() => {
|
||||
request(
|
||||
URL + '/users/' + userId + '/mailboxes/' + inbox.id + '/messages/' + message.id + '/message.eml',
|
||||
(err, meta, raw) => {
|
||||
expect(err).to.not.exist;
|
||||
|
||||
message.raw = raw;
|
||||
|
||||
simpleParser(raw, (err, parsed) => {
|
||||
expect(err).to.not.exist;
|
||||
message.parsed = parsed;
|
||||
callback(null, message);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
let checkNormalUsers = next => {
|
||||
let npos = 0;
|
||||
let nusers = [1, 4, 5];
|
||||
let checkUser = () => {
|
||||
if (npos >= nusers.length) {
|
||||
return next();
|
||||
}
|
||||
let user = nusers[npos++];
|
||||
getFirstMessage(userIds[user - 1], (err, message) => {
|
||||
expect(err).to.not.exist;
|
||||
expect(message.subject).to.equal(subject);
|
||||
expect(message.attachments.length).to.equal(3);
|
||||
expect(message.parsed.attachments.length).to.equal(3);
|
||||
for (let i = 0; i < message.attachments.length; i++) {
|
||||
let hashA = crypto
|
||||
.createHash('md5')
|
||||
.update(message.attachments[i].raw)
|
||||
.digest('hex');
|
||||
let hashB = crypto
|
||||
.createHash('md5')
|
||||
.update(message.parsed.attachments[i].content)
|
||||
.digest('hex');
|
||||
expect(hashA).equal(hashB);
|
||||
}
|
||||
expect(message.parsed.to.value).deep.equal([
|
||||
{ address: 'user1@example.com', name: 'User #1' },
|
||||
{ address: 'user2@example.com', name: 'User #2' },
|
||||
{ address: 'user3@example.com', name: 'User #3' },
|
||||
{ address: 'user4@example.com', name: 'User #4' },
|
||||
{ address: 'user5@example.com', name: 'User #5' }
|
||||
]);
|
||||
expect(message.parsed.headers.get('delivered-to').value[0].address).equal('user' + user + '@example.com');
|
||||
|
||||
setImmediate(checkUser);
|
||||
});
|
||||
};
|
||||
setImmediate(checkUser);
|
||||
};
|
||||
|
||||
let checkEncryptedUsers = next => {
|
||||
let npos = 0;
|
||||
let nusers = [2, 3];
|
||||
let checkUser = () => {
|
||||
if (npos >= nusers.length) {
|
||||
return next();
|
||||
}
|
||||
let user = nusers[npos++];
|
||||
getFirstMessage(userIds[user - 1], (err, message) => {
|
||||
expect(err).to.not.exist;
|
||||
|
||||
expect(message.subject).to.equal(subject);
|
||||
expect(message.parsed.to.value).deep.equal([
|
||||
{ address: 'user1@example.com', name: 'User #1' },
|
||||
{ address: 'user2@example.com', name: 'User #2' },
|
||||
{ address: 'user3@example.com', name: 'User #3' },
|
||||
{ address: 'user4@example.com', name: 'User #4' },
|
||||
{ address: 'user5@example.com', name: 'User #5' }
|
||||
]);
|
||||
expect(message.parsed.headers.get('delivered-to').value[0].address).equal('user' + user + '@example.com');
|
||||
expect(message.parsed.attachments.length).equal(2);
|
||||
expect(message.parsed.attachments[0].contentType).equal('application/pgp-encrypted');
|
||||
expect(message.parsed.attachments[0].content.toString()).equal('Version: 1\r\n');
|
||||
expect(message.parsed.attachments[1].contentType).equal('application/octet-stream');
|
||||
expect(message.parsed.attachments[1].filename).equal('encrypted.asc');
|
||||
expect(message.parsed.attachments[1].size).gte(1000000);
|
||||
setImmediate(checkUser);
|
||||
});
|
||||
};
|
||||
setImmediate(checkUser);
|
||||
};
|
||||
|
||||
checkNormalUsers(() => checkEncryptedUsers(() => done()));
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
58
test/fixtures/user2-private.key
vendored
Normal file
58
test/fixtures/user2-private.key
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Comment: GPGTools - https://gpgtools.org
|
||||
|
||||
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
|
||||
=mnIh
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
31
test/fixtures/user2-public.key
vendored
Normal file
31
test/fixtures/user2-public.key
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Comment: GPGTools - https://gpgtools.org
|
||||
|
||||
mQENBFnoTuIBCADI/rapDP+RIQVyV4bcvPlw5vaLUwQIVYx80aK+hcjbM7fDYq7M
|
||||
YLinidRMKqs8a8uQKLCVNWUT1e68CBr1e65hYlLoqCcI09djaQ48HHF31ts+RSv/
|
||||
sYoJdQPL0zaRRzHWH6MROMRAQSY4lFsTxf/szR5PYYGWu+u/0OhYxkqFhjmUllSD
|
||||
tNE1F46E3RpC3A++kGSCq0kwhDTiePHkf3Pdzw/2xPCQpjJQxSYe5oRX0S7a7YXj
|
||||
PWqbsHyHfOnzv/njkQRTKpLSzgFP7M1YKxBIkqZnCx3hZdSdfnKpKJyByL42+f2X
|
||||
B8p2FBOMVd4alT3YxGlYcb1/HHQSt5l7AfIHABEBAAG0GlVzZXIgMiA8dXNlcjJA
|
||||
ZXhhbXBsZS5jb20+iQFUBBMBCgA+FiEE8I/FYdl9ZWL/l03tHKPFXpk104kFAlno
|
||||
TuICGwMFCQPCZwAFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQHKPFXpk104mC
|
||||
sAgAh7aRBmivj02ZoK4k5ZkAkV6PPTPYGIUbBNsumwF/PQqoi51ZREMbocfxlRAO
|
||||
XXUh+8lsfNYENklZhMhVwpb8IW5XUpHXXy5ZtziVv9KHnW5fJW3U4qxpzqj0HS46
|
||||
VvjtMj7UOEFCbj8zEs0L3M1joJVUjXmX8UXUPMZw3J8vfLRQcC7vdJZFUqaN+4+O
|
||||
q+MWNIvvyB/izOLMavDhBVNF3hhKADtKXjMlwpmNpNHmPFcItPMX8nd366p+iPaW
|
||||
TxrV78afgYDaZmQXToQIMQetThcOj38EU/iIlgNIQ/yJlbG4HY8KYr3IBWX0YggW
|
||||
TJ5xLp04BMwakMrhL1DYaaRhVrkBDQRZ6E7iAQgAwrJrUbqPu2cOfisuFEb0JJFm
|
||||
2Ly4CgTaGusglzo5i3UeVDErfOTNT1CTUEQuJEDed2P6+5Pp7VtH7ps9O00GiIJX
|
||||
B2JWb/Xh3Y+bBQ5PKggi0BiNsPsfwwkw/ELho/lZAv4vap0LO9vLubqFcvbhA+pJ
|
||||
2hmOEkxSp0XrQUXsZfCAqiiOA0Rj3AkTawXsjl2It/e6kV8KXNmgZ4ckzBF8i6gp
|
||||
d0Za5HHsFZnaJ6x3Fa3cV2TCkzAwa3tK+G55eCUQVOMPORtxt/67CZXtVVdNZQmV
|
||||
4lNtyO+XZpP0n/nulAg0xZAcAVXzZFvVAtSalzXxrhYpTsldSCooyUomWNuEwwAR
|
||||
AQABiQE8BBgBCgAmFiEE8I/FYdl9ZWL/l03tHKPFXpk104kFAlnoTuICGwwFCQPC
|
||||
ZwAACgkQHKPFXpk104m/cggAkv+vSSfDkN77p+xPdXjnk7dhdDLm+T+Ye8CcoIik
|
||||
iDxV2E50Mw7WBBZ/cusmpSbEXcFJUTSdx3MoH2ZuiLUQWJTBY8G6vktdzA5ZohPI
|
||||
l8czQ/W4Q5HFiELlykGFFDphqjadmkk8FPJ34UfdaFiwDfjbzNW5yOhO5RS3ogxZ
|
||||
hvJKTX1ASYWqahtazt6HgSfcfdYMwzNzd/a7CQIcUwskDxHPRqHPug1gwIGk05gW
|
||||
mOwn9E06Bs18T8ctubf+3VPVLrv1wQe4Gu/D0K6md8mMSA6HbcNbQ9Tn70OS3TNL
|
||||
wngkXBeL1+lbN4rfrStVzWfVvRdpFBYPtnAn2dG7Q1p3qQ==
|
||||
=kMxV
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
58
test/fixtures/user3-private.key
vendored
Normal file
58
test/fixtures/user3-private.key
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Comment: GPGTools - https://gpgtools.org
|
||||
|
||||
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
|
||||
=MWu4
|
||||
-----END PGP PRIVATE KEY BLOCK-----
|
31
test/fixtures/user3-public.key
vendored
Normal file
31
test/fixtures/user3-public.key
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Comment: GPGTools - https://gpgtools.org
|
||||
|
||||
mQENBFnoT18BCAC60OTvCb8If9FnmhfrRnLOhC1awBVPekAeVpFqBgKjh8RDq8bb
|
||||
39JuRA3UXDr89DJog7OuTzr8B4pIjnRdqTfhVoqGyjXjh5G5199jQ8gpwhr7qFTm
|
||||
PUfJAZxiw/GGG5Zx4b33gvyVaxJFnWyxP4W82nxvrNkwbCnejzHxLZs/sApn1xz3
|
||||
PUmTgdlzC0e6elWu2jWXQgUupYzw2VhnnIo/v0Se2An2ZWT36Q3drkR6XbpCBMJS
|
||||
DJWTbyqsPIR20BiYLNEnKczBorTYP1O2pkw94g852193QIs4n+P9G4ulX1JwmbyV
|
||||
6yZkbig7RjfBjFVByBwJCqq9GQzKSrWMxFQFABEBAAG0GlVzZXIgMyA8dXNlcjNA
|
||||
ZXhhbXBsZS5jb20+iQFUBBMBCgA+FiEEsyqWn3YKjtDW1nzadq7TCKLpcAEFAlno
|
||||
T18CGwMFCQPCZwAFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQdq7TCKLpcAGj
|
||||
QQf/StaNTrH2IbNSPym4eUkr/p0e8iED0w0+gn1Z5YN+FZ8l5vhzrVvqWXL5B9Up
|
||||
xfgKja3ipR89Z95h4IUPjW5xsMkcwd8AZ46axHSyPov872/3xf9RJvEYzPXUUTaB
|
||||
23RVp+xxunZUp4pJSOlrMonVHcPrB2ufB8VKYNaYow6oXbxC7iUzoWYsKN4Oqtve
|
||||
2BYf0JpWXLAo6pVR9X+Dz+r6gaAiEFvxPdJIVsb9JeR2NLLnDXmK1tvTpgp9dKZn
|
||||
WFBxBF1QQWnPxBsMaXkaXkcmKpmiWg+kn5nmDVbOazZJAqyKkkwFVOL4tCIJxDEN
|
||||
PTXXTTsu1KevRKRKfCeC18zrPrkBDQRZ6E9fAQgAzCn7g8lIRlJk5Lrc0sKEueQN
|
||||
Gn3MNxpZ6Xz/wTLc7KfWeTEzO/mKKhfuSGqUBoESYM56AtD6HaKNWIt9EPxWbI5t
|
||||
we1BuOt7Kjic8QNB0gcOxqba76jzpUcVr/z8Y4jShd03ayZm9bTWOTssW76abibv
|
||||
91A3109HRN9QkRCjcEaLDLSTrdBvCg8bgQ1XS7hZSYEZLNoa8myplf5TasuynOtG
|
||||
jkU4NvO62S6FhHW4flWx/dn7wCWqHnKwSjCu4tvDdYC4WXpIwkHxFM5xsS3J5RW3
|
||||
1qzYpHOoLq/z+Nbiqs5hXHwpgdtOtdJ4EF+EuEDQQZuEsEfIAh8FU+4pvyLxFwAR
|
||||
AQABiQE8BBgBCgAmFiEEsyqWn3YKjtDW1nzadq7TCKLpcAEFAlnoT18CGwwFCQPC
|
||||
ZwAACgkQdq7TCKLpcAEb5Af9Hw+GoxL7gt6lZQP717cnwF8ENEQV+ucY4hiM5zcZ
|
||||
TH6ZDAui8u976T2y1tLjV5K7wxR13dIyKEyaUP2DNwXXCKuj1FE/qq6nxElyfYb1
|
||||
QZbaC3pTRM9zz03azO5UKlXrubu7IT2mn7HXhhMxJSLXLylK2b5Z8BjbrCthXKEI
|
||||
+IettPZ4OA1+aQSTYt021fBNeiGK09Ck8OKzunxaRhsuxZ1PrqaRoYz01rV0KYzU
|
||||
jAEP8UJ+oEfzy6jJviZcKua+ghTX6Ptvth6Ga6JwRBudLzw4zrZfq+D4Kvfzvylb
|
||||
dbM2iBdJljBORA0PGgBm/MLzx/slcVZKEN6quSrJuuY51Q==
|
||||
=NKWL
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
Loading…
Reference in a new issue