finish redirect traefik config

This commit is contained in:
Fred KISSIE
2026-09-17 21:32:55 +02:00
parent c51bcbb578
commit ec36317057
13 changed files with 243 additions and 80 deletions
+7 -2
View File
@@ -14,6 +14,7 @@ import {
redirectMatchPathSchema,
redirectPathMatchTypeSchema,
redirectRewritePathSchema,
isValidMatchPath,
redirectRewritePathTypeSchema
} from "@server/routers/redirect/validation";
import { getUniqueRedirectName } from "@server/db/names";
@@ -35,7 +36,7 @@ const bodySchema = z
subdomain: z.string().nonempty().optional().nullable(),
destinationDomain: redirectDestinationDomainSchema,
pathMatchType: redirectPathMatchTypeSchema.optional(),
matchPath: redirectMatchPathSchema,
matchPath: redirectMatchPathSchema.optional().nullable(),
rewritePath: redirectRewritePathSchema.optional().nullable(),
rewritePathType: redirectRewritePathTypeSchema.optional().nullable(),
permanent: z.boolean().optional(),
@@ -57,6 +58,10 @@ const bodySchema = z
.refine((data) => Boolean(data.resourceId) !== Boolean(data.domainId), {
message: "Exactly one of resourceId or domainId must be provided",
path: ["resourceId"]
})
.refine((data) => isValidMatchPath(data.matchPath, data.pathMatchType), {
message: "matchPath must be a valid regular expression",
path: ["matchPath"]
});
registry.registerPath({
@@ -187,7 +192,7 @@ export async function createRedirect(
subdomain: subdomain ?? null,
destinationDomain,
pathMatchType: pathMatchType ?? "regex",
matchPath,
matchPath: matchPath ?? null,
rewritePath: rewritePath ?? null,
rewritePathType: rewritePathType ?? null,
permanent: permanent ?? false,
+1 -1
View File
@@ -19,7 +19,7 @@ export type GetRedirectResponse = {
subdomain: string | null;
destinationDomain: string;
pathMatchType: "exact" | "prefix" | "regex";
matchPath: string;
matchPath: string | null;
rewritePath: string | null;
rewritePathType: "exact" | "prefix" | "regex" | "stripPrefix" | null;
permanent: boolean;
+1 -1
View File
@@ -19,7 +19,7 @@ export type ListRedirectsResponse = PaginatedResponse<{
subdomain: string | null;
destinationDomain: string;
pathMatchType: "exact" | "prefix" | "regex";
matchPath: string;
matchPath: string | null;
rewritePath: string | null;
rewritePathType: "exact" | "prefix" | "regex" | "stripPrefix" | null;
permanent: boolean;
+19 -2
View File
@@ -15,7 +15,8 @@ import {
redirectMatchPathSchema,
redirectPathMatchTypeSchema,
redirectRewritePathSchema,
redirectRewritePathTypeSchema
redirectRewritePathTypeSchema,
isValidMatchPath
} from "@server/routers/redirect/validation";
import { createCertificate } from "../certificates";
@@ -36,7 +37,7 @@ const bodySchema = z.strictObject({
subdomain: z.string().nonempty().optional().nullable(),
destinationDomain: redirectDestinationDomainSchema.optional(),
pathMatchType: redirectPathMatchTypeSchema.optional(),
matchPath: redirectMatchPathSchema.optional(),
matchPath: redirectMatchPathSchema.optional().nullable(),
rewritePath: redirectRewritePathSchema.optional().nullable(),
rewritePathType: redirectRewritePathTypeSchema.optional().nullable(),
permanent: z.boolean().optional(),
@@ -206,6 +207,22 @@ export async function updateRedirect(
}
}
if (
!isValidMatchPath(
body.matchPath !== undefined
? body.matchPath
: existing.matchPath,
body.pathMatchType ?? existing.pathMatchType
)
) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
"matchPath must be a valid regular expression"
)
);
}
const updateData: Partial<typeof redirects.$inferInsert> = {};
if (body.name !== undefined) {
+23 -1
View File
@@ -19,7 +19,29 @@ export const redirectRewritePathTypeSchema = z.enum([
"stripPrefix"
]);
export const redirectMatchPathSchema = z.string().nonempty().default("*");
export const redirectMatchPathSchema = z.string().nonempty();
export function isValidRegex(pattern: string): boolean {
try {
new RegExp(pattern);
return true;
} catch {
return false;
}
}
/**
* A regex match path is fed straight to `new RegExp` when building routes,
* so reject patterns that would throw there.
*/
export function isValidMatchPath(
matchPath: string | null | undefined,
pathMatchType: string | null | undefined
): boolean {
return (
pathMatchType !== "regex" || !matchPath || isValidRegex(matchPath)
);
}
export const redirectRewritePathSchema = z.string().nonempty();