feat(plugin-scaffolder-backend): Validate webhook event names
Webhook event names are validated against Octokit Webhooks `emitterEventNames`. Note `emitterEventNames` contains event/action combinations as well that are comma delimited. Therefore, extracting strings without '.' provides list of all events. "@octokit/webhooks" version 9.14.0 is the minimum requirement because this is a version where I introduced exported `emitterEventNames` to be used here. Signed-off-by: @pawelmitka <pawel.mitka@brainly.com>
This commit is contained in:
@@ -179,7 +179,7 @@ export function createRouter(options: RouterOptions): Promise<express.Router>;
|
||||
// @public (undocumented)
|
||||
export const createTemplateAction: <
|
||||
Input extends Partial<{
|
||||
[name: string]: JsonValue | Partial<JsonObject> | undefined;
|
||||
[name: string]: Partial<JsonObject> | JsonValue | undefined;
|
||||
}>,
|
||||
>(
|
||||
templateAction: TemplateAction<Input>,
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
"@gitbeaker/core": "^30.2.0",
|
||||
"@gitbeaker/node": "^30.2.0",
|
||||
"@octokit/rest": "^18.5.3",
|
||||
"@octokit/webhooks": "^9.14.1",
|
||||
"@types/express": "^4.17.6",
|
||||
"azure-devops-node-api": "^11.0.1",
|
||||
"command-exists": "^1.2.9",
|
||||
|
||||
+58
@@ -205,4 +205,62 @@ describe('github:repository:webhook:create', () => {
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should validate input', async () => {
|
||||
const Validator = require('jsonschema').Validator;
|
||||
const v = new Validator();
|
||||
|
||||
// validate default input without events specified
|
||||
expect(v.validate(mockContext.input, action.schema?.input).valid).toBe(
|
||||
true,
|
||||
);
|
||||
|
||||
const inputWithValidEvent = {
|
||||
...mockContext.input,
|
||||
events: ['push'],
|
||||
};
|
||||
expect(v.validate(inputWithValidEvent, action.schema?.input).valid).toBe(
|
||||
true,
|
||||
);
|
||||
|
||||
const inputWithMultipleValidEvents = {
|
||||
...mockContext.input,
|
||||
events: ['push', 'pull_request'],
|
||||
};
|
||||
expect(
|
||||
v.validate(inputWithMultipleValidEvents, action.schema?.input).valid,
|
||||
).toBe(true);
|
||||
|
||||
const inputWithInvalidEvent = {
|
||||
...mockContext.input,
|
||||
events: ['unexpected_event'],
|
||||
};
|
||||
expect(v.validate(inputWithInvalidEvent, action.schema?.input).valid).toBe(
|
||||
false,
|
||||
);
|
||||
|
||||
const inputWithOneInvalidEvent = {
|
||||
...mockContext.input,
|
||||
events: ['push', 'unexpected_event'],
|
||||
};
|
||||
expect(
|
||||
v.validate(inputWithOneInvalidEvent, action.schema?.input).valid,
|
||||
).toBe(false);
|
||||
|
||||
const inputWithAllEvents = {
|
||||
...mockContext.input,
|
||||
events: ['*'],
|
||||
};
|
||||
expect(v.validate(inputWithAllEvents, action.schema?.input).valid).toBe(
|
||||
true,
|
||||
);
|
||||
|
||||
const inputWithAllEventsAndMore = {
|
||||
...mockContext.input,
|
||||
events: ['*', 'push'],
|
||||
};
|
||||
expect(
|
||||
v.validate(inputWithAllEventsAndMore, action.schema?.input).valid,
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
import { ScmIntegrationRegistry } from '@backstage/integration';
|
||||
import { createTemplateAction } from '../../createTemplateAction';
|
||||
import { OctokitProvider } from './OctokitProvider';
|
||||
import { emitterEventNames } from '@octokit/webhooks';
|
||||
|
||||
type ContentType = 'form' | 'json';
|
||||
|
||||
@@ -25,6 +26,7 @@ export function createGithubWebhookAction(options: {
|
||||
}) {
|
||||
const { integrations, defaultWebhookSecret } = options;
|
||||
const octokitProvider = new OctokitProvider(integrations);
|
||||
const eventNames = emitterEventNames.filter(event => !event.includes('.'));
|
||||
|
||||
return createTemplateAction<{
|
||||
repoUrl: string;
|
||||
@@ -63,9 +65,20 @@ export function createGithubWebhookAction(options: {
|
||||
description:
|
||||
'Determines what events the hook is triggered for. Default: push',
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'string',
|
||||
},
|
||||
oneOf: [
|
||||
{
|
||||
items: {
|
||||
type: 'string',
|
||||
enum: eventNames,
|
||||
},
|
||||
},
|
||||
{
|
||||
items: {
|
||||
type: 'string',
|
||||
const: '*',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
active: {
|
||||
title: 'Active',
|
||||
|
||||
Reference in New Issue
Block a user