Update libraries to resolve critical security findings

This commit is contained in:
grokdesigns
2025-04-08 12:51:06 -07:00
parent 787a172a7c
commit 7fd1652a71
5 changed files with 1061 additions and 1513 deletions

View File

@@ -62,13 +62,11 @@ const createSiteFormSchema = z
.object({
name: z
.string()
.min(2, {
message: "Name must be at least 2 characters."
})
.min(2, { message: "Name must be at least 2 characters." })
.max(30, {
message: "Name must not be longer than 30 characters."
}),
method: z.string(),
method: z.enum(["newt", "wireguard", "local"]),
copied: z.boolean()
})
.refine(
@@ -86,6 +84,15 @@ const createSiteFormSchema = z
type CreateSiteFormValues = z.infer<typeof createSiteFormSchema>;
type SiteType = "newt" | "wireguard" | "local";
interface TunnelTypeOption {
id: SiteType;
title: string;
description: string;
disabled?: boolean;
}
type Commands = {
mac: Record<string, string[]>;
linux: Record<string, string[]>;
@@ -99,7 +106,9 @@ export default function Page() {
const { orgId } = useParams();
const router = useRouter();
const [tunnelTypes, setTunnelTypes] = useState<any>([
const [tunnelTypes, setTunnelTypes] = useState<
ReadonlyArray<TunnelTypeOption>
>([
{
id: "newt",
title: "Newt Tunnel (Recommended)",
@@ -310,22 +319,15 @@ PersistentKeepalive = 5`;
}
};
const form = useForm({
const form = useForm<CreateSiteFormValues>({
resolver: zodResolver(createSiteFormSchema),
defaultValues: {
name: "",
copied: false,
method: "newt"
}
defaultValues: { name: "", copied: false, method: "newt" }
});
async function onSubmit(data: CreateSiteFormValues) {
setCreateLoading(true);
let payload: CreateSiteBody = {
name: data.name,
type: data.method
};
let payload: CreateSiteBody = { name: data.name, type: data.method };
if (data.method == "wireguard") {
if (!siteDefaults || !wgConfig) {
@@ -454,10 +456,7 @@ PersistentKeepalive = 5`;
setTunnelTypes((prev: any) => {
return prev.map((item: any) => {
return {
...item,
disabled: false
};
return { ...item, disabled: false };
});
});
}
@@ -532,9 +531,8 @@ PersistentKeepalive = 5`;
</FormControl>
<FormMessage />
<FormDescription>
This is the
display name for the
site.
This is the display
name for the site.
</FormDescription>
</FormItem>
)}
@@ -558,12 +556,10 @@ PersistentKeepalive = 5`;
<SettingsSectionBody>
<StrategySelect
options={tunnelTypes}
defaultValue={
form.getValues("method") as string
}
onChange={(value) =>
form.setValue("method", value)
}
defaultValue={form.getValues("method")}
onChange={(value) => {
form.setValue("method", value);
}}
cols={3}
/>
</SettingsSectionBody>

View File

@@ -38,7 +38,7 @@ export default function SupporterMessage({ tier }: { tier: string }) {
<path d="M12 .587l3.668 7.431 8.2 1.192-5.934 5.782 1.4 8.168L12 18.896l-7.334 3.864 1.4-8.168L.132 9.21l8.2-1.192z" />
</svg>
{/* Popover */}
<div className="absolute left-1/2 transform -translate-x-1/2 -top-10 hidden group-hover:block bg-white/10 backdrop-blur-md text-primary text-sm rounded-md shadow-lg px-4 py-2">
<div className="absolute left-1/2 transform -translate-x-1/2 -top-10 hidden group-hover:block bg-white/10 text-primary text-sm rounded-md shadow-lg px-4 py-2 pointer-events-none opacity-0 group-hover:opacity-100 transition-opacity">
Thank you for supporting Pangolin as a {tier}!
</div>
</div>

View File

@@ -4,38 +4,39 @@ import { cn } from "@app/lib/cn";
import { RadioGroup, RadioGroupItem } from "./ui/radio-group";
import { useState } from "react";
interface StrategyOption {
id: string;
interface StrategyOption<TValue extends string> {
id: TValue;
title: string;
description: string;
disabled?: boolean; // New optional property
disabled?: boolean;
}
interface StrategySelectProps {
options: StrategyOption[];
defaultValue?: string;
onChange?: (value: string) => void;
interface StrategySelectProps<TValue extends string> {
options: ReadonlyArray<StrategyOption<TValue>>;
defaultValue?: TValue;
onChange?: (value: TValue) => void;
cols?: number;
}
export function StrategySelect({
export function StrategySelect<TValue extends string>({
options,
defaultValue,
onChange,
cols
}: StrategySelectProps) {
const [selected, setSelected] = useState(defaultValue);
}: StrategySelectProps<TValue>) {
const [selected, setSelected] = useState<TValue | undefined>(defaultValue);
return (
<RadioGroup
defaultValue={defaultValue}
onValueChange={(value) => {
setSelected(value);
onChange?.(value);
onValueChange={(value: string) => {
const typedValue = value as TValue;
setSelected(typedValue);
onChange?.(typedValue);
}}
className={`grid md:grid-cols-${cols ? cols : 1} gap-4`}
>
{options.map((option) => (
{options.map((option: StrategyOption<TValue>) => (
<label
key={option.id}
htmlFor={option.id}