revamp db - refactor webhooks

This commit is contained in:
Dave Horton
2020-01-28 10:30:07 -05:00
parent 10074504c5
commit 87208bc669
13 changed files with 675 additions and 252 deletions
+71 -1
View File
@@ -1,6 +1,7 @@
const router = require('express').Router();
const {DbErrorBadRequest, DbErrorUnprocessableRequest} = require('../../utils/errors');
const Account = require('../../models/account');
const Webhook = require('../../models/webhook');
const ServiceProvider = require('../../models/service-provider');
const decorate = require('./decorate');
const sysError = require('./error');
@@ -25,6 +26,16 @@ async function validateAdd(req) {
throw new DbErrorBadRequest(`service_provider not found for sid ${req.body.service_provider_sid}`);
}
}
if (req.body.registration_hook && typeof req.body.registration_hook !== 'object') {
throw new DbErrorBadRequest('\'registration_hook\' must be an object when adding an account');
}
if (req.body.device_calling_hook && typeof req.body.device_calling_hook !== 'object') {
throw new DbErrorBadRequest('\'device_calling_hook\' must be an object when adding an account');
}
if (req.body.error_hook && typeof req.body.error_hook !== 'object') {
throw new DbErrorBadRequest('\'error_hook\' must be an object when adding an account');
}
}
async function validateUpdate(req, sid) {
if (req.user.hasAccountAuth && req.user.account_sid !== sid) {
@@ -53,7 +64,30 @@ async function validateDelete(req, sid) {
}
}
decorate(router, Account, ['add', 'update', 'delete'], preconditions);
decorate(router, Account, ['delete'], preconditions);
/* add */
router.post('/', async(req, res) => {
const logger = req.app.locals.logger;
try {
await validateAdd(req);
// create webhooks if provided
const obj = Object.assign({}, req.body);
for (const prop of ['registration_hook', 'device_calling_hook', 'error_hook']) {
if (obj[prop]) {
obj[`${prop}_sid`] = await Webhook.make(obj[prop]);
delete obj[prop];
}
}
//logger.debug(`Attempting to add account ${JSON.stringify(obj)}`);
const uuid = await Account.make(obj);
res.status(201).json({sid: uuid});
} catch (err) {
sysError(logger, res, err);
}
});
/* list */
router.get('/', async(req, res) => {
@@ -82,4 +116,40 @@ router.get('/:sid', async(req, res) => {
}
});
/* update */
router.put('/:sid', async(req, res) => {
const sid = req.params.sid;
const logger = req.app.locals.logger;
try {
// create webhooks if provided
const obj = Object.assign({}, req.body);
for (const prop of ['registration_hook', 'device_calling_hook', 'error_hook']) {
if (prop in obj && Object.keys(obj[prop]).length) {
if ('webhook_sid' in obj[prop]) {
const sid = obj[prop]['webhook_sid'];
delete obj[prop]['webhook_sid'];
await Webhook.update(sid, obj[prop]);
}
else {
const sid = await Webhook.make(obj[prop]);
obj[`${prop}_sid`] = sid;
}
}
else {
obj[`${prop}_sid`] = null;
}
delete obj[prop];
}
await validateUpdate(req, sid);
const rowsAffected = await Account.update(sid, obj);
if (rowsAffected === 0) {
return res.status(404).end();
}
res.status(204).end();
} catch (err) {
sysError(logger, res, err);
}
});
module.exports = router;
+73 -1
View File
@@ -2,6 +2,7 @@ const router = require('express').Router();
const {DbErrorBadRequest, DbErrorUnprocessableRequest} = require('../../utils/errors');
const Application = require('../../models/application');
const Account = require('../../models/account');
const Webhook = require('../../models/webhook');
const decorate = require('./decorate');
const sysError = require('./error');
const preconditions = {
@@ -23,12 +24,24 @@ async function validateAdd(req) {
throw new DbErrorBadRequest('insufficient privileges to create an application under the specified account');
}
}
if (req.body.call_hook && typeof req.body.call_hook !== 'object') {
throw new DbErrorBadRequest('\'call_hook\' must be an object when adding an application');
}
if (req.body.call_status_hook && typeof req.body.call_hook !== 'object') {
throw new DbErrorBadRequest('\'call_status_hook\' must be an object when adding an application');
}
}
async function validateUpdate(req, sid) {
if (req.user.account_sid && sid !== req.user.account_sid) {
throw new DbErrorBadRequest('you may not update or delete an application associated with a different account');
}
if (req.body.call_hook && typeof req.body.call_hook !== 'object') {
throw new DbErrorBadRequest('\'call_hook\' must be an object when updating an application');
}
if (req.body.call_status_hook && typeof req.body.call_hook !== 'object') {
throw new DbErrorBadRequest('\'call_status_hook\' must be an object when updating an application');
}
}
async function validateDelete(req, sid) {
@@ -39,7 +52,29 @@ async function validateDelete(req, sid) {
if (assignedPhoneNumbers > 0) throw new DbErrorUnprocessableRequest('cannot delete application with phone numbers');
}
decorate(router, Application, ['add', 'update', 'delete'], preconditions);
decorate(router, Application, ['delete'], preconditions);
/* add */
router.post('/', async(req, res) => {
const logger = req.app.locals.logger;
try {
await validateAdd(req);
// create webhooks if provided
const obj = Object.assign({}, req.body);
for (const prop of ['call_hook', 'call_status_hook']) {
if (obj[prop]) {
obj[`${prop}_sid`] = await Webhook.make(obj[prop]);
delete obj[prop];
}
}
const uuid = await Application.make(obj);
res.status(201).json({sid: uuid});
} catch (err) {
sysError(logger, res, err);
}
});
/* list */
router.get('/', async(req, res) => {
@@ -69,4 +104,41 @@ router.get('/:sid', async(req, res) => {
}
});
/* update */
router.put('/:sid', async(req, res) => {
const sid = req.params.sid;
const logger = req.app.locals.logger;
try {
await validateUpdate(req, sid);
// create webhooks if provided
const obj = Object.assign({}, req.body);
for (const prop of ['call_hook', 'call_status_hook']) {
if (prop in obj && Object.keys(obj[prop]).length) {
if ('webhook_sid' in obj[prop]) {
const sid = obj[prop]['webhook_sid'];
delete obj[prop]['webhook_sid'];
await Webhook.update(sid, obj[prop]);
}
else {
const sid = await Webhook.make(obj[prop]);
obj[`${prop}_sid`] = sid;
}
}
else {
obj[`${prop}_sid`] = null;
}
delete obj[prop];
}
const rowsAffected = await Application.update(sid, obj);
if (rowsAffected === 0) {
return res.status(404).end();
}
res.status(204).end();
} catch (err) {
sysError(logger, res, err);
}
});
module.exports = router;