Skip to content
Merged
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
64 changes: 64 additions & 0 deletions packages/gitlab/webhooks/types.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import type { WebhookRequest } from 'corsair/core';
import type { GitlabWebhookPayload } from './types';
import { verifyGitlabWebhookSignature } from './types';

describe('verifyGitlabWebhookSignature', () => {
const secret = 'my-super-secret-token';
const payload: GitlabWebhookPayload = {
object_kind: 'push',
event_name: 'push',
};

const requestWith = (
headers: Record<string, string | string[]>,
): WebhookRequest<GitlabWebhookPayload> => ({
payload,
headers,
rawBody: JSON.stringify(payload),
});

it('should fail closed when secret is missing', () => {
// The regression: verification returned { valid: true } unconditionally
// when no secret was configured, without ever reading the token header.
const result = verifyGitlabWebhookSignature(
requestWith({ 'x-gitlab-token': secret }),
'',
);
expect(result).toEqual({
valid: false,
error: 'Missing webhook secret',
});
});

it('should fail closed when both secret and token header are missing', () => {
const result = verifyGitlabWebhookSignature(requestWith({}), '');
expect(result.valid).toBe(false);
});

it('should return invalid if the token header is missing', () => {
const result = verifyGitlabWebhookSignature(requestWith({}), secret);
expect(result).toEqual({
valid: false,
error: 'Missing X-Gitlab-Token header',
});
});

it('should return invalid if the token does not match the secret', () => {
const result = verifyGitlabWebhookSignature(
requestWith({ 'x-gitlab-token': 'not-the-secret' }),
secret,
);
expect(result).toEqual({
valid: false,
error: 'X-Gitlab-Token does not match configured secret',
});
});

it('should return valid when the token matches the configured secret', () => {
const result = verifyGitlabWebhookSignature(
requestWith({ 'x-gitlab-token': secret }),
secret,
);
expect(result).toEqual({ valid: true });
});
});
2 changes: 1 addition & 1 deletion packages/gitlab/webhooks/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function verifyGitlabWebhookSignature(
secret: string,
): { valid: boolean; error?: string } {
if (!secret) {
return { valid: true };
return { valid: false, error: 'Missing webhook secret' };
}

const token = request.headers['x-gitlab-token'];
Expand Down
Loading