1.0.18
This commit is contained in:
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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user