Compare commits

..

2 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
baf45c47eb Tidy SSH defaults formatting 2026-06-16 23:56:01 +00:00
copilot-swe-agent[bot]
76d0b5753a Restrict public browser gateway defaults to newt targets 2026-06-16 23:53:23 +00:00
6 changed files with 24 additions and 70 deletions

View File

@@ -1,7 +1,4 @@
import {
getResourceRuleValueValidationError,
isValidUrlGlobPattern
} from "./validators";
import { isValidUrlGlobPattern } from "./validators";
import { assertEquals } from "@test/assert";
function runTests() {
@@ -239,43 +236,6 @@ function runTests() {
"Path with isolated percent sign should be invalid"
);
// ASN validation tests
assertEquals(
getResourceRuleValueValidationError("ASN", "AS15169"),
null,
"Standard ASN should be valid"
);
assertEquals(
getResourceRuleValueValidationError("ASN", " As15169 "),
null,
"Standard ASN should be valid with mixed case and whitespace"
);
assertEquals(
getResourceRuleValueValidationError("ASN", "ALL"),
null,
"ALL ASN selector should be valid"
);
assertEquals(
getResourceRuleValueValidationError("ASN", " all "),
null,
"ALL ASN selector should be valid with mixed case and whitespace"
);
assertEquals(
getResourceRuleValueValidationError("ASN", "AS0"),
null,
"AS0 alias should be valid"
);
assertEquals(
getResourceRuleValueValidationError("ASN", " as0 "),
null,
"AS0 alias should be valid with mixed case and whitespace"
);
assertEquals(
getResourceRuleValueValidationError("ASN", "not-an-asn"),
"Invalid ASN provided",
"Invalid ASN should return an error"
);
console.log("All tests passed!");
}

View File

@@ -100,10 +100,7 @@ export function getResourceRuleValueValidationError(
? null
: "Invalid country code provided";
case "ASN":
const normalizedValue = value.trim().toUpperCase();
return /^AS\d+$/.test(normalizedValue) ||
normalizedValue === "ALL" ||
normalizedValue === "AS0"
return /^AS\d+$/i.test(value.trim())
? null
: "Invalid ASN provided";
default:

View File

@@ -40,6 +40,7 @@ type TargetRow = {
targetId: number;
resourceId: number;
siteId: number;
siteType: string | null;
siteName?: string;
mode: string | null;
ip: string;
@@ -105,7 +106,8 @@ function RdpServerForm({
const api = createApiClient(useEnvContext());
const router = useRouter();
const targets = targetsResponse.targets.filter((t) => t.mode === "rdp");
const firstTarget = targets[0];
const browserGatewayTargets = targets.filter((t) => t.siteType === "newt");
const firstTarget = browserGatewayTargets[0];
const formSchema = useMemo(
() => createBrowserGatewayTargetFormSchema(t),
@@ -115,7 +117,7 @@ function RdpServerForm({
const form = useForm<BrowserGatewayTargetFormValues>({
resolver: zodResolver(formSchema),
defaultValues: {
selectedSites: targets.map((target) => ({
selectedSites: browserGatewayTargets.map((target) => ({
siteId: target.siteId,
name: target.siteName ?? String(target.siteId),
type: "newt" as const

View File

@@ -62,6 +62,7 @@ type TargetRow = {
targetId: number;
resourceId: number;
siteId: number;
siteType: string | null;
siteName?: string;
mode: string | null;
ip: string;
@@ -130,7 +131,9 @@ function SshServerForm({
const isNativeInitially = resource.authDaemonMode === "native";
const targets = targetsResponse.targets.filter((t) => t.mode === "ssh");
const browserGatewayTargets = targets.filter((t) => t.siteType === "newt");
const firstTarget = targets[0];
const firstBrowserGatewayTarget = browserGatewayTargets[0];
const initialPamMode =
(resource.pamMode as "passthrough" | "push") || "passthrough";
const initialStandardDaemonLocation = isNativeInitially
@@ -163,18 +166,18 @@ function SshServerForm({
selectedSites:
isNativeInitially || useSingleSiteOnLoad
? []
: targets.map((target) => ({
: browserGatewayTargets.map((target) => ({
siteId: target.siteId,
name: target.siteName ?? String(target.siteId),
type: "newt" as const
})),
selectedSite:
useSingleSiteOnLoad && firstTarget
useSingleSiteOnLoad && firstBrowserGatewayTarget
? {
siteId: firstTarget.siteId,
siteId: firstBrowserGatewayTarget.siteId,
name:
firstTarget.siteName ??
String(firstTarget.siteId),
firstBrowserGatewayTarget.siteName ??
String(firstBrowserGatewayTarget.siteId),
type: "newt" as const
}
: null,
@@ -190,11 +193,11 @@ function SshServerForm({
: null,
destination: isNativeInitially
? ""
: (firstTarget?.ip ?? ""),
: (firstBrowserGatewayTarget?.ip ?? ""),
destinationPort: isNativeInitially
? "22"
: firstTarget
? String(firstTarget.port)
: firstBrowserGatewayTarget
? String(firstBrowserGatewayTarget.port)
: "22"
}
});

View File

@@ -40,6 +40,7 @@ type TargetRow = {
targetId: number;
resourceId: number;
siteId: number;
siteType: string | null;
siteName?: string;
mode: string | null;
ip: string;
@@ -105,7 +106,8 @@ function VncServerForm({
const api = createApiClient(useEnvContext());
const router = useRouter();
const targets = targetsResponse.targets.filter((t) => t.mode === "vnc");
const firstTarget = targets[0];
const browserGatewayTargets = targets.filter((t) => t.siteType === "newt");
const firstTarget = browserGatewayTargets[0];
const formSchema = useMemo(
() => createBrowserGatewayTargetFormSchema(t),
@@ -115,7 +117,7 @@ function VncServerForm({
const form = useForm<BrowserGatewayTargetFormValues>({
resolver: zodResolver(formSchema),
defaultValues: {
selectedSites: targets.map((target) => ({
selectedSites: browserGatewayTargets.map((target) => ({
siteId: target.siteId,
name: target.siteName ?? String(target.siteId),
type: "newt" as const

View File

@@ -83,19 +83,9 @@ export function createPolicyRuleValueSchema(t: TranslateFn, match: string) {
{ message: t("rulesErrorInvalidCountryDescription") }
);
case "ASN":
return required.refine(
(value) => {
const normalizedValue = value.trim().toUpperCase();
return (
/^AS\d+$/.test(normalizedValue) ||
normalizedValue === "ALL" ||
normalizedValue === "AS0"
);
},
{
message: t("rulesErrorInvalidAsnDescription")
}
);
return required.refine((value) => /^AS\d+$/i.test(value.trim()), {
message: t("rulesErrorInvalidAsnDescription")
});
default:
return required;
}