mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-16 18:06:39 +00:00
Merge pull request #501 from achtnullzwei/customize-tls-server-name
Add option to customise TLS server name in resource settings
This commit is contained in:
@@ -48,7 +48,7 @@ import { useOrgContext } from "@app/hooks/useOrgContext";
|
||||
import CustomDomainInput from "../CustomDomainInput";
|
||||
import { createApiClient } from "@app/lib/api";
|
||||
import { useEnvContext } from "@app/hooks/useEnvContext";
|
||||
import { subdomainSchema } from "@server/lib/schemas";
|
||||
import { subdomainSchema, tlsNameSchema } from "@server/lib/schemas";
|
||||
import { CaretSortIcon, CheckIcon } from "@radix-ui/react-icons";
|
||||
import { RadioGroup, RadioGroupItem } from "@app/components/ui/radio-group";
|
||||
import { Label } from "@app/components/ui/label";
|
||||
@@ -109,8 +109,40 @@ const TransferFormSchema = z.object({
|
||||
siteId: z.number()
|
||||
});
|
||||
|
||||
const AdvancedFormSchema = z
|
||||
.object({
|
||||
http: z.boolean(),
|
||||
tlsServerName: z.string().optional(),
|
||||
setHostHeader: z.string().optional()
|
||||
})
|
||||
.refine(
|
||||
(data) => {
|
||||
if (data.tlsServerName) {
|
||||
return tlsNameSchema.safeParse(data.tlsServerName).success;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
{
|
||||
message: "Invalid TLS Server Name. Use domain name format, or save empty to remove the TLS Server Name.",
|
||||
path: ["tlsServerName"]
|
||||
}
|
||||
)
|
||||
.refine(
|
||||
(data) => {
|
||||
if (data.setHostHeader) {
|
||||
return tlsNameSchema.safeParse(data.setHostHeader).success;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
{
|
||||
message: "Invalid custom Host Header value. Use domain name format, or save empty to unset the custom Host Header",
|
||||
path: ["tlsServerName"]
|
||||
}
|
||||
);
|
||||
|
||||
type GeneralFormValues = z.infer<typeof GeneralFormSchema>;
|
||||
type TransferFormValues = z.infer<typeof TransferFormSchema>;
|
||||
type AdvancedFormValues = z.infer<typeof AdvancedFormSchema>;
|
||||
|
||||
export default function GeneralForm() {
|
||||
const [formKey, setFormKey] = useState(0);
|
||||
@@ -151,6 +183,16 @@ export default function GeneralForm() {
|
||||
mode: "onChange"
|
||||
});
|
||||
|
||||
const advancedForm = useForm<AdvancedFormValues>({
|
||||
resolver: zodResolver(AdvancedFormSchema),
|
||||
defaultValues: {
|
||||
http: resource.http,
|
||||
tlsServerName: resource.http ? resource.tlsServerName || "" : undefined,
|
||||
setHostHeader: resource.http ? resource.setHostHeader || "" : undefined
|
||||
},
|
||||
mode: "onChange"
|
||||
});
|
||||
|
||||
const transferForm = useForm<TransferFormValues>({
|
||||
resolver: zodResolver(TransferFormSchema),
|
||||
defaultValues: {
|
||||
@@ -279,6 +321,46 @@ export default function GeneralForm() {
|
||||
setTransferLoading(false);
|
||||
}
|
||||
|
||||
async function onSubmitAdvanced(data: AdvancedFormValues) {
|
||||
setSaveLoading(true);
|
||||
|
||||
const res = await api
|
||||
.post<AxiosResponse<UpdateResourceResponse>>(
|
||||
`resource/${resource?.resourceId}`,
|
||||
{
|
||||
tlsServerName: data.http ? data.tlsServerName : undefined,
|
||||
setHostHeader: data.http ? data.setHostHeader : undefined
|
||||
}
|
||||
)
|
||||
.catch((e) => {
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "Failed to update resource",
|
||||
description: formatAxiosError(
|
||||
e,
|
||||
"An error occurred while updating the resource"
|
||||
)
|
||||
});
|
||||
});
|
||||
|
||||
if (res && res.status === 200) {
|
||||
toast({
|
||||
title: "Resource updated",
|
||||
description: "The resource has been updated successfully"
|
||||
});
|
||||
|
||||
const resource = res.data.data;
|
||||
|
||||
updateResource({
|
||||
tlsServerName: data.tlsServerName,
|
||||
setHostHeader: data.setHostHeader
|
||||
});
|
||||
|
||||
router.refresh();
|
||||
}
|
||||
setSaveLoading(false);
|
||||
}
|
||||
|
||||
async function toggleResourceEnabled(val: boolean) {
|
||||
const res = await api
|
||||
.post<AxiosResponse<UpdateResourceResponse>>(
|
||||
@@ -601,6 +683,81 @@ export default function GeneralForm() {
|
||||
</SettingsSectionFooter>
|
||||
</SettingsSection>
|
||||
|
||||
{resource.http && (
|
||||
<>
|
||||
<SettingsSection>
|
||||
<SettingsSectionHeader>
|
||||
<SettingsSectionTitle>Advanced</SettingsSectionTitle>
|
||||
<SettingsSectionDescription>
|
||||
Adjust advanced settings for the resource, like customize the Host Header or set a TLS Server Name for SNI based routing.
|
||||
</SettingsSectionDescription>
|
||||
</SettingsSectionHeader>
|
||||
<SettingsSectionBody>
|
||||
<SettingsSectionForm>
|
||||
<Form {...advancedForm}>
|
||||
<form
|
||||
onSubmit={advancedForm.handleSubmit(onSubmitAdvanced)}
|
||||
className="grid grid-cols-1 md:grid-cols-2 gap-4"
|
||||
id="advanced-settings-form"
|
||||
>
|
||||
{/* New TLS Server Name Field */}
|
||||
<div className="w-fill space-y-2">
|
||||
<FormLabel>
|
||||
TLS Server Name (optional)
|
||||
</FormLabel>
|
||||
<FormField
|
||||
control={advancedForm.control}
|
||||
name="tlsServerName"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
{/* New Custom Host Header Field */}
|
||||
<div className="w-fill space-y-2">
|
||||
<FormLabel>
|
||||
Custom Host Header (optional)
|
||||
</FormLabel>
|
||||
<FormField
|
||||
control={advancedForm.control}
|
||||
name="setHostHeader"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
</Form>
|
||||
</SettingsSectionForm>
|
||||
</SettingsSectionBody>
|
||||
|
||||
<SettingsSectionFooter>
|
||||
<Button
|
||||
type="submit"
|
||||
loading={saveLoading}
|
||||
disabled={saveLoading}
|
||||
form="advanced-settings-form"
|
||||
>
|
||||
Save Advanced Settings
|
||||
</Button>
|
||||
</SettingsSectionFooter>
|
||||
</SettingsSection>
|
||||
</>
|
||||
)}
|
||||
<SettingsSection>
|
||||
<SettingsSectionHeader>
|
||||
<SettingsSectionTitle>
|
||||
|
||||
Reference in New Issue
Block a user