mirror of
https://github.com/nodemailer/wildduck.git
synced 2025-09-04 20:25:28 +08:00
Backported API tests from the Hapi branch
This commit is contained in:
parent
7932b3ee79
commit
6045004dc5
11 changed files with 890 additions and 30 deletions
|
@ -148,6 +148,7 @@ module.exports = (db, server, userHandler, settingsHandler) => {
|
|||
name: true,
|
||||
user: true,
|
||||
tags: true,
|
||||
tagsview: true,
|
||||
targets: true,
|
||||
forwardedDisabled: true
|
||||
}
|
||||
|
@ -437,7 +438,7 @@ module.exports = (db, server, userHandler, settingsHandler) => {
|
|||
|
||||
if (result.value.tags) {
|
||||
addressData.tags = result.value.tags;
|
||||
addressData.tagsview = result.value.tags;
|
||||
addressData.tagsview = result.value.tags.map(tag => tag.toLowerCase());
|
||||
}
|
||||
|
||||
if (result.value.metaData) {
|
||||
|
@ -1073,8 +1074,10 @@ module.exports = (db, server, userHandler, settingsHandler) => {
|
|||
}
|
||||
|
||||
if (addressData.address === userData.address) {
|
||||
res.status(400);
|
||||
res.json({
|
||||
error: 'Trying to delete main address. Set a new main address first'
|
||||
error: 'Can not delete main address',
|
||||
code: 'NotPermitted'
|
||||
});
|
||||
return next();
|
||||
}
|
||||
|
@ -1509,7 +1512,7 @@ module.exports = (db, server, userHandler, settingsHandler) => {
|
|||
|
||||
if (result.value.tags) {
|
||||
addressData.tags = result.value.tags;
|
||||
addressData.tagsview = result.value.tags;
|
||||
addressData.tagsview = result.value.tags.map(tag => tag.toLowerCase());
|
||||
}
|
||||
|
||||
if (result.value.metaData) {
|
||||
|
|
|
@ -357,7 +357,7 @@ module.exports = (db, server) => {
|
|||
// permissions check
|
||||
req.validate(roles.can(req.role).readAny('certs'));
|
||||
|
||||
let cert = new ObjectId(result.value.certs);
|
||||
let cert = new ObjectId(result.value.cert);
|
||||
|
||||
let response;
|
||||
try {
|
||||
|
|
|
@ -1629,7 +1629,8 @@ async function getKeyInfo(pubKeyArmored) {
|
|||
let ciphertext = await openpgp.encrypt({
|
||||
message: await openpgp.createMessage({ text: 'Hello, World!' }),
|
||||
encryptionKeys: pubKey, // for encryption
|
||||
format: 'armored'
|
||||
format: 'armored',
|
||||
config: { minRSABits: 1024 }
|
||||
});
|
||||
|
||||
if (/^-----BEGIN PGP MESSAGE/.test(ciphertext)) {
|
||||
|
|
|
@ -1767,7 +1767,8 @@ class MessageHandler {
|
|||
ciphertext = await openpgp.encrypt({
|
||||
message: await openpgp.createMessage({ binary: Buffer.concat([Buffer.from(bodyHeaders + '\r\n\r\n'), body]) }),
|
||||
encryptionKeys: pubKey,
|
||||
format: 'armored'
|
||||
format: 'armored',
|
||||
config: { minRSABits: 1024 }
|
||||
});
|
||||
} catch (err) {
|
||||
return false;
|
||||
|
|
|
@ -726,7 +726,7 @@ class UserHandler {
|
|||
throw err;
|
||||
}
|
||||
if (success) {
|
||||
if (userData.validAfter > now) {
|
||||
if (userData.tempPassword.validAfter && userData.tempPassword.validAfter > now) {
|
||||
let err = new Error('Temporary password is not yet activated');
|
||||
err.responseCode = 403;
|
||||
err.code = 'TempPasswordNotYetValid';
|
||||
|
|
47
package.json
47
package.json
|
@ -19,23 +19,23 @@
|
|||
},
|
||||
"license": "EUPL-1.2",
|
||||
"devDependencies": {
|
||||
"ajv": "8.10.0",
|
||||
"ajv": "8.11.0",
|
||||
"chai": "4.3.6",
|
||||
"docsify-cli": "4.4.3",
|
||||
"eslint": "8.10.0",
|
||||
"docsify-cli": "4.4.4",
|
||||
"eslint": "8.15.0",
|
||||
"eslint-config-nodemailer": "1.2.0",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"grunt": "1.4.1",
|
||||
"grunt": "1.5.3",
|
||||
"grunt-cli": "1.4.3",
|
||||
"grunt-eslint": "24.0.0",
|
||||
"grunt-mocha-test": "0.13.3",
|
||||
"grunt-shell-spawn": "0.4.0",
|
||||
"grunt-wait": "0.3.0",
|
||||
"imapflow": "1.0.85",
|
||||
"mailparser": "3.4.0",
|
||||
"mocha": "9.2.1",
|
||||
"imapflow": "1.0.95",
|
||||
"mailparser": "3.5.0",
|
||||
"mocha": "10.0.0",
|
||||
"request": "2.88.2",
|
||||
"supertest": "6.2.2"
|
||||
"supertest": "6.2.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fidm/x509": "1.2.1",
|
||||
|
@ -44,36 +44,36 @@
|
|||
"@root/csr": "0.8.1",
|
||||
"accesscontrol": "2.2.1",
|
||||
"argon2-browser": "1.18.0",
|
||||
"axios": "0.26.0",
|
||||
"axios": "0.27.2",
|
||||
"base32.js": "0.1.0",
|
||||
"bcryptjs": "2.4.3",
|
||||
"bull": "3.29.3",
|
||||
"fido2-lib": "^2.8.1",
|
||||
"fido2-lib": "3.1.4",
|
||||
"gelf": "2.0.1",
|
||||
"generate-password": "1.7.0",
|
||||
"he": "1.2.0",
|
||||
"html-to-text": "8.1.0",
|
||||
"html-to-text": "8.2.0",
|
||||
"humanname": "0.2.2",
|
||||
"iconv-lite": "0.6.3",
|
||||
"ioredfour": "1.2.0-ioredis-06",
|
||||
"ioredis": "4.28.5",
|
||||
"ioredis": "5.0.4",
|
||||
"ipaddr.js": "2.0.1",
|
||||
"isemail": "3.2.0",
|
||||
"joi": "17.6.0",
|
||||
"js-yaml": "4.1.0",
|
||||
"key-fingerprint": "1.1.0",
|
||||
"libbase64": "1.2.1",
|
||||
"libmime": "5.0.0",
|
||||
"libmime": "5.1.0",
|
||||
"libqp": "1.1.0",
|
||||
"mailsplit": "5.3.1",
|
||||
"mailsplit": "5.3.2",
|
||||
"mobileconfig": "2.4.0",
|
||||
"mongo-cursor-pagination": "7.6.1",
|
||||
"mongodb": "4.4.1",
|
||||
"mongodb": "4.6.0",
|
||||
"mongodb-extended-json": "1.11.1",
|
||||
"node-forge": "1.2.1",
|
||||
"nodemailer": "6.7.2",
|
||||
"npmlog": "6.0.1",
|
||||
"openpgp": "5.2.0",
|
||||
"node-forge": "1.3.1",
|
||||
"nodemailer": "6.7.5",
|
||||
"npmlog": "6.0.2",
|
||||
"openpgp": "5.2.1",
|
||||
"pem-jwk": "2.0.0",
|
||||
"punycode": "2.1.1",
|
||||
"pwnedpasswords": "1.0.6",
|
||||
|
@ -83,18 +83,19 @@
|
|||
"restify-logger": "2.0.1",
|
||||
"saslprep": "1.0.3",
|
||||
"seq-index": "1.1.0",
|
||||
"smtp-server": "3.10.0",
|
||||
"smtp-server": "3.11.0",
|
||||
"speakeasy": "2.0.0",
|
||||
"unixcrypt": "1.0.13",
|
||||
"unix-crypt-td-js": "1.1.4",
|
||||
"unixcrypt": "1.1.0",
|
||||
"uuid": "8.3.2",
|
||||
"wild-config": "1.6.0",
|
||||
"yargs": "17.3.1"
|
||||
"yargs": "17.5.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/wildduck-email/wildduck.git"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
"node": ">=12.0.0 <17"
|
||||
}
|
||||
}
|
||||
|
|
214
test/api/addresses-test.js
Normal file
214
test/api/addresses-test.js
Normal file
|
@ -0,0 +1,214 @@
|
|||
/*eslint no-unused-expressions: 0, prefer-arrow-callback: 0, no-console:0 */
|
||||
|
||||
/* globals before: false, after: false */
|
||||
|
||||
'use strict';
|
||||
|
||||
const supertest = require('supertest');
|
||||
const chai = require('chai');
|
||||
|
||||
const expect = chai.expect;
|
||||
chai.config.includeStack = true;
|
||||
|
||||
const server = supertest.agent('http://localhost:8080');
|
||||
|
||||
describe('API Users', function () {
|
||||
this.timeout(10000); // eslint-disable-line no-invalid-this
|
||||
|
||||
let user, user2, forwarded;
|
||||
|
||||
before(async () => {
|
||||
// ensure that we have an existing user account
|
||||
const response = await server
|
||||
.post('/users')
|
||||
.send({
|
||||
username: 'addressuser',
|
||||
password: 'secretvalue',
|
||||
address: 'addressuser.addrtest@example.com',
|
||||
name: 'address user'
|
||||
})
|
||||
.expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(response.body.id).to.exist;
|
||||
|
||||
user = response.body.id;
|
||||
|
||||
const response2 = await server
|
||||
.post('/users')
|
||||
.send({
|
||||
username: 'addressuser2',
|
||||
password: 'secretvalue',
|
||||
address: 'addressuser2.addrtest@example.com',
|
||||
name: 'address user 2'
|
||||
})
|
||||
.expect(200);
|
||||
expect(response2.body.success).to.be.true;
|
||||
expect(response2.body.id).to.exist;
|
||||
|
||||
user2 = response2.body.id;
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await server.delete(`/users/${user}`).expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
|
||||
user = false;
|
||||
});
|
||||
|
||||
it('should POST /users/{user}/addresses', async () => {
|
||||
const response = await server
|
||||
.post(`/users/${user}/addresses`)
|
||||
.send({
|
||||
address: `user1.1.addrtest@example.com`,
|
||||
tags: ['TAG1', 'tag2']
|
||||
})
|
||||
.expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
|
||||
const response2 = await server
|
||||
.post(`/users/${user2}/addresses`)
|
||||
.send({
|
||||
address: `user2.1.addrtest@example.com`
|
||||
})
|
||||
.expect(200);
|
||||
expect(response2.body.success).to.be.true;
|
||||
|
||||
const response3 = await server
|
||||
.post(`/users/${user}/addresses`)
|
||||
.send({
|
||||
address: `user1.2.addrtest@example.com`,
|
||||
tags: ['TAG2', 'tag3']
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(response3.body.success).to.be.true;
|
||||
});
|
||||
|
||||
it('should GET /addresses', async () => {
|
||||
const addressListResponse = await server.get(`/addresses`).expect(200);
|
||||
expect(addressListResponse.body.success).to.be.true;
|
||||
expect(addressListResponse.body.total).to.gt(3);
|
||||
});
|
||||
|
||||
it('should GET /addresses with tags', async () => {
|
||||
const addressListResponse = await server.get(`/addresses?tags=tag2,tag3`).expect(200);
|
||||
expect(addressListResponse.body.success).to.be.true;
|
||||
expect(addressListResponse.body.total).to.equal(2);
|
||||
});
|
||||
|
||||
it('should GET /addresses with required tags', async () => {
|
||||
const addressListResponse = await server.get(`/addresses?requiredTags=tag2,tag3`).expect(200);
|
||||
expect(addressListResponse.body.success).to.be.true;
|
||||
expect(addressListResponse.body.total).to.equal(1);
|
||||
});
|
||||
|
||||
it('should GET /addresses with a user token', async () => {
|
||||
const authResponse = await server
|
||||
.post('/authenticate')
|
||||
.send({
|
||||
username: 'addressuser',
|
||||
password: 'secretvalue',
|
||||
token: true
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(authResponse.body.success).to.be.true;
|
||||
expect(authResponse.body.token).to.exist;
|
||||
|
||||
let token = authResponse.body.token;
|
||||
|
||||
const userListResponse = await server.get(`/addresses?accessToken=${token}`).expect(200);
|
||||
expect(userListResponse.body.success).to.be.true;
|
||||
|
||||
expect(userListResponse.body.total).to.equal(3);
|
||||
});
|
||||
|
||||
it('should GET /users/{user}/addresses', async () => {
|
||||
const addressListResponse = await server.get(`/users/${user}/addresses`).expect(200);
|
||||
expect(addressListResponse.body.success).to.be.true;
|
||||
|
||||
expect(addressListResponse.body.results.length).to.equal(3);
|
||||
expect(addressListResponse.body.results.filter(addr => addr.main).length).to.equal(1);
|
||||
expect(addressListResponse.body.results.find(addr => addr.main).address).to.equal('addressuser.addrtest@example.com');
|
||||
});
|
||||
|
||||
it('should PUT /users/{user}/addresses/{address}', async () => {
|
||||
let addressListResponse = await server.get(`/users/${user}/addresses`).expect(200);
|
||||
expect(addressListResponse.body.success).to.be.true;
|
||||
let addresses = addressListResponse.body.results;
|
||||
let address = addresses.find(addr => addr.address === 'user1.1.addrtest@example.com').id;
|
||||
|
||||
const response = await server
|
||||
.put(`/users/${user}/addresses/${address}`)
|
||||
.send({
|
||||
main: true
|
||||
})
|
||||
.expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
|
||||
addressListResponse = await server.get(`/users/${user}/addresses`).expect(200);
|
||||
expect(addressListResponse.body.success).to.be.true;
|
||||
|
||||
expect(addressListResponse.body.results.length).to.equal(3);
|
||||
expect(addressListResponse.body.results.filter(addr => addr.main).length).to.equal(1);
|
||||
expect(addressListResponse.body.results.find(addr => addr.main).address).to.equal('user1.1.addrtest@example.com');
|
||||
});
|
||||
|
||||
it('should DELETE /users/{user}/addresses/{address} and fail', async () => {
|
||||
let addressListResponse = await server.get(`/users/${user}/addresses`).expect(200);
|
||||
expect(addressListResponse.body.success).to.be.true;
|
||||
let addresses = addressListResponse.body.results;
|
||||
let address = addresses.find(addr => addr.main).id;
|
||||
|
||||
// trying to delete a main address should fail
|
||||
const response = await server.delete(`/users/${user}/addresses/${address}`).expect(400);
|
||||
expect(response.body.code).to.equal('NotPermitted');
|
||||
});
|
||||
|
||||
it('should DELETE /users/{user}/addresses/{address}', async () => {
|
||||
let addressListResponse = await server.get(`/users/${user}/addresses`).expect(200);
|
||||
expect(addressListResponse.body.success).to.be.true;
|
||||
let addresses = addressListResponse.body.results;
|
||||
let address = addresses.find(addr => addr.address === 'user1.2.addrtest@example.com').id;
|
||||
|
||||
const response = await server.delete(`/users/${user}/addresses/${address}`).expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
});
|
||||
|
||||
it('should POST /addresses/forwarded', async () => {
|
||||
const response = await server
|
||||
.post(`/addresses/forwarded`)
|
||||
.send({
|
||||
address: `forwarded.1.addrtest@example.com`,
|
||||
targets: ['andris@ethereal.email'],
|
||||
tags: ['TAG1', 'tag2']
|
||||
})
|
||||
.expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
forwarded = response.body.id;
|
||||
});
|
||||
|
||||
it('should GET /addresses with query', async () => {
|
||||
const addressListResponse = await server.get(`/addresses?query=forwarded.1.addrtest`).expect(200);
|
||||
expect(addressListResponse.body.success).to.be.true;
|
||||
expect(addressListResponse.body.total).to.equal(1);
|
||||
expect(forwarded).to.exist;
|
||||
});
|
||||
|
||||
it('should PUT /addresses/forwarded/{address}', async () => {
|
||||
const response = await server
|
||||
.put(`/addresses/forwarded/${forwarded}`)
|
||||
.send({
|
||||
tags: ['tAG2', 'tAg3']
|
||||
})
|
||||
.expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
|
||||
const addressListResponse = await server.get(`/addresses?query=forwarded.1.addrtest`).expect(200);
|
||||
expect(addressListResponse.body.total).to.equal(1);
|
||||
});
|
||||
});
|
111
test/api/certs-test.js
Normal file
111
test/api/certs-test.js
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*eslint no-unused-expressions: 0, prefer-arrow-callback: 0, no-console:0 */
|
||||
|
||||
'use strict';
|
||||
|
||||
const supertest = require('supertest');
|
||||
const chai = require('chai');
|
||||
|
||||
const expect = chai.expect;
|
||||
chai.config.includeStack = true;
|
||||
|
||||
const server = supertest.agent('http://localhost:8080');
|
||||
|
||||
describe('API Certs', function () {
|
||||
let cert;
|
||||
|
||||
this.timeout(10000); // eslint-disable-line no-invalid-this
|
||||
|
||||
it('should POST /certs', async () => {
|
||||
const response = await server
|
||||
.post('/certs')
|
||||
.send({
|
||||
servername: 'example.com',
|
||||
privateKey: `-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDUwsIjU4ItLme5
|
||||
8bhvsdU3ifpYxCA0sz1GaDnUIeH62JW1XLR5dM9yh1vNCZNeMnZ2YASA7dh1+SNT
|
||||
J8O46OWaIaDMt3PqBeYs8seuJDiHc1kZtsXWaoKQpeA0LkQsDMTpHm/m2j4lpMeI
|
||||
+c0GjEcYYYupnbJPxfMW9Xzxmer7p1SduKl5g9x0Izicv6ZvuBnQSpaYQUruqIXU
|
||||
CdK7RAVUinNU2Bjik/bg773CXvCgEf4QpJQdOMaGB45MWs61x3yv+qoIE7oSE36/
|
||||
RsstJC9NbnavFhheitvc8rPJchq7LWMdADD/C/OdYXM3j9AyVdAbCMYpgcOLNdmG
|
||||
+mGZUKexAgMBAAECggEBAMsH/9NOQY90FS/wZ5zPCzUwymIi5sjjsrmZhHXWz5td
|
||||
S6ACk4bD3aLhYM1NMgBWD43vGt0eG86YrQkRjUjLly96n8Q73LWaY4jJNZwMnJVF
|
||||
keVj8W8nvOjkIgwpioyussnzbb3SzjOGB5PDLc/t1XqCu5BlGF/f+pYSNeUoiIET
|
||||
8xCMLQ7yWyTA7b8mL3Lx+ZJsW4nbugK7FwOnRktK+RQlAPiJsLCzFL+9AZPRrMom
|
||||
Tq0z5F7iYGet5vdc/3IiEDG0sH7H51Gtjbc0sLT901Faw+fw2Ca9C6tuR30SFuNY
|
||||
8SPt4ETViVdueSjuAzCnDAqjeHm7H9lWb8GGjXBfjHECgYEA92lxgXb6xwNSQ9Rx
|
||||
1bCjlpoLNPvbxUYiKBeCNGUor5i1aLWd8hbF6nMCx6/2AzOFCzK1WxKEFfreY3bG
|
||||
IyiJxxFYCWNoS2+dCM0IbbC4oY1VQzbagv3V8gGCh8to47dUDBV8nNE8Iqi03Hpk
|
||||
WDVqk3jnzUQ77IYTcPjHCm+uw2sCgYEA3CVlxKiyRV6f/TboSfio8+jCm2Z/eYP1
|
||||
UoaWBOwdpFzsOMn74MXtfwQhDm6tf0vjnEDFWWrS0d8lxGV4rSCMJT0o+sgZrs/2
|
||||
D+MSZxLyqq+NewsqaEU6Hl13/Ic09xIP2Gz8Fk36ddl6f/MO9j/pAdhxF21jNSIW
|
||||
/dlxnPvU5FMCgYEAt5TpIUyctlEzmJspwIsqR5SUHkOIBnCM5bzT43bwYqNocILa
|
||||
6QiW4OloNa3OWP/Ah9eflC1AD2Mv4xP935az7R9keMrnV5pBJoek6meICG/rxU0N
|
||||
hMc/Giyeo45+jQG6fqDu7xmeioUudq7miEFSjIzZS4mHAXFXOauPXaITRnMCgYA5
|
||||
JSwJpJDCGRIGtN4PdZDF38HEfRLSBEMGLRF8LZ50L/rRsvzDGB3SPswl5uz6gkSP
|
||||
JvETiPs4p2gyVvTAXBaFBB9DGfYwvqLs9NCuGOkNDYz4R6m2b2Hqx/CBiMdi6zlZ
|
||||
wNCfKZa+SLnXxMw5d9WQORMCNc7u1+6H7o3jZiuZKQKBgF92xcje7ROjMas6bLru
|
||||
XzoNjcESSn09LuY0Jmm6eq927QPWvr7HGpvHZJCtsoPhSAqoVVL2f4SlDfxko+NG
|
||||
5RD9W3AE6jSBumZSpGD+3Pm1p/3fRAbrfOcKJai9O9/K3ZQi3aSQgRQgAhAUZ1C4
|
||||
gWkJtB9ZKR6nboyDYCFNjfYw
|
||||
-----END PRIVATE KEY-----
|
||||
`,
|
||||
cert: `-----BEGIN CERTIFICATE-----
|
||||
MIIDADCCAegCCQCPXSqvTzty/zANBgkqhkiG9w0BAQsFADBCMRQwEgYDVQQDDAtl
|
||||
eGFtcGxlLmNvbTEdMBsGA1UECgwUTXkgQ29tcGFueSBOYW1lIExURC4xCzAJBgNV
|
||||
BAYTAlVTMB4XDTIxMTEzMDEzMjUyOFoXDTIyMTEzMDEzMjUyOFowQjEUMBIGA1UE
|
||||
AwwLZXhhbXBsZS5jb20xHTAbBgNVBAoMFE15IENvbXBhbnkgTmFtZSBMVEQuMQsw
|
||||
CQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANTCwiNT
|
||||
gi0uZ7nxuG+x1TeJ+ljEIDSzPUZoOdQh4frYlbVctHl0z3KHW80Jk14ydnZgBIDt
|
||||
2HX5I1Mnw7jo5ZohoMy3c+oF5izyx64kOIdzWRm2xdZqgpCl4DQuRCwMxOkeb+ba
|
||||
PiWkx4j5zQaMRxhhi6mdsk/F8xb1fPGZ6vunVJ24qXmD3HQjOJy/pm+4GdBKlphB
|
||||
Su6ohdQJ0rtEBVSKc1TYGOKT9uDvvcJe8KAR/hCklB04xoYHjkxazrXHfK/6qggT
|
||||
uhITfr9Gyy0kL01udq8WGF6K29zys8lyGrstYx0AMP8L851hczeP0DJV0BsIximB
|
||||
w4s12Yb6YZlQp7ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAxpun+z6fLOW8xlWx
|
||||
ej7XUmaI5emFC6wFSaGh3022ASvqS8TOR9qnY9yN+a1notLyqIiKUvoY4uvjPpk8
|
||||
OAcMa6e7NRjsBQ/Zry3dxC88CCs4oR0SHeKy/4d3VmqUax5Ufn+X1+in+Sb4FDBD
|
||||
rDnBTi9TJnAo8JMQ7FwkBFnMsieelX9IXLSsFE0yhz0U97r9B0JFcUEP0OsY9Tz0
|
||||
NbFXanIpFENKxoXRzAvq0XlE3p446wIiUlIle/PXQpOx8s5Ae0eEmX0/2DY+1MZs
|
||||
nBhCzyAvD7Z2TQjrszlbekiIeqTgN/D+r7WWJ3Urpf2NdfLOGNWTDe9cVgZlR85n
|
||||
rp+tEw==
|
||||
-----END CERTIFICATE-----
|
||||
`,
|
||||
description: 'Some text about this certificate',
|
||||
sess: '12345',
|
||||
ip: '127.0.0.1'
|
||||
})
|
||||
.expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(/^[0-9a-f]{24}$/.test(response.body.id)).to.be.true;
|
||||
expect(response.body.servername).to.equal('example.com');
|
||||
expect(response.body.altNames).to.deep.equal(['example.com']);
|
||||
cert = response.body.id;
|
||||
});
|
||||
|
||||
it('should GET /certs/:cert', async () => {
|
||||
const response = await server.get(`/certs/${cert}`).expect(200);
|
||||
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(response.body.id).to.equal(cert);
|
||||
});
|
||||
|
||||
it('should GET /certs/resolve/:servername', async () => {
|
||||
const response = await server.get(`/certs/resolve/example.com`).expect(200);
|
||||
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(response.body.id).to.equal(cert);
|
||||
});
|
||||
|
||||
it('should GET /certs', async () => {
|
||||
const response = await server.get(`/certs`).expect(200);
|
||||
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(response.body.results.length).to.gte(1);
|
||||
expect(response.body.results.find(entry => entry.id === cert)).to.exist;
|
||||
});
|
||||
|
||||
it('should DELETE /certs/:cert', async () => {
|
||||
const response = await server.delete(`/certs/${cert}`).expect(200);
|
||||
|
||||
expect(response.body.success).to.be.true;
|
||||
});
|
||||
});
|
62
test/api/dkim-test.js
Normal file
62
test/api/dkim-test.js
Normal file
|
@ -0,0 +1,62 @@
|
|||
/*eslint no-unused-expressions: 0, prefer-arrow-callback: 0, no-console:0 */
|
||||
|
||||
'use strict';
|
||||
|
||||
const supertest = require('supertest');
|
||||
const chai = require('chai');
|
||||
|
||||
const expect = chai.expect;
|
||||
chai.config.includeStack = true;
|
||||
|
||||
const server = supertest.agent('http://localhost:8080');
|
||||
|
||||
describe('API DKIM', function () {
|
||||
let dkim;
|
||||
|
||||
this.timeout(10000); // eslint-disable-line no-invalid-this
|
||||
|
||||
it('should POST /dkim', async () => {
|
||||
const response = await server
|
||||
.post('/dkim')
|
||||
.send({
|
||||
domain: 'example.com',
|
||||
selector: 'wildduck',
|
||||
privateKey:
|
||||
'-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDFCPszabID2MLAzzfja3/TboKp4dHUGSkl6hNSly7IRdAhfh6J\nh6vNa+2Y7pyNagX00ukycZ/03O/93X3UxjzX/NpLESo3GwSjp39R4AgdW91nKt7X\nzGoz4ZQELAao+AH1QhJ8vumXFLFc6sS9l7Eu3+cZcAdWij2TCPKrB56tMQIDAQAB\nAoGAAQNfz07e1Hg74CPwpKG74Yly8I6xtoZ+mKxQdx9B5VO+kz2DyK9C6eaBLUUk\n1vFRoIWpH1JIQUkVjtehuwNd8rgPacPZRjSJrGuvwtP/bjzA8m/z/lI0+rfQW7L7\nRfPoi2fl6MJ3KkjNypmVPPNvtJA42aPUDW6SFcXFvSv43gECQQD12RFLlZ5H3W6z\n2ncJXiZha508LoyABkYeb+veCFwicoNEreQrToDgC3GuBRkODsUgRZaVu2sa4tlv\nzO0rwkXRAkEAzSvmAxTvkSf/gMy5mO+sZKeUEtMHibF4LKxw7Men2oADgVTnS38r\nf8uYJteLt3lkfHfV5ezEOERvQutKnMfpYQJBAL7apceUvkyyBWfQWIrIMWl9vpHi\n3SXiOPsWDfjPap8/YNKnYDOSfQ/xMm5S/NFh+/yCqVVSKuKzavOVFiXbapECQQDC\nhWdK7rN/xRNaUz93/2xL9hHOkyNnacoNWOSrqVO8NnicSxoLmyNrw2SbFusRZdde\npuM2XfdffYqbQKd545OhAkBiCm/hUl5+hCJI6xl4wh3aR4h8j/TA6/u4ohPjqYco\nLUPpKBaWeKdwQRbkkpMsVz6lFtpyZlV6V8joGEd8OLMO\n-----END RSA PRIVATE KEY-----',
|
||||
description: 'Some text about this DKIM certificate',
|
||||
sess: '12345',
|
||||
ip: '127.0.0.1'
|
||||
})
|
||||
.expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(/^[0-9a-f]{24}$/.test(response.body.id)).to.be.true;
|
||||
dkim = response.body.id;
|
||||
});
|
||||
|
||||
it('should GET /dkim/:dkim', async () => {
|
||||
const response = await server.get(`/dkim/${dkim}`).expect(200);
|
||||
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(response.body.id).to.equal(dkim);
|
||||
});
|
||||
|
||||
it('should GET /dkim/resolve/:domain', async () => {
|
||||
const response = await server.get(`/dkim/resolve/example.com`).expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(response.body.id).to.equal(dkim);
|
||||
});
|
||||
|
||||
it('should GET /dkim', async () => {
|
||||
const response = await server.get(`/dkim`).expect(200);
|
||||
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(response.body.results.length).to.equal(1);
|
||||
expect(response.body.results.find(entry => entry.id === dkim)).to.exist;
|
||||
});
|
||||
|
||||
it('should DELETE /dkim/:dkim', async () => {
|
||||
const response = await server.delete(`/dkim/${dkim}`).expect(200);
|
||||
|
||||
expect(response.body.success).to.be.true;
|
||||
});
|
||||
});
|
59
test/api/domainaliases-test.js
Normal file
59
test/api/domainaliases-test.js
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*eslint no-unused-expressions: 0, prefer-arrow-callback: 0, no-console:0 */
|
||||
|
||||
'use strict';
|
||||
|
||||
const supertest = require('supertest');
|
||||
const chai = require('chai');
|
||||
|
||||
const expect = chai.expect;
|
||||
chai.config.includeStack = true;
|
||||
|
||||
const server = supertest.agent('http://localhost:8080');
|
||||
|
||||
describe('API DomainAliases', function () {
|
||||
let domainalias;
|
||||
|
||||
this.timeout(10000); // eslint-disable-line no-invalid-this
|
||||
|
||||
it('should POST /domainaliases', async () => {
|
||||
const response = await server
|
||||
.post('/domainaliases')
|
||||
.send({
|
||||
domain: 'example.com',
|
||||
alias: 'alias.example.com',
|
||||
sess: '12345',
|
||||
ip: '127.0.0.1'
|
||||
})
|
||||
.expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(/^[0-9a-f]{24}$/.test(response.body.id)).to.be.true;
|
||||
domainalias = response.body.id;
|
||||
});
|
||||
|
||||
it('should GET /domainaliases/:domainalias', async () => {
|
||||
const response = await server.get(`/domainaliases/${domainalias}`).expect(200);
|
||||
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(response.body.id).to.equal(domainalias);
|
||||
});
|
||||
|
||||
it('should GET /domainaliases/resolve/:domain', async () => {
|
||||
const response = await server.get(`/domainaliases/resolve/alias.example.com`).expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(response.body.id).to.equal(domainalias);
|
||||
});
|
||||
|
||||
it('should GET /domainaliases', async () => {
|
||||
const response = await server.get(`/domainaliases?query=alias.example.com`).expect(200);
|
||||
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(response.body.results.length).to.gte(1);
|
||||
expect(response.body.results.find(entry => entry.id === domainalias)).to.exist;
|
||||
});
|
||||
|
||||
it('should DELETE /domainaliases/:domainalias', async () => {
|
||||
const response = await server.delete(`/domainaliases/${domainalias}`).expect(200);
|
||||
|
||||
expect(response.body.success).to.be.true;
|
||||
});
|
||||
});
|
408
test/api/users-test.js
Normal file
408
test/api/users-test.js
Normal file
|
@ -0,0 +1,408 @@
|
|||
/*eslint no-unused-expressions: 0, prefer-arrow-callback: 0, no-console:0 */
|
||||
|
||||
'use strict';
|
||||
|
||||
const supertest = require('supertest');
|
||||
const chai = require('chai');
|
||||
|
||||
const expect = chai.expect;
|
||||
chai.config.includeStack = true;
|
||||
|
||||
const server = supertest.agent('http://localhost:8080');
|
||||
|
||||
describe('API Users', function () {
|
||||
this.timeout(10000); // eslint-disable-line no-invalid-this
|
||||
|
||||
let user, user2, token;
|
||||
|
||||
it('should POST /users', async () => {
|
||||
const response = await server
|
||||
.post('/users')
|
||||
.send({
|
||||
username: 'myuser2',
|
||||
name: 'John Smith',
|
||||
address: 'john@example.com',
|
||||
password: 'secretvalue',
|
||||
hashedPassword: false,
|
||||
emptyAddress: false,
|
||||
language: 'et',
|
||||
retention: 0,
|
||||
targets: ['user@example.com', 'https://example.com/upload/email'],
|
||||
spamLevel: 50,
|
||||
quota: 1073741824,
|
||||
recipients: 2000,
|
||||
forwards: 2000,
|
||||
requirePasswordChange: false,
|
||||
imapMaxUpload: 5368709120,
|
||||
imapMaxDownload: 21474836480,
|
||||
pop3MaxDownload: 21474836480,
|
||||
pop3MaxMessages: 300,
|
||||
imapMaxConnections: 15,
|
||||
receivedMax: 60,
|
||||
fromWhitelist: ['user@alternative.domain', '*@example.com'],
|
||||
tags: ['status:user', 'account:example.com'],
|
||||
addTagsToAddress: false,
|
||||
uploadSentMessages: false,
|
||||
mailboxes: {
|
||||
sent: 'Saadetud kirjad',
|
||||
trash: 'Prügikast',
|
||||
junk: 'Praht',
|
||||
drafts: 'Mustandid'
|
||||
},
|
||||
disabledScopes: ['imap', 'pop3', 'smtp'],
|
||||
metaData: {
|
||||
accountIcon: 'avatar.png'
|
||||
},
|
||||
internalData: {
|
||||
inTrial: true
|
||||
},
|
||||
pubKey: '-----BEGIN PGP PUBLIC KEY BLOCK-----\nVersion: Keybase OpenPGP v1.0.0\nComment: https://keybase.io/crypto\n\nxo0EYb0PqAEEANJtI/ivwudfCMmxm+a77Fll5YwSzaaI2nqhcp6pMRJ4l0aafsX3\nBcXUQpsyyELelt2xFtwTNygR4RFWVTn4OoXmO5zFtWCSegAwSyUNK7R/GXi2GTKk\nkYtxUwGcNKBkfY7yAn5KsaeuZL1feDXUGt0YHUmBds5i+6ylI+i4tNbRABEBAAHN\nH1dpbGQgRHVjayA8dGVzdEB3aWxkZHVjay5lbWFpbD7CrQQTAQoAFwUCYb0PqAIb\nLwMLCQcDFQoIAh4BAheAAAoJEJVLs8wf5gSCzBoD/3gz32OfJM1D4IrmKVwyLKxC\n1P81kL7E6ICWD2A0JF9EkojsMHl+/zagwoJejBQhmzTNkFmui5zwmdLGforKl303\ntB0l9vCTb5+eDDHOTUatJrvlw76Fz2ZjIhQTqD4xEM7MWx4xwTGY8bC5roIpdZJD\n9+vr81MXxiq9LZJDBXIyzo0EYb0PqAEEAL/uCTOrAncTRC/3cOQz+kLIzF4A9OTe\n6yxdNWWmx+uo9yJxnBv59Xz9qt8OT8Ih7SD/A4kFCuQqlyd0OFVhyd3KTAQ3CEml\nYOgL5jOE11YrEQjr36xPqO646JZuZIorKDf9PoIyipAMG89BlAoAjSXB1oeQADYn\n5fFLFVm1S7pLABEBAAHCwIMEGAEKAA8FAmG9D6gFCQ8JnAACGy4AqAkQlUuzzB/m\nBIKdIAQZAQoABgUCYb0PqAAKCRBhR/oKY9pg/YqnA/0Szmy4q4TnTBby+j57oXtn\nX/7H/xiaqlCd6bA3lbj3cPK4ybn/gnI4ECsfZfmSFG3T5C9EcZU0e9ByzimH6sxi\nOwPgKFWeJzpl5o8toR7m4wQVhv2NZRUukHe+2JH7nITS0gKeIBHMq2TbufcH6do1\n8s2G7XyLSd5Kkljxx7YmNiKoA/9CQ4l2WkARAFByyEJT9BEE4NBO0m0bI8sg0HRK\nGuP3FKcUu0Pz9R8AExEecofh8s4kaxofa2sbrTcK+L0p0hdR/39JWNuTJbxwEU3C\nA0mZKthjzL7seiRTG7Eny5gGenejRp2x0ziyMEaTgkvf44LPi06XiuE6FGnhElOc\nC7JoIc6NBGG9D6gBBADzW30GOysnqYkexL+bY9o+ai1mL+X58GPLilXJ5WXgEEdf\n8Pg/9jlEOzOnWTTgJAQDGHtwm0duKmK7EJGozLEY94QGOzRjAir6tMF2OYDQIDgj\nAoXavPAc5chFABEVUS12hUPPLoW6YgvaIb3AAZbIM8603BLXTaLGbtZ0z7eYxwAR\nAQABwsCDBBgBCgAPBQJhvQ+oBQkPCZwAAhsuAKgJEJVLs8wf5gSCnSAEGQEKAAYF\nAmG9D6gACgkQ58zrS0TNGbAiVAP/UIxYiSdoHDnBW5qB7onEiUVL5ZFk1Xk+NB0z\n7jOm1oAV0RH8I5NRQBtZ+75xar0vPTX122IdkgpaiNT0wy5Kd/2vz4LKVK9apyJI\neaZ+D7dt5Ipu1p0lWtglqL0xtjOSWuwHFwHuiRYg6eyhGN1RylFpuiKi5KykhrBS\nuBL/BHrk6AP/boRA+KIlb6s19KHNt54Kl8n8G4ZApCwZbUc2jzvbP5DZL5rcjlHd\ns4i4XE+uIJxsiX3iJZtVXzhTKuQlaoEljlhPs/TZYUmxeJ3TdV4o7emWiZ4gE8EQ\nhfxV37ew/GoYm6yME3tAZLIXbv2+bj6HZ4eE8bAMmPvpcQ+UwNJXvnk=\n=dR+x\n-----END PGP PUBLIC KEY BLOCK-----',
|
||||
encryptMessages: false,
|
||||
encryptForwarded: false
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(/^[0-9a-f]{24}$/.test(response.body.id)).to.be.true;
|
||||
|
||||
user = response.body.id;
|
||||
});
|
||||
|
||||
it('should POST /authenticate', async () => {
|
||||
const authResponse = await server
|
||||
.post('/authenticate')
|
||||
.send({
|
||||
username: 'myuser2',
|
||||
password: 'secretvalue'
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(authResponse.body.success).to.be.true;
|
||||
expect(authResponse.body).to.deep.equal({
|
||||
success: true,
|
||||
id: user,
|
||||
username: 'myuser2',
|
||||
scope: 'master',
|
||||
require2fa: false,
|
||||
requirePasswordChange: false
|
||||
});
|
||||
});
|
||||
|
||||
it('should POST /authenticate and fail', async () => {
|
||||
const authResponse = await server
|
||||
.post('/authenticate')
|
||||
.send({
|
||||
username: 'myuser2',
|
||||
password: 'invalidpass'
|
||||
})
|
||||
.expect(403);
|
||||
expect(authResponse.body.code).to.equal('AuthFailed');
|
||||
});
|
||||
|
||||
it('should POST /users and fail - invalid username', async () => {
|
||||
const response = await server
|
||||
.post('/users')
|
||||
.send({
|
||||
username: 'ömyuser2',
|
||||
name: 'John Smith',
|
||||
password: 'secretvalue'
|
||||
})
|
||||
.expect(400);
|
||||
|
||||
expect(response.body.details.username).to.exist;
|
||||
});
|
||||
|
||||
it('should POST /authenticate and request a token', async () => {
|
||||
const authResponse = await server
|
||||
.post('/authenticate')
|
||||
.send({
|
||||
username: 'myuser2',
|
||||
password: 'secretvalue',
|
||||
token: true
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(authResponse.body.success).to.be.true;
|
||||
expect(authResponse.body.token).to.exist;
|
||||
|
||||
token = authResponse.body.token;
|
||||
});
|
||||
|
||||
it('should POST /users with hashed password', async () => {
|
||||
const response = await server
|
||||
.post('/users')
|
||||
.send({
|
||||
username: 'myuser2hash',
|
||||
name: 'John Smith',
|
||||
// password: 'test',
|
||||
password: '$argon2i$v=19$m=16,t=2,p=1$SFpGczI1bWV1RVRpYjNYaw$EBE/WnOGeWint3eQ+SQ7Sg',
|
||||
hashedPassword: true
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.success).to.be.true;
|
||||
user2 = response.body.id;
|
||||
|
||||
const authResponse = await server
|
||||
.post('/authenticate')
|
||||
.send({
|
||||
username: 'myuser2hash',
|
||||
password: 'test'
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(authResponse.body.success).to.be.true;
|
||||
expect(authResponse.body).to.deep.equal({
|
||||
success: true,
|
||||
id: user2,
|
||||
username: 'myuser2hash',
|
||||
scope: 'master',
|
||||
require2fa: false,
|
||||
requirePasswordChange: false
|
||||
});
|
||||
});
|
||||
|
||||
it('should GET /users/resolve/{username}', async () => {
|
||||
const response = await server.get('/users/resolve/myuser2').expect(200);
|
||||
|
||||
expect(response.body).to.deep.equal({
|
||||
success: true,
|
||||
id: user
|
||||
});
|
||||
});
|
||||
|
||||
it('should GET /users/resolve/{username} and fail', async () => {
|
||||
const response = await server.get('/users/resolve/myuser2invalid').expect(404);
|
||||
expect(response.body.code).to.equal('UserNotFound');
|
||||
});
|
||||
|
||||
it('should GET /users', async () => {
|
||||
const response = await server.get('/users?query=myuser2').expect(200);
|
||||
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(response.body.results.find(entry => entry.id === user)).to.exist;
|
||||
});
|
||||
|
||||
it('should GET /users/{user}', async () => {
|
||||
let response = await server.get(`/users/${user}`).expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(response.body.id).to.equal(user);
|
||||
});
|
||||
|
||||
it('should GET /users/{user} using a token', async () => {
|
||||
let response = await server.get(`/users/${user}?accessToken=${token}`).expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(response.body.id).to.equal(user);
|
||||
});
|
||||
|
||||
it('should GET /users/me using a token', async () => {
|
||||
let response = await server.get(`/users/me?accessToken=${token}`).expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(response.body.id).to.equal(user);
|
||||
});
|
||||
|
||||
it('should GET /users/{user} using a token and fail against other user', async () => {
|
||||
let response = await server.get(`/users/${user2}?accessToken=${token}`);
|
||||
expect(response.body.code).to.equal('MissingPrivileges');
|
||||
});
|
||||
|
||||
it('should DELETE /authenticate', async () => {
|
||||
let response = await server.delete(`/authenticate?accessToken=${token}`).expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
});
|
||||
|
||||
it('should DELETE /authenticate with false', async () => {
|
||||
// token is not valid anymore
|
||||
await server.delete(`/authenticate?accessToken=${token}`).expect(403);
|
||||
});
|
||||
|
||||
it('should PUT /users/{user}', async () => {
|
||||
const name = 'John Smith 2';
|
||||
|
||||
// update user data
|
||||
const response = await server
|
||||
.put(`/users/${user}`)
|
||||
.send({
|
||||
name
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.success).to.be.true;
|
||||
|
||||
// request and verify
|
||||
let getResponse = await server.get(`/users/${user}`);
|
||||
expect(getResponse.body.success).to.be.true;
|
||||
expect(getResponse.body.id).to.equal(user);
|
||||
expect(getResponse.body.name).to.equal(name);
|
||||
});
|
||||
|
||||
it('should PUT /users/{user} and renew a token', async () => {
|
||||
const authResponse1 = await server
|
||||
.post('/authenticate')
|
||||
.send({
|
||||
username: 'myuser2',
|
||||
password: 'secretvalue',
|
||||
token: true
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(authResponse1.body.success).to.be.true;
|
||||
expect(authResponse1.body.token).to.exist;
|
||||
|
||||
let token1 = authResponse1.body.token;
|
||||
|
||||
const authResponse2 = await server
|
||||
.post('/authenticate')
|
||||
.send({
|
||||
username: 'myuser2',
|
||||
password: 'secretvalue',
|
||||
token: true
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(authResponse2.body.success).to.be.true;
|
||||
expect(authResponse2.body.token).to.exist;
|
||||
|
||||
let token2 = authResponse2.body.token;
|
||||
|
||||
// try out token 1
|
||||
let getResponse1 = await server.get(`/users/me?accessToken=${token1}`).expect(200);
|
||||
expect(getResponse1.body.success).to.be.true;
|
||||
expect(getResponse1.body.id).to.equal(user);
|
||||
|
||||
// try out token 2
|
||||
let getResponse2 = await server.get(`/users/me?accessToken=${token2}`).expect(200);
|
||||
expect(getResponse2.body.success).to.be.true;
|
||||
expect(getResponse2.body.id).to.equal(user);
|
||||
|
||||
// update password using a token
|
||||
const response = await server
|
||||
.put(`/users/me?accessToken=${token1}`)
|
||||
.send({
|
||||
password: 'secretvalue'
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.success).to.be.true;
|
||||
|
||||
// try out token 1, should have been renewed
|
||||
let getResponse3 = await server.get(`/users/me?accessToken=${token1}`).expect(200);
|
||||
expect(getResponse3.body.success).to.be.true;
|
||||
expect(getResponse3.body.id).to.equal(user);
|
||||
|
||||
// try out token 2, should fail as it was not renewed
|
||||
await server.get(`/users/me?accessToken=${token2}`).expect(403);
|
||||
});
|
||||
|
||||
it('should PUT /users/{user}/logout', async () => {
|
||||
// request logout
|
||||
const response = await server.put(`/users/${user}/logout`).send({ reason: 'Just because' }).expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
});
|
||||
|
||||
it('should POST /users/{user}/quota/reset', async () => {
|
||||
const response = await server.post(`/users/${user}/quota/reset`).send({}).expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
|
||||
expect(response.body.storageUsed).to.exist;
|
||||
expect(response.body.previousStorageUsed).to.exist;
|
||||
});
|
||||
|
||||
it('should POST /quota/reset', async () => {
|
||||
const response = await server.post(`/quota/reset`).send({}).expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
expect(response.body.task).to.exist;
|
||||
});
|
||||
|
||||
it('should POST /users/{user}/password/reset', async () => {
|
||||
const response = await server.post(`/users/${user}/password/reset`).send({}).expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
|
||||
expect(response.body.password).to.exist;
|
||||
|
||||
const authResponse = await server
|
||||
.post('/authenticate')
|
||||
.send({
|
||||
username: 'myuser2',
|
||||
password: response.body.password
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(authResponse.body.success).to.be.true;
|
||||
expect(authResponse.body).to.deep.equal({
|
||||
success: true,
|
||||
id: user,
|
||||
username: 'myuser2',
|
||||
scope: 'master',
|
||||
require2fa: false,
|
||||
// using a temporary password requires a password change
|
||||
requirePasswordChange: true
|
||||
});
|
||||
});
|
||||
|
||||
it('should POST /users/{user}/password/reset using a future date', async () => {
|
||||
const response = await server
|
||||
.post(`/users/${user}/password/reset`)
|
||||
.send({
|
||||
validAfter: new Date(Date.now() + 1 * 3600 * 1000).toISOString()
|
||||
})
|
||||
.expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
|
||||
expect(response.body.password).to.exist;
|
||||
|
||||
// password not yet valid
|
||||
await server
|
||||
.post('/authenticate')
|
||||
.send({
|
||||
username: 'myuser2',
|
||||
password: response.body.password
|
||||
})
|
||||
.expect(403);
|
||||
});
|
||||
|
||||
it('should DELETE /users/{user}', async () => {
|
||||
// first set the user password
|
||||
const passwordUpdateResponse = await server
|
||||
.put(`/users/${user}`)
|
||||
.send({
|
||||
password: 'secretvalue',
|
||||
ip: '1.2.3.5'
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(passwordUpdateResponse.body.success).to.be.true;
|
||||
|
||||
// Delete user
|
||||
const response = await server.delete(`/users/${user}?deleteAfter=${encodeURIComponent(new Date(Date.now() + 3600 * 1000).toISOString())}`).expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
|
||||
expect(response.body.addresses.deleted).to.gte(1);
|
||||
expect(response.body.task).to.exist;
|
||||
|
||||
// Try to authenticate, should fail
|
||||
await server
|
||||
.post('/authenticate')
|
||||
.send({
|
||||
username: 'myuser2',
|
||||
password: 'secretvalue'
|
||||
})
|
||||
.expect(403);
|
||||
});
|
||||
|
||||
it('should GET /users/{user}/restore', async () => {
|
||||
const response = await server.get(`/users/${user}/restore`).expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
|
||||
expect(response.body.username).to.equal('myuser2');
|
||||
expect(response.body.recoverableAddresses).to.deep.equal(['john@example.com']);
|
||||
});
|
||||
|
||||
it('should POST /users/{user}/restore', async () => {
|
||||
const response = await server.post(`/users/${user}/restore`).send({}).expect(200);
|
||||
expect(response.body.success).to.be.true;
|
||||
|
||||
expect(response.body.addresses.recovered).to.gte(1);
|
||||
expect(response.body.addresses.main).to.equal('john@example.com');
|
||||
});
|
||||
});
|
Loading…
Add table
Reference in a new issue