This commit is contained in:
jarek committed 2026-01-14 08:18:20 +01:00
1 parent 027aee434c
commit 62636426bf
15 files changed
+317 -65

No files matched your search

+10 -2
View File
@@ -13,6 +13,9 @@ import { authorize } from '$lib/server/authorize';
import { registerSchedule } from '$lib/server/scheduler';
import { secureRandomBytes } from '$lib/server/crypto-fallback';
// Stack name validation: must start with alphanumeric, can contain alphanumeric, hyphens, underscores
const STACK_NAME_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;
export const GET: RequestHandler = async ({ url, cookies }) => {
const auth = await authorize(cookies);
@@ -49,6 +52,11 @@ export const POST: RequestHandler = async ({ request, cookies }) => {
return json({ error: 'Stack name is required' }, { status: 400 });
}
const trimmedStackName = data.stackName.trim();
if (!STACK_NAME_REGEX.test(trimmedStackName)) {
return json({ error: 'Stack name must start with a letter or number, and contain only letters, numbers, hyphens, and underscores' }, { status: 400 });
}
// Either repositoryId or new repo details (url, branch) must be provided
let repositoryId = data.repositoryId;
@@ -98,7 +106,7 @@ export const POST: RequestHandler = async ({ request, cookies }) => {
}
const gitStack = await createGitStack({
stackName: data.stackName,
stackName: trimmedStackName,
environmentId: data.environmentId || null,
repositoryId: repositoryId,
composePath: data.composePath || 'docker-compose.yml',
@@ -112,7 +120,7 @@ export const POST: RequestHandler = async ({ request, cookies }) => {
// Create stack_sources entry so the stack appears in the list immediately
await upsertStackSource({
stackName: data.stackName,
stackName: trimmedStackName,
environmentId: data.environmentId || null,
sourceType: 'git',
gitRepositoryId: repositoryId,
+26 -1
View File
@@ -1,10 +1,13 @@
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { getGitStack, updateGitStack, deleteGitStack } from '$lib/server/db';
import { getGitStack, updateGitStack, deleteGitStack, deleteStackSource, updateStackSourceName } from '$lib/server/db';
import { deleteGitStackFiles, deployGitStack } from '$lib/server/git';
import { authorize } from '$lib/server/authorize';
import { registerSchedule, unregisterSchedule } from '$lib/server/scheduler';
// Stack name validation: must start with alphanumeric, can contain alphanumeric, hyphens, underscores
const STACK_NAME_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;
export const GET: RequestHandler = async ({ params, cookies }) => {
const auth = await authorize(cookies);
@@ -43,6 +46,20 @@ export const PUT: RequestHandler = async ({ params, request, cookies }) => {
}
const data = await request.json();
// Validate stack name if it's being changed
if (data.stackName !== undefined) {
const trimmedStackName = data.stackName.trim();
if (!trimmedStackName) {
return json({ error: 'Stack name is required' }, { status: 400 });
}
if (!STACK_NAME_REGEX.test(trimmedStackName)) {
return json({ error: 'Stack name must start with a letter or number, and contain only letters, numbers, hyphens, and underscores' }, { status: 400 });
}
data.stackName = trimmedStackName;
}
const oldStackName = existing.stackName;
const updated = await updateGitStack(id, {
stackName: data.stackName,
composePath: data.composePath,
@@ -54,6 +71,11 @@ export const PUT: RequestHandler = async ({ params, request, cookies }) => {
webhookSecret: data.webhookSecret
});
// If stack name changed, update the stack_sources record too
if (data.stackName && data.stackName !== oldStackName) {
await updateStackSourceName(oldStackName, data.stackName, existing.environmentId);
}
// Register or unregister schedule with croner
if (updated.autoUpdate && updated.autoUpdateCron) {
await registerSchedule(id, 'git_stack_sync', updated.environmentId);
@@ -101,6 +123,9 @@ export const DELETE: RequestHandler = async ({ params, cookies }) => {
// Delete git files first
deleteGitStackFiles(id);
// Delete the stack_sources record to free up the stack name
await deleteStackSource(existing.stackName, existing.environmentId);
// Delete from database
await deleteGitStack(id);