Skip to content

Commit

Permalink
fix(api-domainaccess): Added all DomainAccess endpoints to api docs g…
Browse files Browse the repository at this point in the history
…eneration ZMS-144 (#670)

* added add domain to whitelist/blocklist api endpoints to api docs generation

* added all get and del domainaccess endpoints to api docs generation
  • Loading branch information
NickOvt committed Apr 11, 2024
1 parent 6e251c5 commit c846b66
Showing 1 changed file with 315 additions and 23 deletions.
338 changes: 315 additions & 23 deletions lib/api/domainaccess.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,49 @@ const ObjectId = require('mongodb').ObjectId;
const tools = require('../tools');
const roles = require('../roles');
const { sessSchema, sessIPSchema } = require('../schemas');
const { successRes } = require('../schemas/response/general-schemas');

module.exports = (db, server) => {
server.post(
'/domainaccess/:tag/:action',
{
path: '/domainaccess/:tag/allow',
tags: ['DomainAccess'],
summary: 'Add domain to allowlist',
description: 'If an email is sent from a domain that is listed in the allowlist then it is never marked as spam. Lists apply for tagged users.',
validationObjs: {
requestBody: {
domain: Joi.string()
.max(255)
//.hostname()
.required()
.description('Domain name to allowlist for users/addresses that include this tag'),
sess: sessSchema,
ip: sessIPSchema
},
queryParams: {},
pathParams: {
tag: Joi.string().trim().max(128).required().description('Tag to look for')
},
response: {
200: {
description: 'Success',
model: Joi.object({
success: successRes,
id: Joi.string().required().description('ID for the created record')
})
}
}
}
},
tools.responseWrapper(async (req, res) => {
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 { pathParams, requestBody, queryParams } = req.route.spec.validationObjs;

const schema = Joi.object({
...pathParams,
...requestBody,
...queryParams
});

const result = schema.validate(req.params, {
Expand All @@ -43,7 +70,7 @@ module.exports = (db, server) => {
let domain = tools.normalizeDomain(result.value.domain);
let tag = result.value.tag;
let tagview = tag.toLowerCase();
let action = result.value.action;
let action = 'allow';

let r;
try {
Expand Down Expand Up @@ -84,17 +111,257 @@ module.exports = (db, server) => {
})
);

server.post(
{
path: '/domainaccess/:tag/block',
tags: ['DomainAccess'],
summary: 'Add domain to blocklist',
description: 'If an email is sent from a domain that is listed in the blocklist then it is always marked as spam. Lists apply for tagged users.',
validationObjs: {
requestBody: {
domain: Joi.string()
.max(255)
//.hostname()
.required()
.description('Domain name to blocklist for users/addresses that include this tag'),
sess: sessSchema,
ip: sessIPSchema
},
queryParams: {},
pathParams: {
tag: Joi.string().trim().max(128).required().description('Tag to look for')
},
response: {
200: {
description: 'Success',
model: Joi.object({
success: successRes,
id: Joi.string().required().description('ID for the created record')
})
}
}
}
},
tools.responseWrapper(async (req, res) => {
res.charSet('utf-8');

const { pathParams, requestBody, queryParams } = req.route.spec.validationObjs;

const schema = Joi.object({
...pathParams,
...requestBody,
...queryParams
});

const result = schema.validate(req.params, {
abortEarly: false,
convert: true
});

if (result.error) {
res.status(400);
return res.json({
error: result.error.message,
code: 'InputValidationError',
details: tools.validationErrors(result)
});
}

// 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 = 'block';

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);
return res.json({
error: 'MongoDB Error: ' + err.message,
code: 'InternalDatabaseError'
});
}

return res.json({
success: !!(r && r.value),
id: ((r && r.value && r.value._id) || '').toString()
});
})
);

server.get(
{
path: '/domainaccess/:tag/allow',
tags: ['DomainAccess'],
summary: 'List allowlisted domains',
validationObjs: {
requestBody: {},
queryParams: {
ess: sessSchema,
ip: sessIPSchema
},
pathParams: {
tag: Joi.string().trim().max(128).required().description('Tag to look for')
},
response: {
200: {
description: 'Success',
model: Joi.object({
success: successRes,
results: Joi.array()
.items(
Joi.object({
id: Joi.string().required().description('Entry ID'),
domain: Joi.string().required().description('Allowlisted domain name'),
action: Joi.string().required().description('Action: `allow`').example('allow')
})
.required()
.$_setFlag('objectName', 'GetAllowedDomainResult')
)
.description('Domain list')
.required()
})
}
}
}
},
tools.responseWrapper(async (req, res) => {
res.charSet('utf-8');

const { pathParams, requestBody, queryParams } = req.route.spec.validationObjs;

const schema = Joi.object({
...pathParams,
...requestBody,
...queryParams
});

const result = schema.validate(req.params, {
abortEarly: false,
convert: true
});

if (result.error) {
res.status(400);
return res.json({
error: result.error.message,
code: 'InputValidationError',
details: tools.validationErrors(result)
});
}

// permissions check
req.validate(roles.can(req.role).readAny('domainaccess'));

let tag = result.value.tag;
let tagview = tag.toLowerCase();
let action = 'action';

let domains;
try {
domains = await db.database
.collection('domainaccess')
.find({
tagview,
action
})
.sort({
domain: 1
})
.toArray();
} catch (err) {
res.status(500);
return res.json({
error: 'MongoDB Error: ' + err.message,
code: 'InternalDatabaseError'
});
}

if (!domains) {
domains = [];
}

return res.json({
success: true,
results: domains.map(domainData => ({
id: domainData._id.toString(),
domain: domainData.domain,
action
}))
});
})
);

server.get(
'/domainaccess/:tag/:action',
{
path: '/domainaccess/:tag/block',
tags: ['DomainAccess'],
summary: 'List blocklisted domains',
validationObjs: {
requestBody: {},
queryParams: {
ess: sessSchema,
ip: sessIPSchema
},
pathParams: {
tag: Joi.string().trim().max(128).required().description('Tag to look for')
},
response: {
200: {
description: 'Success',
model: Joi.object({
success: successRes,
results: Joi.array()
.items(
Joi.object({
id: Joi.string().required().description('Entry ID'),
domain: Joi.string().required().description('Blocklisted domain name'),
action: Joi.string().required().description('Action: `block`').example('block')
})
.required()
.$_setFlag('objectName', 'GetBlockedDomainResult')
)
.description('Domain list')
.required()
})
}
}
}
},
tools.responseWrapper(async (req, res) => {
res.charSet('utf-8');

const schema = Joi.object().keys({
tag: Joi.string().trim().max(128).required(),
action: Joi.string().valid('allow', 'block').required(),
const { pathParams, requestBody, queryParams } = req.route.spec.validationObjs;

sess: sessSchema,
ip: sessIPSchema
const schema = Joi.object({
...pathParams,
...requestBody,
...queryParams
});

const result = schema.validate(req.params, {
Expand All @@ -116,7 +383,7 @@ module.exports = (db, server) => {

let tag = result.value.tag;
let tagview = tag.toLowerCase();
let action = result.value.action;
let action = 'block';

let domains;
try {
Expand Down Expand Up @@ -154,14 +421,39 @@ module.exports = (db, server) => {
);

server.del(
'/domainaccess/:domain',
{
path: '/domainaccess/:domain',
tags: ['DomainAccess'],
summary: 'Delete a Domain from listing',
validationObjs: {
requestBody: {},
queryParams: {
sess: sessSchema,
ip: sessIPSchema
},
pathParams: {
domain: Joi.string().hex().lowercase().length(24).required().description("Listed domain's unique ID")
},
response: {
200: {
description: 'Success',
model: Joi.object({
success: successRes,
deleted: Joi.string().required().description("Deleted domain's unique ID")
})
}
}
}
},
tools.responseWrapper(async (req, res) => {
res.charSet('utf-8');

const schema = Joi.object().keys({
domain: 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, {
Expand Down

0 comments on commit c846b66

Please sign in to comment.