mirror of
https://github.com/nodemailer/wildduck.git
synced 2025-02-25 16:34:36 +08:00
allow to use predefined asp passwords
This commit is contained in:
parent
f633e3a89d
commit
d95f4fe4cd
4 changed files with 55 additions and 6 deletions
|
@ -5003,6 +5003,9 @@ components:
|
||||||
address:
|
address:
|
||||||
type: string
|
type: string
|
||||||
description: E-mail address to be used as the account address in mobileconfig file. Must be one of the listed identity addresses of the user. Defaults to the main address of the user
|
description: E-mail address to be used as the account address in mobileconfig file. Must be one of the listed identity addresses of the user. Defaults to the main address of the user
|
||||||
|
password:
|
||||||
|
type: string
|
||||||
|
description: Optional pregenerated password. Must be 16 characters, latin letters only.
|
||||||
ttl:
|
ttl:
|
||||||
type: number
|
type: number
|
||||||
description: 'TTL in seconds for this password. Every time password is used, TTL is reset to this value'
|
description: 'TTL in seconds for this password. Every time password is used, TTL is reset to this value'
|
||||||
|
|
|
@ -230,6 +230,9 @@ module.exports = (db, server, userHandler) => {
|
||||||
)
|
)
|
||||||
.unique(),
|
.unique(),
|
||||||
address: Joi.string().empty('').email({ tlds: false }),
|
address: Joi.string().empty('').email({ tlds: false }),
|
||||||
|
password: Joi.string()
|
||||||
|
.empty('')
|
||||||
|
.pattern(/^[a-z]{16}$/, { name: 'password' }),
|
||||||
generateMobileconfig: booleanSchema.default(false),
|
generateMobileconfig: booleanSchema.default(false),
|
||||||
ttl: Joi.number().empty([0, '']),
|
ttl: Joi.number().empty([0, '']),
|
||||||
sess: sessSchema,
|
sess: sessSchema,
|
||||||
|
|
|
@ -1088,12 +1088,14 @@ class UserHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
async generateASP(user, data) {
|
async generateASP(user, data) {
|
||||||
let password = generatePassword.generate({
|
let password =
|
||||||
length: 16,
|
data.password ||
|
||||||
uppercase: false,
|
generatePassword.generate({
|
||||||
numbers: false,
|
length: 16,
|
||||||
symbols: false
|
uppercase: false,
|
||||||
});
|
numbers: false,
|
||||||
|
symbols: false
|
||||||
|
});
|
||||||
// We need a quick hash key that can be used to identify the password.
|
// We need a quick hash key that can be used to identify the password.
|
||||||
// Otherwise, when authenticating, we'd need to check the password against all stored bcrypt
|
// Otherwise, when authenticating, we'd need to check the password against all stored bcrypt
|
||||||
// hashes which would make forever if the user has a longer list of application specific passwords
|
// hashes which would make forever if the user has a longer list of application specific passwords
|
||||||
|
|
|
@ -151,6 +151,35 @@ describe('API tests', function () {
|
||||||
asp = response.body.password;
|
asp = response.body.password;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should POST /users/:user/asps to generate ASP with custom password', async () => {
|
||||||
|
const response = await server
|
||||||
|
.post(`/users/${userId}/asps`)
|
||||||
|
.send({
|
||||||
|
description: 'test',
|
||||||
|
scopes: ['imap', 'smtp'],
|
||||||
|
generateMobileconfig: true,
|
||||||
|
password: 'a'.repeat(16)
|
||||||
|
})
|
||||||
|
.expect(200);
|
||||||
|
expect(response.body.error).to.not.exist;
|
||||||
|
expect(response.body.success).to.be.true;
|
||||||
|
expect(response.body.password).to.equal('a'.repeat(16));
|
||||||
|
expect(response.body.mobileconfig).to.exist;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail POST /users/:user/asps to generate ASP with custom password', async () => {
|
||||||
|
const response = await server
|
||||||
|
.post(`/users/${userId}/asps`)
|
||||||
|
.send({
|
||||||
|
description: 'test',
|
||||||
|
scopes: ['imap', 'smtp'],
|
||||||
|
generateMobileconfig: true,
|
||||||
|
password: '0'.repeat(16)
|
||||||
|
})
|
||||||
|
.expect(400);
|
||||||
|
expect(response.body.error).to.exist;
|
||||||
|
});
|
||||||
|
|
||||||
it('should POST /authenticate using ASP and allowed scope', async () => {
|
it('should POST /authenticate using ASP and allowed scope', async () => {
|
||||||
const response = await server
|
const response = await server
|
||||||
.post(`/authenticate`)
|
.post(`/authenticate`)
|
||||||
|
@ -163,6 +192,18 @@ describe('API tests', function () {
|
||||||
expect(response.body.success).to.be.true;
|
expect(response.body.success).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should POST /authenticate using ASP and allowed scope with custom password', async () => {
|
||||||
|
const response = await server
|
||||||
|
.post(`/authenticate`)
|
||||||
|
.send({
|
||||||
|
username: 'testuser@jõgeva.öö',
|
||||||
|
password: 'a'.repeat(16),
|
||||||
|
scope: 'imap'
|
||||||
|
})
|
||||||
|
.expect(200);
|
||||||
|
expect(response.body.success).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
it('should POST /authenticate with failure using ASP and master scope', async () => {
|
it('should POST /authenticate with failure using ASP and master scope', async () => {
|
||||||
const response = await server
|
const response = await server
|
||||||
.post(`/authenticate`)
|
.post(`/authenticate`)
|
||||||
|
|
Loading…
Reference in a new issue