feat(domain-handling): enhance custom entry point handling in AddDomain component

- Added logic to conditionally set the custom entry point based on the useCustomEntrypoint flag.
- Updated the onCheckedChange handler to clear the custom entry point value when the switch is turned off, improving form state management.
This commit is contained in:
Mauricio Siu
2026-04-04 10:17:06 -06:00
parent e36ae4b4d6
commit 8557432db0
4 changed files with 78 additions and 34 deletions
@@ -173,12 +173,12 @@ describe("createDomainLabels", () => {
"websecure", "websecure",
); );
// Web entrypoint should have both middlewares with redirect first // Web entrypoint with HTTPS should only have redirect
expect(webLabels).toContain( expect(webLabels).toContain(
"traefik.http.routers.test-app-1-web.middlewares=redirect-to-https@file,addprefix-test-app-1", "traefik.http.routers.test-app-1-web.middlewares=redirect-to-https@file",
); );
// Websecure should only have the addprefix middleware // Websecure should have the addprefix middleware
expect(websecureLabels).toContain( expect(websecureLabels).toContain(
"traefik.http.routers.test-app-1-websecure.middlewares=addprefix-test-app-1", "traefik.http.routers.test-app-1-websecure.middlewares=addprefix-test-app-1",
); );
@@ -210,9 +210,9 @@ describe("createDomainLabels", () => {
"traefik.http.middlewares.addprefix-test-app-1.addprefix.prefix=/hello", "traefik.http.middlewares.addprefix-test-app-1.addprefix.prefix=/hello",
); );
// Should have middlewares in correct order: redirect, stripprefix, addprefix // Web router with HTTPS should only have redirect
expect(webLabels).toContain( expect(webLabels).toContain(
"traefik.http.routers.test-app-1-web.middlewares=redirect-to-https@file,stripprefix-test-app-1,addprefix-test-app-1", "traefik.http.routers.test-app-1-web.middlewares=redirect-to-https@file",
); );
}); });
@@ -267,7 +267,7 @@ describe("createDomainLabels", () => {
); );
}); });
it("should combine custom middlewares with HTTPS redirect in correct order", async () => { it("should only have redirect on web router when HTTPS is enabled with custom middlewares", async () => {
const combinedDomain = { const combinedDomain = {
...baseDomain, ...baseDomain,
https: true, https: true,
@@ -275,13 +275,14 @@ describe("createDomainLabels", () => {
}; };
const labels = await createDomainLabels(appName, combinedDomain, "web"); const labels = await createDomainLabels(appName, combinedDomain, "web");
// HTTPS redirect should come before custom middleware // Web router with HTTPS should only redirect, custom middlewares go on websecure
expect(labels).toContain( expect(labels).toContain(
"traefik.http.routers.test-app-1-web.middlewares=redirect-to-https@file,auth@file", "traefik.http.routers.test-app-1-web.middlewares=redirect-to-https@file",
); );
expect(labels).not.toContain("auth@file");
}); });
it("should combine custom middlewares with stripPath middleware", async () => { it("should combine custom middlewares with stripPath middleware (no HTTPS)", async () => {
const combinedDomain = { const combinedDomain = {
...baseDomain, ...baseDomain,
path: "/api", path: "/api",
@@ -296,7 +297,7 @@ describe("createDomainLabels", () => {
); );
}); });
it("should combine all built-in middlewares with custom middlewares in correct order", async () => { it("should only have redirect on web router even with all built-in middlewares and custom middlewares", async () => {
const fullDomain = { const fullDomain = {
...baseDomain, ...baseDomain,
https: true, https: true,
@@ -307,10 +308,21 @@ describe("createDomainLabels", () => {
}; };
const webLabels = await createDomainLabels(appName, fullDomain, "web"); const webLabels = await createDomainLabels(appName, fullDomain, "web");
// Order: redirect-to-https, stripprefix, addprefix, then custom middlewares // Web router with HTTPS should only redirect
expect(webLabels).toContain( expect(webLabels).toContain(
"traefik.http.routers.test-app-1-web.middlewares=redirect-to-https@file,stripprefix-test-app-1,addprefix-test-app-1,auth@file,rate-limit@file", "traefik.http.routers.test-app-1-web.middlewares=redirect-to-https@file",
); );
// Middleware definitions should still be present (Traefik needs them registered)
expect(webLabels).toContain(
"traefik.http.middlewares.stripprefix-test-app-1.stripprefix.prefixes=/api",
);
expect(webLabels).toContain(
"traefik.http.middlewares.addprefix-test-app-1.addprefix.prefix=/hello",
);
// But they should NOT be attached to the router
expect(webLabels).not.toContain("stripprefix-test-app-1,");
expect(webLabels).not.toContain("auth@file");
expect(webLabels).not.toContain("rate-limit@file");
}); });
it("should include custom middlewares on websecure entrypoint", async () => { it("should include custom middlewares on websecure entrypoint", async () => {
@@ -332,6 +344,22 @@ describe("createDomainLabels", () => {
expect(websecureLabels).not.toContain("redirect-to-https"); expect(websecureLabels).not.toContain("redirect-to-https");
}); });
it("should NOT include custom middlewares on web router when HTTPS is enabled (only redirect)", async () => {
const domain = {
...baseDomain,
https: true,
middlewares: ["rate-limit@file", "auth@file"],
};
const webLabels = await createDomainLabels(appName, domain, "web");
// Web router with HTTPS should ONLY have redirect, not custom middlewares
expect(webLabels).toContain(
"traefik.http.routers.test-app-1-web.middlewares=redirect-to-https@file",
);
expect(webLabels).not.toContain("rate-limit@file");
expect(webLabels).not.toContain("auth@file");
});
it("should create basic labels for custom entrypoint", async () => { it("should create basic labels for custom entrypoint", async () => {
const labels = await createDomainLabels( const labels = await createDomainLabels(
appName, appName,
@@ -290,6 +290,9 @@ export const AddDomain = ({ id, type, domainId = "", children }: Props) => {
composeId: id, composeId: id,
}), }),
...data, ...data,
customEntrypoint: data.useCustomEntrypoint
? data.customEntrypoint
: null,
}) })
.then(async () => { .then(async () => {
toast.success(dictionary.success); toast.success(dictionary.success);
@@ -674,7 +677,12 @@ export const AddDomain = ({ id, type, domainId = "", children }: Props) => {
<FormControl> <FormControl>
<Switch <Switch
checked={field.value} checked={field.value}
onCheckedChange={field.onChange} onCheckedChange={(checked) => {
field.onChange(checked);
if (!checked) {
form.setValue("customEntrypoint", undefined);
}
}}
/> />
</FormControl> </FormControl>
</FormItem> </FormItem>
+14 -8
View File
@@ -279,38 +279,44 @@ export const createDomainLabels = (
// Collect middlewares for this router // Collect middlewares for this router
const middlewares: string[] = []; const middlewares: string[] = [];
const isRedirectRouter = entrypoint === "web" && https && !customEntrypoint;
// Add HTTPS redirect for web entrypoint (must be first) // Web router with HTTPS only needs redirect — all other middlewares
if (entrypoint === "web" && https) { // run on the websecure router where the request actually lands.
if (isRedirectRouter) {
middlewares.push("redirect-to-https@file"); middlewares.push("redirect-to-https@file");
} }
// Add stripPath middleware if needed // Add stripPath middleware if needed
if (stripPath && path && path !== "/") { if (stripPath && path && path !== "/") {
const middlewareName = `stripprefix-${appName}-${uniqueConfigKey}`; const middlewareName = `stripprefix-${appName}-${uniqueConfigKey}`;
// Only define middleware once (on web entrypoint) // Define middleware on web (or custom) entrypoint so Traefik registers it
if (entrypoint === "web" || customEntrypoint) { if (entrypoint === "web" || customEntrypoint) {
labels.push( labels.push(
`traefik.http.middlewares.${middlewareName}.stripprefix.prefixes=${path}`, `traefik.http.middlewares.${middlewareName}.stripprefix.prefixes=${path}`,
); );
} }
middlewares.push(middlewareName); if (!isRedirectRouter) {
middlewares.push(middlewareName);
}
} }
// Add internalPath middleware if needed // Add internalPath middleware if needed
if (internalPath && internalPath !== "/" && internalPath.startsWith("/")) { if (internalPath && internalPath !== "/" && internalPath.startsWith("/")) {
const middlewareName = `addprefix-${appName}-${uniqueConfigKey}`; const middlewareName = `addprefix-${appName}-${uniqueConfigKey}`;
// Only define middleware once (on web entrypoint) // Define middleware on web (or custom) entrypoint so Traefik registers it
if (entrypoint === "web" || customEntrypoint) { if (entrypoint === "web" || customEntrypoint) {
labels.push( labels.push(
`traefik.http.middlewares.${middlewareName}.addprefix.prefix=${internalPath}`, `traefik.http.middlewares.${middlewareName}.addprefix.prefix=${internalPath}`,
); );
} }
middlewares.push(middlewareName); if (!isRedirectRouter) {
middlewares.push(middlewareName);
}
} }
// Add custom middlewares // Add custom middlewares (skip for redirect-only router)
if (domain.middlewares?.length) { if (!isRedirectRouter && domain.middlewares?.length) {
middlewares.push(...domain.middlewares); middlewares.push(...domain.middlewares);
} }
+15 -13
View File
@@ -143,22 +143,24 @@ export const createRouterConfig = async (
entryPoints: [entryPoint], entryPoints: [entryPoint],
}; };
// Add path rewriting middleware if needed const isRedirectRouter = entryPoint === "web" && https && !customEntrypoint;
if (internalPath && internalPath !== "/" && internalPath !== path) {
const pathMiddleware = `addprefix-${appName}-${uniqueConfigKey}`;
routerConfig.middlewares?.push(pathMiddleware);
}
if (stripPath && path && path !== "/") { // Web router with HTTPS only needs redirect — all other middlewares
const stripMiddleware = `stripprefix-${appName}-${uniqueConfigKey}`; // run on the websecure router where the request actually lands.
routerConfig.middlewares?.push(stripMiddleware); if (isRedirectRouter) {
} routerConfig.middlewares?.push("redirect-to-https");
} else {
// Add path rewriting middleware if needed
if (internalPath && internalPath !== "/" && internalPath !== path) {
const pathMiddleware = `addprefix-${appName}-${uniqueConfigKey}`;
routerConfig.middlewares?.push(pathMiddleware);
}
if (entryPoint === "web" && https) { if (stripPath && path && path !== "/") {
routerConfig.middlewares?.unshift("redirect-to-https"); const stripMiddleware = `stripprefix-${appName}-${uniqueConfigKey}`;
} routerConfig.middlewares?.push(stripMiddleware);
}
if ((entryPoint === "websecure" && https) || !https) {
// redirects - skip for preview deployments as wildcard subdomains // redirects - skip for preview deployments as wildcard subdomains
// should not inherit parent redirect rules (e.g., www-redirect) // should not inherit parent redirect rules (e.g., www-redirect)
if (domain.domainType !== "preview") { if (domain.domainType !== "preview") {