mirror of
https://github.com/fosrl/pangolin.git
synced 2026-09-19 17:19:58 +02:00
✨ finish redirect traefik config
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user