Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ We make use of the following environment variables:
| NOTIFY_ISSUES_ASSIGNED_TO | A comma-separated list of GitHub user names. Only issues assigned to these users will be notified or leave it empty to receive all notifications. | No | _empty array_ |
| IGNORE_PR_OPENED_BY | A comma-separated list of GitHub user names. Only PR not opened by these users will be notified or leave it empty to receive all notifications. | No | _empty array_ |
| NOTIFY_CHECK_RUNS_FOR | Comma-separated list of branches to notify Check Runs for. Leave empty to notify for any branch | No | _empty_ _array_ |
| GITLAB_TOKEN | Allows you to configure a secret in order to add a security layer to the webhook | No | _empty_ |

### GitHub Configuration

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"dev": "nodemon src/index.js"
},
"dependencies": {
"@hapi/boom": "^9.1.0",
"@hapi/hapi": "^19.1.1",
"@hapi/joi": "^17.1.1",
"axios": "^0.19.2",
Expand Down
2 changes: 2 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface Config {
NOTIFY_CHECK_RUNS_FOR: string[];
NOTIFY_ISSUES_ASSIGNED_TO: string[];
IGNORE_PR_OPENED_BY: string[];
GITLAB_TOKEN?: string;
}

export const getConfig = (): Config => {
Expand Down Expand Up @@ -35,5 +36,6 @@ export const getConfig = (): Config => {
NOTIFY_CHECK_RUNS_FOR: process.env['NOTIFY_CHECK_RUNS_FOR']?.split(',') || [],
NOTIFY_ISSUES_ASSIGNED_TO: process.env['NOTIFY_ISSUES_ASSIGNED_TO']?.split(',') || [],
IGNORE_PR_OPENED_BY: process.env['IGNORE_PR_OPENED_BY']?.split(',') || [],
GITLAB_TOKEN: process.env['GITLAB_TOKEN'],
};
};
18 changes: 16 additions & 2 deletions src/routes/gitlab/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { TwitchChat } from '../../services/TwitchChat';
import { Config } from '../../config';
import { StreamLabs } from '../../services/StreamLabs';
import { MergeRequestPayload } from '../../schemas/gitlab/merge-request-payload';
import { Boom, forbidden } from '@hapi/boom';

export const routes = (config: Config): ServerRoute[] => {
return [
Expand All @@ -15,11 +16,24 @@ export const routes = (config: Config): ServerRoute[] => {
headers: gitlabHeader(),
},
},
handler: async (request: Request, h: ResponseToolkit): Promise<ResponseObject> => {
handler: async (request: Request, h: ResponseToolkit): Promise<ResponseObject | Boom> => {
const { headers, payload } = (request as unknown) as {
headers: { 'x-gitlab-event': string };
headers: { 'x-gitlab-event': string; 'x-gitlab-token': string };
payload: MergeRequestPayload;
};

if (config.GITLAB_TOKEN) {
if (!headers['x-gitlab-token']) {
console.error("Missing 'X-GitLab-Token' header");
return forbidden();
}

if (config.GITLAB_TOKEN !== headers['x-gitlab-token']) {
console.error("'X-GitLab-Token' mismatch");
return forbidden();
}
}

const event = headers['x-gitlab-event'];

const twitchChat = new TwitchChat({
Expand Down
38 changes: 38 additions & 0 deletions test/routes/gitlab/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,42 @@ describe('POST /gitlab', () => {

expect(result).toEqual({ message: `Ignoring event: 'test'` });
});

describe('with GitLab token configured', () => {
it("rejects any request without the 'X-Gitlab-Token' header", async () => {
const subject = await initServer({ ...getConfig(), GITLAB_TOKEN: 'patatas' });

const { statusCode } = await subject.inject({
method: 'POST',
url: '/gitlab',
headers: { 'X-Gitlab-Event': 'test' },
});

expect(statusCode).toEqual(403);
});

it("rejects request with an invalid 'X-Gitlab-Token' header", async () => {
const subject = await initServer({ ...getConfig(), GITLAB_TOKEN: 'patatas' });

const { statusCode } = await subject.inject({
method: 'POST',
url: '/gitlab',
headers: { 'X-Gitlab-Event': 'test', 'X-Gitlab-Token': 'patata' },
});

expect(statusCode).toEqual(403);
});

it("accepts request with an valid 'X-Gitlab-Token' header", async () => {
const subject = await initServer({ ...getConfig(), GITLAB_TOKEN: 'patatas' });

const { statusCode } = await subject.inject({
method: 'POST',
url: '/gitlab',
headers: { 'X-Gitlab-Event': 'test', 'X-Gitlab-Token': 'patatas' },
});

expect(statusCode).toEqual(200);
});
});
});
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@
dependencies:
"@hapi/hoek" "9.x.x"

"@hapi/boom@9.x.x", "@hapi/boom@^9.0.0":
"@hapi/boom@9.x.x", "@hapi/boom@^9.0.0", "@hapi/boom@^9.1.0":
version "9.1.0"
resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-9.1.0.tgz#0d9517657a56ff1e0b42d0aca9da1b37706fec56"
integrity sha512-4nZmpp4tXbm162LaZT45P7F7sgiem8dwAh2vHWT6XX24dozNjGMg6BvKCRvtCUcmcXqeMIUqWN8Rc5X8yKuROQ==
Expand Down