fix: address CodeQL and code quality review comments

Replace polynomial trailing-slash regex with removeTrailingSlash helper
and remove unused ModalFormFooter import in quick-add-app modal.
This commit is contained in:
Thomas Camlong committed 2026-05-29 14:54:39 +02:00
1 parent 28f31243fb
commit 1c9a63d9ef
5 files changed
+13 -6

No files matched your search

+5 -1
View File
@@ -1,7 +1,11 @@
import type { ReadonlyHeaders } from "next/dist/server/web/spec-extension/adapters/headers";
export const removeTrailingSlash = (path: string) => {
return path.at(-1) === "/" ? path.substring(0, path.length - 1) : path;
let end = path.length;
while (end > 0 && path.charAt(end - 1) === "/") {
end--;
}
return path.slice(0, end);
};
export const extractBaseUrlFromHeaders = (
@@ -1,3 +1,5 @@
import { removeTrailingSlash } from "@homarr/common";
import { integrationIconSlugs } from "./docker-integration-match";
import type { IntegrationKind } from "./integration";
import { getIntegrationDefaultPort } from "./integration";
@@ -20,7 +22,7 @@ export const buildIntegrationUrl = (
mode: UrlTemplateMode,
dockerPort?: number,
): string => {
const host = baseHost.trim().replace(/\/+$/, "");
const host = removeTrailingSlash(baseHost.trim());
if (!host) return "";
const port = dockerPort ?? getIntegrationDefaultPort(kind);
return buildUrl(getSlugForKind(kind), host, mode, port ?? undefined);
@@ -32,7 +34,7 @@ export const buildAppUrl = (
mode: UrlTemplateMode,
dockerPort?: number,
): string => {
const host = baseHost.trim().replace(/\/+$/, "");
const host = removeTrailingSlash(baseHost.trim());
if (!host) return "";
const slug = containerName.toLowerCase().replace(/[^a-z0-9-]/g, "-");
return buildUrl(slug, host, mode, dockerPort);
+2 -2
View File
@@ -1,4 +1,4 @@
import { objectKeys } from "@homarr/common";
import { objectKeys, removeTrailingSlash } from "@homarr/common";
import type { AtLeastOneOf } from "@homarr/common/types";
import { createDocumentationLink } from "./docs";
@@ -475,7 +475,7 @@ export const getIntegrationDefaultPort = (kind: IntegrationKind): number | undef
export const getIntegrationApiKeyUrl = (integrationUrl: string, kind: IntegrationKind): string | null => {
const definition = integrationDefs[kind];
if (!("apiKeySettingsPath" in definition)) return null;
const base = integrationUrl.replace(/\/+$/, "");
const base = removeTrailingSlash(integrationUrl);
if (!base) return null;
return `${base}${definition.apiKeySettingsPath}`;
};
@@ -22,6 +22,7 @@ describe("buildIntegrationUrl", () => {
it("strips trailing slashes from host", () => {
expect(buildIntegrationUrl("sonarr", "homelab.local/", "subdomain")).toBe("https://sonarr.homelab.local");
expect(buildIntegrationUrl("sonarr", "homelab.local///", "subdomain")).toBe("https://sonarr.homelab.local");
});
it("returns empty string for empty host", () => {
@@ -3,7 +3,7 @@ import type { z } from "zod/v4";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import { AppForm } from "@homarr/forms-collection";
import { createModal, ModalFormFooter, modalSizeForm } from "@homarr/modals";
import { createModal, modalSizeForm } from "@homarr/modals";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n, useScopedI18n } from "@homarr/translation/client";
import type { appManageSchema } from "@homarr/validation/app";