This commit is contained in:
jarek committed 2026-02-16 08:46:56 +01:00
1 parent d83ca684d7
commit 8ee4fe4d68
49 files changed
+2126 -261

No files matched your search

@@ -2,6 +2,7 @@ import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { getGitStack } from '$lib/server/db';
import { deployGitStack } from '$lib/server/git';
import { auditGitStack } from '$lib/server/audit';
import crypto from 'node:crypto';
function verifySignature(payload: string, signature: string | null, secret: string): boolean {
@@ -26,7 +27,14 @@ function verifySignature(payload: string, signature: string | null, secret: stri
return signature === secret;
}
export const POST: RequestHandler = async ({ params, request }) => {
function detectSource(request: Request): string {
if (request.headers.get('x-hub-signature-256')) return 'github';
if (request.headers.get('x-gitlab-token')) return 'gitlab';
return 'unknown';
}
export const POST: RequestHandler = async (event) => {
const { params, request } = event;
try {
const id = parseInt(params.id);
if (isNaN(id)) {
@@ -42,6 +50,8 @@ export const POST: RequestHandler = async ({ params, request }) => {
return json({ error: 'Webhook is not enabled for this stack' }, { status: 403 });
}
const source = detectSource(request);
// Verify webhook secret if set
if (gitStack.webhookSecret) {
const payload = await request.text();
@@ -51,12 +61,18 @@ export const POST: RequestHandler = async ({ params, request }) => {
const signature = githubSignature || gitlabToken;
if (!verifySignature(payload, signature, gitStack.webhookSecret)) {
await auditGitStack(event, 'webhook', id, gitStack.stackName, gitStack.environmentId, {
method: 'POST', source, error: 'invalid_signature'
});
return json({ error: 'Invalid webhook signature' }, { status: 401 });
}
}
// Deploy the git stack (syncs and deploys only if there are changes)
const result = await deployGitStack(id, { force: false });
await auditGitStack(event, 'webhook', id, gitStack.stackName, gitStack.environmentId, {
method: 'POST', source, result: result.skipped ? 'skipped' : result.success ? 'deployed' : 'failed'
});
return json(result);
} catch (error: any) {
console.error('Webhook error:', error);
@@ -65,7 +81,8 @@ export const POST: RequestHandler = async ({ params, request }) => {
};
// Also support GET for simple polling/manual triggers
export const GET: RequestHandler = async ({ params, url }) => {
export const GET: RequestHandler = async (event) => {
const { params, url } = event;
try {
const id = parseInt(params.id);
if (isNaN(id)) {
@@ -84,11 +101,17 @@ export const GET: RequestHandler = async ({ params, url }) => {
// Verify secret via query parameter for GET requests
const secret = url.searchParams.get('secret');
if (gitStack.webhookSecret && secret !== gitStack.webhookSecret) {
await auditGitStack(event, 'webhook', id, gitStack.stackName, gitStack.environmentId, {
method: 'GET', source: 'get', error: 'invalid_secret'
});
return json({ error: 'Invalid webhook secret' }, { status: 401 });
}
// Deploy the git stack (syncs and deploys only if there are changes)
const result = await deployGitStack(id, { force: false });
await auditGitStack(event, 'webhook', id, gitStack.stackName, gitStack.environmentId, {
method: 'GET', source: 'get', result: result.skipped ? 'skipped' : result.success ? 'deployed' : 'failed'
});
return json(result);
} catch (error: any) {
console.error('Webhook GET error:', error);
+25 -2
View File
@@ -2,6 +2,7 @@ import { json, text } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { getGitRepository } from '$lib/server/db';
import { deployFromRepository } from '$lib/server/git';
import { auditGitRepository } from '$lib/server/audit';
import crypto from 'node:crypto';
function verifySignature(payload: string, signature: string | null, secret: string): boolean {
@@ -26,7 +27,14 @@ function verifySignature(payload: string, signature: string | null, secret: stri
return signature === secret;
}
export const POST: RequestHandler = async ({ params, request }) => {
function detectSource(request: Request): string {
if (request.headers.get('x-hub-signature-256')) return 'github';
if (request.headers.get('x-gitlab-token')) return 'gitlab';
return 'unknown';
}
export const POST: RequestHandler = async (event) => {
const { params, request } = event;
try {
const id = parseInt(params.id);
if (isNaN(id)) {
@@ -42,6 +50,8 @@ export const POST: RequestHandler = async ({ params, request }) => {
return json({ error: 'Webhook is not enabled for this repository' }, { status: 403 });
}
const source = detectSource(request);
// Verify webhook secret if set
if (repository.webhookSecret) {
const payload = await request.text();
@@ -51,6 +61,9 @@ export const POST: RequestHandler = async ({ params, request }) => {
const signature = githubSignature || gitlabToken;
if (!verifySignature(payload, signature, repository.webhookSecret)) {
await auditGitRepository(event, 'webhook', id, repository.name, {
method: 'POST', source, error: 'invalid_signature'
});
return json({ error: 'Invalid webhook signature' }, { status: 401 });
}
}
@@ -63,6 +76,9 @@ export const POST: RequestHandler = async ({ params, request }) => {
// Deploy from repository
const result = await deployFromRepository(id);
await auditGitRepository(event, 'webhook', id, repository.name, {
method: 'POST', source, result: result.success ? 'deployed' : 'failed'
});
return json(result);
} catch (error: any) {
console.error('Webhook error:', error);
@@ -71,7 +87,8 @@ export const POST: RequestHandler = async ({ params, request }) => {
};
// Also support GET for simple polling/manual triggers
export const GET: RequestHandler = async ({ params, url }) => {
export const GET: RequestHandler = async (event) => {
const { params, url } = event;
try {
const id = parseInt(params.id);
if (isNaN(id)) {
@@ -90,11 +107,17 @@ export const GET: RequestHandler = async ({ params, url }) => {
// Verify secret via query parameter for GET requests
const secret = url.searchParams.get('secret');
if (repository.webhookSecret && secret !== repository.webhookSecret) {
await auditGitRepository(event, 'webhook', id, repository.name, {
method: 'GET', source: 'get', error: 'invalid_secret'
});
return json({ error: 'Invalid webhook secret' }, { status: 401 });
}
// Deploy from repository
const result = await deployFromRepository(id);
await auditGitRepository(event, 'webhook', id, repository.name, {
method: 'GET', source: 'get', result: result.success ? 'deployed' : 'failed'
});
return json(result);
} catch (error: any) {
console.error('Webhook GET error:', error);