mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-14 00:46:39 +00:00
Headers input working on resource
This commit is contained in:
@@ -129,6 +129,40 @@ export function isValidDomain(domain: string): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
export function validateHeaders(headers: string): boolean {
|
||||
// Validate comma-separated headers in format "Header-Name: value"
|
||||
const headerPairs = headers.split(",").map((pair) => pair.trim());
|
||||
return headerPairs.every((pair) => {
|
||||
// Check if the pair contains exactly one colon
|
||||
const colonCount = (pair.match(/:/g) || []).length;
|
||||
if (colonCount !== 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const colonIndex = pair.indexOf(":");
|
||||
if (colonIndex === 0 || colonIndex === pair.length - 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const headerName = pair.substring(0, colonIndex).trim();
|
||||
const headerValue = pair.substring(colonIndex + 1).trim();
|
||||
|
||||
// Header name should not be empty and should contain valid characters
|
||||
// Header names are case-insensitive and can contain alphanumeric, hyphens
|
||||
const headerNameRegex = /^[a-zA-Z0-9\-_]+$/;
|
||||
if (!headerName || !headerNameRegex.test(headerName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Header value should not be empty and should not contain colons
|
||||
if (!headerValue || headerValue.includes(":")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
const validTlds = [
|
||||
"AAA",
|
||||
"AARP",
|
||||
|
||||
@@ -21,6 +21,7 @@ import { subdomainSchema } from "@server/lib/schemas";
|
||||
import { registry } from "@server/openApi";
|
||||
import { OpenAPITags } from "@server/openApi";
|
||||
import { validateAndConstructDomain } from "@server/lib/domainUtils";
|
||||
import { validateHeaders } from "@server/lib/validators";
|
||||
|
||||
const updateResourceParamsSchema = z
|
||||
.object({
|
||||
@@ -45,7 +46,8 @@ const updateHttpResourceBodySchema = z
|
||||
stickySession: z.boolean().optional(),
|
||||
tlsServerName: z.string().nullable().optional(),
|
||||
setHostHeader: z.string().nullable().optional(),
|
||||
skipToIdpId: z.number().int().positive().nullable().optional()
|
||||
skipToIdpId: z.number().int().positive().nullable().optional(),
|
||||
headers: z.string().nullable().optional()
|
||||
})
|
||||
.strict()
|
||||
.refine((data) => Object.keys(data).length > 0, {
|
||||
@@ -83,6 +85,18 @@ const updateHttpResourceBodySchema = z
|
||||
message:
|
||||
"Invalid custom Host Header value. Use domain name format, or save empty to unset custom Host Header."
|
||||
}
|
||||
)
|
||||
.refine(
|
||||
(data) => {
|
||||
if (data.headers) {
|
||||
return validateHeaders(data.headers)
|
||||
}
|
||||
return true;
|
||||
},
|
||||
{
|
||||
message:
|
||||
"Invalid headers format. Use comma-separated format: 'Header-Name: value, Another-Header: another-value'. Header values cannot contain colons."
|
||||
}
|
||||
);
|
||||
|
||||
export type UpdateResourceResponse = Resource;
|
||||
|
||||
Reference in New Issue
Block a user