Skip to content

Commit 742b567

Browse files
authored
Merge pull request #8 from techulus/main
2026.2.10
2 parents 6d7554d + 4dbec71 commit 742b567

23 files changed

Lines changed: 1154 additions & 832 deletions

File tree

web/actions/projects.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,18 @@ import cronstrue from "cronstrue";
4040
import { startMigration } from "./migrations";
4141
import { inngest } from "@/lib/inngest/client";
4242

43+
function isValidImageReferencePart(reference: string): boolean {
44+
// Allow only characters that are valid in Docker tags/digests and avoid path traversal.
45+
// Tags: letters, digits, underscores, periods and dashes; Digests: "algorithm:hex".
46+
// This regex is intentionally conservative.
47+
const tagPattern = /^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$/;
48+
const digestPattern = /^[A-Za-z0-9_+.-]+:[0-9a-fA-F]{32,256}$/;
49+
50+
return reference === "latest" ||
51+
tagPattern.test(reference) ||
52+
digestPattern.test(reference);
53+
}
54+
4355
function parseImageReference(image: string): {
4456
registry: string;
4557
namespace: string;
@@ -96,6 +108,13 @@ export async function validateDockerImage(
96108
parseImageReference(image);
97109
const reference = digest || tag || "latest";
98110

111+
if (!isValidImageReferencePart(reference)) {
112+
return {
113+
valid: false,
114+
error: "Invalid image tag or digest",
115+
};
116+
}
117+
99118
if (registry === "docker.io") {
100119
const repoPath =
101120
namespace === "library" ? repository : `${namespace}/${repository}`;

web/app/(auth)/login/page.tsx

Lines changed: 0 additions & 99 deletions
This file was deleted.

web/app/(auth)/register/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export default function RegisterPage() {
101101
</Button>
102102
<p className="text-sm text-muted-foreground">
103103
Already have an account?{" "}
104-
<Link href="/login" className="text-primary hover:underline">
104+
<Link href="/" className="text-primary hover:underline">
105105
Sign in
106106
</Link>
107107
</p>

web/app/(dashboard)/dashboard/projects/[slug]/[env]/services/[serviceId]/configuration/page.tsx

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
"use client";
22

3-
import { useState } from "react";
3+
import { useCallback, useState } from "react";
44
import { useRouter } from "next/navigation";
5+
import { toast } from "sonner";
56
import { useSWRConfig } from "swr";
67
import { deleteService } from "@/actions/projects";
78
import { useService } from "@/components/service/service-layout-client";
@@ -36,6 +37,11 @@ export default function ConfigurationPage() {
3637
const { service, projectSlug, envName, proxyDomain, onUpdate } = useService();
3738
const [isDeleting, setIsDeleting] = useState(false);
3839

40+
const handleConfigSave = useCallback(() => {
41+
onUpdate();
42+
toast.info("Changes saved. Deploy to apply them.");
43+
}, [onUpdate]);
44+
3945
const handleDelete = async () => {
4046
setIsDeleting(true);
4147
try {
@@ -49,29 +55,29 @@ export default function ConfigurationPage() {
4955

5056
return (
5157
<div className="space-y-6">
52-
<SourceSection service={service} onUpdate={onUpdate} />
58+
<SourceSection service={service} onUpdate={handleConfigSave} />
5359

54-
<ReplicasSection service={service} onUpdate={onUpdate} />
60+
<ReplicasSection service={service} onUpdate={handleConfigSave} />
5561

56-
<VolumesSection service={service} onUpdate={onUpdate} />
62+
<VolumesSection service={service} onUpdate={handleConfigSave} />
5763

58-
<SecretsSection service={service} onUpdate={onUpdate} />
64+
<SecretsSection service={service} onUpdate={handleConfigSave} />
5965

60-
<PortsSection service={service} onUpdate={onUpdate} />
66+
<PortsSection service={service} onUpdate={handleConfigSave} />
6167

6268
<TCPProxySection
6369
service={service}
6470
proxyDomain={proxyDomain}
65-
onUpdate={onUpdate}
71+
onUpdate={handleConfigSave}
6672
/>
6773

68-
<HealthCheckSection service={service} onUpdate={onUpdate} />
74+
<HealthCheckSection service={service} onUpdate={handleConfigSave} />
6975

70-
<ResourceLimitsSection service={service} onUpdate={onUpdate} />
76+
<ResourceLimitsSection service={service} onUpdate={handleConfigSave} />
7177

72-
<StartCommandSection service={service} onUpdate={onUpdate} />
78+
<StartCommandSection service={service} onUpdate={handleConfigSave} />
7379

74-
<ScheduleSection service={service} onUpdate={onUpdate} />
80+
<ScheduleSection service={service} onUpdate={handleConfigSave} />
7581

7682
<div className="space-y-3">
7783
<h2 className="text-xl font-semibold text-destructive">Danger Zone</h2>

0 commit comments

Comments
 (0)