mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-15 05:37:22 +01:00
fix(api): Prevent webhooks from having duplicate ids
This commit is contained in:
@@ -100,6 +100,16 @@ describe('POST /user/webhook', () => {
|
|||||||
expect(webhook.url).to.eql(body.url);
|
expect(webhook.url).to.eql(body.url);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('cannot use an id of a webhook that already exists', async () => {
|
||||||
|
await user.post('/user/webhook', body);
|
||||||
|
|
||||||
|
await expect(user.post('/user/webhook', body)).to.eventually.be.rejected.and.eql({
|
||||||
|
code: 400,
|
||||||
|
error: 'BadRequest',
|
||||||
|
message: t('webhookIdAlreadyTaken', { id: body.id }),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('defaults taskActivity options', async () => {
|
it('defaults taskActivity options', async () => {
|
||||||
body.type = 'taskActivity';
|
body.type = 'taskActivity';
|
||||||
|
|
||||||
|
|||||||
@@ -159,6 +159,7 @@
|
|||||||
"missingWebhookId": "The webhook's id is required.",
|
"missingWebhookId": "The webhook's id is required.",
|
||||||
"invalidWebhookType": "\"<%= type %>\" is not a valid value for the parameter \"type\".",
|
"invalidWebhookType": "\"<%= type %>\" is not a valid value for the parameter \"type\".",
|
||||||
"webhookBooleanOption": "\"<%= option %>\" must be a Boolean value.",
|
"webhookBooleanOption": "\"<%= option %>\" must be a Boolean value.",
|
||||||
|
"webhookIdAlreadyTaken": "A webhook with the id <%= id %> already exists.",
|
||||||
"noWebhookWithId": "There is no webhook with the id <%= id %>.",
|
"noWebhookWithId": "There is no webhook with the id <%= id %>.",
|
||||||
"regIdRequired": "RegId is required",
|
"regIdRequired": "RegId is required",
|
||||||
"invalidPushClient": "Invalid client. Only Official Habitica clients can receive push notifications.",
|
"invalidPushClient": "Invalid client. Only Official Habitica clients can receive push notifications.",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { authWithHeaders } from '../../middlewares/auth';
|
import { authWithHeaders } from '../../middlewares/auth';
|
||||||
import { model as Webhook } from '../../models/webhook';
|
import { model as Webhook } from '../../models/webhook';
|
||||||
import { removeFromArray } from '../../libs/collectionManipulators';
|
import { removeFromArray } from '../../libs/collectionManipulators';
|
||||||
import { NotFound } from '../../libs/errors';
|
import { NotFound, BadRequest } from '../../libs/errors';
|
||||||
|
|
||||||
let api = {};
|
let api = {};
|
||||||
|
|
||||||
@@ -53,6 +53,7 @@ let api = {};
|
|||||||
* @apiSuccess {Object} data.options The options for the webhook (See examples)
|
* @apiSuccess {Object} data.options The options for the webhook (See examples)
|
||||||
*
|
*
|
||||||
* @apiError InvalidUUID The `id` was not a valid `UUID`
|
* @apiError InvalidUUID The `id` was not a valid `UUID`
|
||||||
|
* @apiError IdTaken The `id` is already being used by another webhook
|
||||||
* @apiError InvalidEnable The `enable` param was not a `Boolean` value
|
* @apiError InvalidEnable The `enable` param was not a `Boolean` value
|
||||||
* @apiError InvalidUrl The `url` param was not valid url
|
* @apiError InvalidUrl The `url` param was not valid url
|
||||||
* @apiError InvalidWebhookType The `type` param was not a supported Webhook type
|
* @apiError InvalidWebhookType The `type` param was not a supported Webhook type
|
||||||
@@ -67,6 +68,14 @@ api.addWebhook = {
|
|||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
let webhook = new Webhook(req.body);
|
let webhook = new Webhook(req.body);
|
||||||
|
|
||||||
|
let existingWebhook = user.webhooks.find((wh) => {
|
||||||
|
return wh.id === webhook.id;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingWebhook) {
|
||||||
|
throw new BadRequest(res.t('webhookIdAlreadyTaken', { id: webhook.id }));
|
||||||
|
}
|
||||||
|
|
||||||
webhook.formatOptions(res);
|
webhook.formatOptions(res);
|
||||||
|
|
||||||
user.webhooks.push(webhook);
|
user.webhooks.push(webhook);
|
||||||
|
|||||||
Reference in New Issue
Block a user