wildduck/lib/api/settings.js
2021-09-04 10:30:50 +03:00

176 lines
5.1 KiB
JavaScript

'use strict';
const Joi = require('joi');
const tools = require('../tools');
const roles = require('../roles');
const { sessSchema, sessIPSchema } = require('../schemas');
// allow overriding the following consts using the key format `const:archive:time`
module.exports = (db, server, settingsHandler) => {
server.get(
{ name: 'settings', path: '/settings' },
tools.asyncifyJson(async (req, res, next) => {
res.charSet('utf-8');
const schema = Joi.object().keys({
prefix: Joi.string().empty('').max(128),
sess: sessSchema,
ip: sessIPSchema
});
const result = schema.validate(req.params, {
abortEarly: false,
convert: true,
allowUnknown: true
});
if (result.error) {
res.status(400);
res.json({
error: result.error.message,
code: 'InputValidationError',
details: tools.validationErrors(result)
});
return next();
}
let permission = roles.can(req.role).readAny('settings');
// permissions check
req.validate(permission);
let settings = await settingsHandler.list(result.value.prefix);
let response = {
success: true,
prefix: result.value.prefix,
settings
};
res.json(response);
return next();
})
);
server.put(
'/settings/:key',
tools.asyncifyJson(async (req, res, next) => {
res.charSet('utf-8');
const schema = Joi.object().keys({
key: Joi.string()
.empty('')
.valid(...settingsHandler.keys.map(entry => entry.key))
.required(),
value: Joi.any()
.when('key', {
switch: settingsHandler.keys.map(entry => ({
is: entry.key,
then: entry.schema
}))
})
.required(),
sess: sessSchema,
ip: sessIPSchema
});
const result = schema.validate(req.params, {
abortEarly: false,
convert: true
});
if (result.error) {
res.status(400);
res.json({
error: result.error.message,
code: 'InputValidationError',
details: tools.validationErrors(result)
});
return next();
}
// permissions check
let permission = roles.can(req.role).createAny('settings');
req.validate(permission);
result.value = permission.filter(result.value);
let key = result.value.key;
let value = result.value.value;
let storedValue;
try {
storedValue = await settingsHandler.set(key, value);
} catch (err) {
res.status(500);
res.json({
error: 'MongoDB Error: ' + err.message,
code: 'InternalDatabaseError'
});
return next();
}
res.json({
success: !!storedValue,
key
});
return next();
})
);
server.get(
'/settings/:key',
tools.asyncifyJson(async (req, res, next) => {
res.charSet('utf-8');
const schema = Joi.object().keys({
key: Joi.string().empty('').max(128).required(),
sess: sessSchema,
ip: sessIPSchema
});
const result = schema.validate(req.params, {
abortEarly: false,
convert: true
});
if (result.error) {
res.status(400);
res.json({
error: result.error.message,
code: 'InputValidationError',
details: tools.validationErrors(result)
});
return next();
}
// permissions check
let permission = roles.can(req.role).readAny('settings');
req.validate(permission);
let key = result.value.key;
let value;
try {
value = await settingsHandler.get(key, {});
} catch (err) {
res.status(500);
res.json({
error: 'MongoDB Error: ' + err.message,
code: 'InternalDatabaseError'
});
return next();
}
res.json({
success: value !== undefined,
key,
value,
error: value === undefined ? 'Key was not found' : undefined
});
return next();
})
);
};