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:
NickOvt 2024-03-18 10:37:16 +02:00 committed by GitHub
parent b9e3f94c6f
commit 9f9c55a886
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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, {