mirror of
https://github.com/nodemailer/wildduck.git
synced 2024-11-10 09:32:28 +08:00
fix(api-ApplicationPassword): Added all ApplicationPasswords API endpoints to API docs generation ZMS-136 (#645)
* List Application Passwords and Request ASP information endpoints added to API docs generation * fixes. Added Create new Application Password endpoint to API docs generation * Added Delete an Application Password api endpoint to API docs generation
This commit is contained in:
parent
b9e3f94c6f
commit
9f9c55a886
1 changed files with 187 additions and 37 deletions
224
lib/api/asps.js
224
lib/api/asps.js
|
@ -11,20 +11,70 @@ const tools = require('../tools');
|
|||
const roles = require('../roles');
|
||||
const util = require('util');
|
||||
const { sessSchema, sessIPSchema, booleanSchema } = require('../schemas');
|
||||
const { userId } = require('../schemas/request/general-schemas');
|
||||
const { successRes } = require('../schemas/response/general-schemas');
|
||||
|
||||
module.exports = (db, server, userHandler) => {
|
||||
const mobileconfigGetSignedConfig = util.promisify(mobileconfig.getSignedConfig.bind(mobileconfig));
|
||||
|
||||
server.get(
|
||||
'/users/:user/asps',
|
||||
{
|
||||
path: '/users/:user/asps',
|
||||
tags: ['ApplicationPasswords'],
|
||||
summary: 'List Application Passwords',
|
||||
validationObjs: {
|
||||
requestBody: {},
|
||||
queryParams: {
|
||||
showAll: booleanSchema.default(false).description('If not true then skips entries with a TTL set'),
|
||||
sess: sessSchema,
|
||||
ip: sessIPSchema
|
||||
},
|
||||
pathParams: { user: userId },
|
||||
response: {
|
||||
200: {
|
||||
description: 'Success',
|
||||
model: Joi.object({
|
||||
success: successRes,
|
||||
results: Joi.array()
|
||||
.items(
|
||||
Joi.object({
|
||||
id: Joi.string().required().description('ID of the Application Password'),
|
||||
description: Joi.string().required().description('Description'),
|
||||
scopes: Joi.array()
|
||||
.items(
|
||||
Joi.string()
|
||||
.required()
|
||||
.valid(...consts.SCOPES, '*')
|
||||
)
|
||||
.required()
|
||||
.description('Allowed scopes for the Application Password'),
|
||||
lastUse: Joi.object({
|
||||
time: Joi.date().required().description('Datestring of last use or false if password has not been used'),
|
||||
event: Joi.string().required().description('Event ID of the security log for the last authentication')
|
||||
})
|
||||
.required()
|
||||
.$_setFlag('objectName', 'LastUse')
|
||||
.description('Information about last use'),
|
||||
created: Joi.date().required().description('Datestring'),
|
||||
expires: Joi.date().required().description('Application password expires after the given date')
|
||||
}).$_setFlag('objectName', 'GetASPsResult')
|
||||
)
|
||||
.required()
|
||||
.description('Event listing')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
tools.responseWrapper(async (req, res) => {
|
||||
res.charSet('utf-8');
|
||||
|
||||
const schema = Joi.object().keys({
|
||||
user: Joi.string().hex().lowercase().length(24).required(),
|
||||
showAll: booleanSchema.default(false),
|
||||
sess: sessSchema,
|
||||
ip: sessIPSchema
|
||||
const { pathParams, requestBody, queryParams } = req.route.spec.validationObjs;
|
||||
|
||||
const schema = Joi.object({
|
||||
...pathParams,
|
||||
...requestBody,
|
||||
...queryParams
|
||||
});
|
||||
|
||||
const result = schema.validate(req.params, {
|
||||
|
@ -130,15 +180,55 @@ module.exports = (db, server, userHandler) => {
|
|||
);
|
||||
|
||||
server.get(
|
||||
'/users/:user/asps/:asp',
|
||||
{
|
||||
path: '/users/:user/asps/:asp',
|
||||
tags: ['ApplicationPasswords'],
|
||||
summary: 'Request ASP information',
|
||||
validationObjs: {
|
||||
requestBody: {},
|
||||
queryParams: {
|
||||
sess: sessSchema,
|
||||
ip: sessIPSchema
|
||||
},
|
||||
pathParams: { user: userId, asp: Joi.string().hex().lowercase().length(24).required().description('ID of the Application Password') },
|
||||
response: {
|
||||
200: {
|
||||
description: 'Success',
|
||||
model: Joi.object({
|
||||
success: successRes,
|
||||
id: Joi.string().required().description('ID of the Application Password'),
|
||||
description: Joi.string().required().description('Description'),
|
||||
scopes: Joi.array()
|
||||
.items(
|
||||
Joi.string()
|
||||
.valid(...consts.SCOPES, '*')
|
||||
.required()
|
||||
)
|
||||
.required()
|
||||
.description('Allowed scopes for the Application Password'),
|
||||
lastUse: Joi.object({
|
||||
time: Joi.date().required().description('Datestring of last use or false if password has not been used'),
|
||||
event: Joi.string().required().description('Event ID of the security log for the last authentication')
|
||||
})
|
||||
.required()
|
||||
.$_setFlag('objectName', 'LastUse')
|
||||
.description('Information about last use'),
|
||||
created: Joi.date().required().description('Datestring'),
|
||||
expires: Joi.date().required().description('Application password expires after the given date')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
tools.responseWrapper(async (req, res) => {
|
||||
res.charSet('utf-8');
|
||||
|
||||
const schema = Joi.object().keys({
|
||||
user: Joi.string().hex().lowercase().length(24).required(),
|
||||
asp: Joi.string().hex().lowercase().length(24).required(),
|
||||
sess: sessSchema,
|
||||
ip: sessIPSchema
|
||||
const { pathParams, requestBody, queryParams } = req.route.spec.validationObjs;
|
||||
|
||||
const schema = Joi.object({
|
||||
...pathParams,
|
||||
...requestBody,
|
||||
...queryParams
|
||||
});
|
||||
|
||||
const result = schema.validate(req.params, {
|
||||
|
@ -204,28 +294,74 @@ module.exports = (db, server, userHandler) => {
|
|||
);
|
||||
|
||||
server.post(
|
||||
'/users/:user/asps',
|
||||
{
|
||||
path: '/users/:user/asps',
|
||||
tags: ['ApplicationPasswords'],
|
||||
summary: 'Create new Application Password',
|
||||
validationObjs: {
|
||||
requestBody: {
|
||||
description: Joi.string().trim().max(255).required().description('Description for the Application Password entry'),
|
||||
scopes: Joi.array()
|
||||
.items(
|
||||
Joi.string()
|
||||
.valid(...consts.SCOPES, '*')
|
||||
.required()
|
||||
)
|
||||
.unique()
|
||||
.description(
|
||||
'List of scopes this Password applies to. Special scope "*" indicates that this password can be used for any scope except "master"'
|
||||
),
|
||||
address: Joi.string()
|
||||
.empty('')
|
||||
.email({ tlds: false })
|
||||
.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: Joi.string()
|
||||
.empty('')
|
||||
.pattern(/^[a-z]{16}$/, { name: 'password' })
|
||||
.description('Optional pregenerated password. Must be 16 characters, latin letters only.'),
|
||||
generateMobileconfig: booleanSchema
|
||||
.default(false)
|
||||
.description('If true then result contains a mobileconfig formatted file with account config'),
|
||||
ttl: Joi.number().empty([0, '']).description('TTL in seconds for this password. Every time password is used, TTL is reset to this value'),
|
||||
sess: sessSchema,
|
||||
ip: sessIPSchema
|
||||
},
|
||||
queryParams: {},
|
||||
pathParams: { user: userId },
|
||||
response: {
|
||||
200: {
|
||||
description: 'Success',
|
||||
model: Joi.object({
|
||||
success: successRes,
|
||||
id: Joi.string().required().description('ID of the Application Password'),
|
||||
password: Joi.string()
|
||||
.required()
|
||||
.description(
|
||||
'Application Specific Password. Generated password is whitespace agnostic, so it could be displayed to the client as "abcd efgh ijkl mnop" instead of "abcdefghijklmnop"'
|
||||
),
|
||||
mobileconfig: Joi.string()
|
||||
.required()
|
||||
.description(
|
||||
'Base64 encoded mobileconfig file. Generated profile file should be sent to the client with Content-Type value of application/x-apple-aspen-config.'
|
||||
),
|
||||
name: Joi.string().required().description('Account name'),
|
||||
address: Joi.string().required().description('Account address or the address specified in params of this endpoint')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
tools.responseWrapper(async (req, res) => {
|
||||
res.charSet('utf-8');
|
||||
|
||||
const schema = Joi.object().keys({
|
||||
user: Joi.string().hex().lowercase().length(24).required(),
|
||||
description: Joi.string().trim().max(255).required(),
|
||||
scopes: Joi.array()
|
||||
.items(
|
||||
Joi.string()
|
||||
.valid(...consts.SCOPES, '*')
|
||||
.required()
|
||||
)
|
||||
.unique(),
|
||||
address: Joi.string().empty('').email({ tlds: false }),
|
||||
password: Joi.string()
|
||||
.empty('')
|
||||
.pattern(/^[a-z]{16}$/, { name: 'password' }),
|
||||
generateMobileconfig: booleanSchema.default(false),
|
||||
ttl: Joi.number().empty([0, '']),
|
||||
sess: sessSchema,
|
||||
ip: sessIPSchema
|
||||
const { pathParams, requestBody, queryParams } = req.route.spec.validationObjs;
|
||||
|
||||
const schema = Joi.object({
|
||||
...pathParams,
|
||||
...requestBody,
|
||||
...queryParams
|
||||
});
|
||||
|
||||
if (typeof req.params.scopes === 'string') {
|
||||
|
@ -432,15 +568,29 @@ module.exports = (db, server, userHandler) => {
|
|||
);
|
||||
|
||||
server.del(
|
||||
'/users/:user/asps/:asp',
|
||||
{
|
||||
path: '/users/:user/asps/:asp',
|
||||
tags: ['ApplicationPasswords'],
|
||||
summary: 'Delete an Application Password',
|
||||
validationObjs: {
|
||||
requestBody: {},
|
||||
queryParams: {
|
||||
sess: sessSchema,
|
||||
ip: sessIPSchema
|
||||
},
|
||||
pathParams: { user: userId, asp: Joi.string().hex().lowercase().length(24).required().description('ID of the Application Password') },
|
||||
response: { 200: { description: 'Success', model: Joi.object({ success: successRes }) } }
|
||||
}
|
||||
},
|
||||
tools.responseWrapper(async (req, res) => {
|
||||
res.charSet('utf-8');
|
||||
|
||||
const schema = Joi.object().keys({
|
||||
user: Joi.string().hex().lowercase().length(24).required(),
|
||||
asp: Joi.string().hex().lowercase().length(24).required(),
|
||||
sess: sessSchema,
|
||||
ip: sessIPSchema
|
||||
const { pathParams, requestBody, queryParams } = req.route.spec.validationObjs;
|
||||
|
||||
const schema = Joi.object({
|
||||
...pathParams,
|
||||
...requestBody,
|
||||
...queryParams
|
||||
});
|
||||
|
||||
const result = schema.validate(req.params, {
|
||||
|
|
Loading…
Reference in a new issue