wildduck/lib/api/domainaccess.js
2021-08-30 11:21:50 +03:00

227 lines
6.5 KiB
JavaScript

'use strict';
const Joi = require('joi');
const ObjectId = require('mongodb').ObjectId;
const tools = require('../tools');
const roles = require('../roles');
const { sessSchema, sessIPSchema } = require('../schemas');
module.exports = (db, server) => {
server.post(
'/domainaccess/:tag/:action',
tools.asyncifyJson(async (req, res, next) => {
res.charSet('utf-8');
const schema = Joi.object().keys({
tag: Joi.string().trim().max(128).required(),
domain: Joi.string()
.max(255)
//.hostname()
.required(),
action: Joi.string().valid('allow', 'block').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
req.validate(roles.can(req.role).createAny('domainaccess'));
let domain = tools.normalizeDomain(result.value.domain);
let tag = result.value.tag;
let tagview = tag.toLowerCase();
let action = result.value.action;
let r;
try {
r = await db.database.collection('domainaccess').findOneAndUpdate(
{
tagview,
domain
},
{
$setOnInsert: {
tag,
tagview,
domain
},
$set: {
action
}
},
{
upsert: true,
projection: { _id: true },
returnDocument: 'after'
}
);
} catch (err) {
res.status(500);
res.json({
error: 'MongoDB Error: ' + err.message,
code: 'InternalDatabaseError'
});
return next();
}
res.json({
success: !!(r && r.value),
id: ((r && r.value && r.value._id) || '').toString()
});
return next();
})
);
server.get(
'/domainaccess/:tag/:action',
tools.asyncifyJson(async (req, res, next) => {
res.charSet('utf-8');
const schema = Joi.object().keys({
tag: Joi.string().trim().max(128).required(),
action: Joi.string().valid('allow', 'block').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
req.validate(roles.can(req.role).readAny('domainaccess'));
let tag = result.value.tag;
let tagview = tag.toLowerCase();
let action = result.value.action;
let domains;
try {
domains = await db.database
.collection('domainaccess')
.find({
tagview,
action
})
.sort({
domain: 1
})
.toArray();
} catch (err) {
res.status(500);
res.json({
error: 'MongoDB Error: ' + err.message,
code: 'InternalDatabaseError'
});
return next();
}
if (!domains) {
domains = [];
}
res.json({
success: true,
results: domains.map(domainData => ({
id: domainData._id.toString(),
domain: domainData.domain,
action
}))
});
return next();
})
);
server.del(
'/domainaccess/:domain',
tools.asyncifyJson(async (req, res, next) => {
res.charSet('utf-8');
const schema = Joi.object().keys({
domain: Joi.string().hex().lowercase().length(24).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
req.validate(roles.can(req.role).deleteAny('domainaccess'));
let domain = new ObjectId(result.value.domain);
let r;
try {
r = await db.database.collection('domainaccess').deleteOne({
_id: domain
});
} catch (err) {
res.status(500);
res.json({
error: 'MongoDB Error: ' + err.message,
code: 'InternalDatabaseError'
});
return next();
}
if (!r.deletedCount) {
res.status(404);
res.json({
error: 'Domain was not found',
code: 'DomainNotFound'
});
return next();
}
res.json({
success: true,
deleted: domain
});
return next();
})
);
};