mirror of
https://github.com/netbirdio/dashboard.git
synced 2026-01-26 01:21:04 +00:00
Add custom dns domain (#458)
* Update domain validator * Add custom dns domain
This commit is contained in:
@@ -14,5 +14,6 @@ export interface Account {
|
|||||||
jwt_allow_groups: string[];
|
jwt_allow_groups: string[];
|
||||||
regular_users_view_blocked: boolean;
|
regular_users_view_blocked: boolean;
|
||||||
routing_peer_dns_resolution_enabled: boolean;
|
routing_peer_dns_resolution_enabled: boolean;
|
||||||
|
dns_domain: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,18 @@
|
|||||||
import Breadcrumbs from "@components/Breadcrumbs";
|
import Breadcrumbs from "@components/Breadcrumbs";
|
||||||
|
import Button from "@components/Button";
|
||||||
import FancyToggleSwitch from "@components/FancyToggleSwitch";
|
import FancyToggleSwitch from "@components/FancyToggleSwitch";
|
||||||
|
import HelpText from "@components/HelpText";
|
||||||
|
import InlineLink from "@components/InlineLink";
|
||||||
|
import { Input } from "@components/Input";
|
||||||
|
import { Label } from "@components/Label";
|
||||||
import { notify } from "@components/Notification";
|
import { notify } from "@components/Notification";
|
||||||
|
import { useHasChanges } from "@hooks/useHasChanges";
|
||||||
import * as Tabs from "@radix-ui/react-tabs";
|
import * as Tabs from "@radix-ui/react-tabs";
|
||||||
import { useApiCall } from "@utils/api";
|
import { useApiCall } from "@utils/api";
|
||||||
import { GlobeIcon, NetworkIcon } from "lucide-react";
|
import { validator } from "@utils/helpers";
|
||||||
import React, { useState } from "react";
|
import { isNetBirdHosted } from "@utils/netbird";
|
||||||
|
import { ExternalLinkIcon, GlobeIcon, NetworkIcon } from "lucide-react";
|
||||||
|
import React, { useMemo, useState } from "react";
|
||||||
import { useSWRConfig } from "swr";
|
import { useSWRConfig } from "swr";
|
||||||
import SettingsIcon from "@/assets/icons/SettingsIcon";
|
import SettingsIcon from "@/assets/icons/SettingsIcon";
|
||||||
import { Account } from "@/interfaces/Account";
|
import { Account } from "@/interfaces/Account";
|
||||||
@@ -13,18 +21,23 @@ type Props = {
|
|||||||
account: Account;
|
account: Account;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function NetworkSettingsTab({ account }: Props) {
|
export default function NetworkSettingsTab({ account }: Readonly<Props>) {
|
||||||
const { mutate } = useSWRConfig();
|
const { mutate } = useSWRConfig();
|
||||||
const saveRequest = useApiCall<Account>("/accounts/" + account.id);
|
const saveRequest = useApiCall<Account>("/accounts/" + account.id, true);
|
||||||
|
|
||||||
const [routingPeerDNSSetting, setRoutingPeerDNSSetting] = useState(
|
const [routingPeerDNSSetting, setRoutingPeerDNSSetting] = useState(
|
||||||
account.settings.routing_peer_dns_resolution_enabled,
|
account.settings.routing_peer_dns_resolution_enabled,
|
||||||
);
|
);
|
||||||
|
const [customDNSDomain, setCustomDNSDomain] = useState(
|
||||||
|
account.settings.dns_domain || "",
|
||||||
|
);
|
||||||
|
|
||||||
const toggleSetting = async (toggle: boolean) => {
|
const toggleNetworkDNSSetting = async (toggle: boolean) => {
|
||||||
notify({
|
notify({
|
||||||
title: "Save Network Settings",
|
title: "DNS Wildcard Routing",
|
||||||
description: "Network settings successfully saved.",
|
description: `DNS Wildcard Routing successfully ${
|
||||||
|
toggle ? "enabled" : "disabled"
|
||||||
|
}.`,
|
||||||
promise: saveRequest
|
promise: saveRequest
|
||||||
.put({
|
.put({
|
||||||
id: account.id,
|
id: account.id,
|
||||||
@@ -37,10 +50,43 @@ export default function NetworkSettingsTab({ account }: Props) {
|
|||||||
setRoutingPeerDNSSetting(toggle);
|
setRoutingPeerDNSSetting(toggle);
|
||||||
mutate("/accounts");
|
mutate("/accounts");
|
||||||
}),
|
}),
|
||||||
loadingMessage: "Saving the network settings...",
|
loadingMessage: "Updating DNS wildcard setting...",
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const { hasChanges, updateRef } = useHasChanges([customDNSDomain]);
|
||||||
|
|
||||||
|
const saveChanges = async () => {
|
||||||
|
notify({
|
||||||
|
title: "Custom DNS Domain",
|
||||||
|
description: `Custom DNS Domain successfully updated.`,
|
||||||
|
promise: saveRequest
|
||||||
|
.put({
|
||||||
|
id: account.id,
|
||||||
|
settings: {
|
||||||
|
...account.settings,
|
||||||
|
dns_domain: customDNSDomain || "",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
mutate("/accounts");
|
||||||
|
updateRef([customDNSDomain]);
|
||||||
|
}),
|
||||||
|
loadingMessage: "Updating Custom DNS domain...",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const domainError = useMemo(() => {
|
||||||
|
if (customDNSDomain == "") return "";
|
||||||
|
const valid = validator.isValidDomain(customDNSDomain, {
|
||||||
|
allowWildcard: false,
|
||||||
|
allowOnlyTld: false,
|
||||||
|
});
|
||||||
|
if (!valid) {
|
||||||
|
return "Please enter a valid domain, e.g. example.com or intra.example.com";
|
||||||
|
}
|
||||||
|
}, [customDNSDomain]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tabs.Content value={"networks"}>
|
<Tabs.Content value={"networks"}>
|
||||||
<div className={"p-default py-6 max-w-2xl"}>
|
<div className={"p-default py-6 max-w-2xl"}>
|
||||||
@@ -51,36 +97,80 @@ export default function NetworkSettingsTab({ account }: Props) {
|
|||||||
icon={<SettingsIcon size={13} />}
|
icon={<SettingsIcon size={13} />}
|
||||||
/>
|
/>
|
||||||
<Breadcrumbs.Item
|
<Breadcrumbs.Item
|
||||||
href={"/settings#network"}
|
href={"/settings?tab=networks"}
|
||||||
label={"Network"}
|
label={"Networks"}
|
||||||
icon={<NetworkIcon size={14} />}
|
icon={<NetworkIcon size={14} />}
|
||||||
active
|
active
|
||||||
/>
|
/>
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
<div className={"flex items-start justify-between"}>
|
<div className={"flex items-start justify-between"}>
|
||||||
<h1>Networks</h1>
|
<div>
|
||||||
|
<h1>Networks</h1>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant={"primary"}
|
||||||
|
disabled={!hasChanges}
|
||||||
|
onClick={saveChanges}
|
||||||
|
>
|
||||||
|
Save Changes
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={"flex flex-col gap-6 w-full mt-8"}>
|
<div className={"flex flex-col gap-6 w-full mt-8"}>
|
||||||
<div>
|
<div>
|
||||||
<FancyToggleSwitch
|
<div
|
||||||
value={routingPeerDNSSetting}
|
className={
|
||||||
onChange={toggleSetting}
|
"flex flex-col gap-1 sm:flex-row w-full sm:gap-4 items-center"
|
||||||
label={
|
|
||||||
<>
|
|
||||||
<GlobeIcon size={15} />
|
|
||||||
Enable DNS Wildcard Routing
|
|
||||||
</>
|
|
||||||
}
|
}
|
||||||
helpText={
|
>
|
||||||
<>
|
<div className={"min-w-[330px]"}>
|
||||||
Allow routing using DNS wildcards. This requires NetBird
|
<Label>DNS Domain</Label>
|
||||||
client v0.35 or higher. Changes will only take effect after
|
<HelpText>
|
||||||
restarting the clients.
|
Specify a custom DNS domain for your network. This will be
|
||||||
</>
|
used for all your peers.
|
||||||
}
|
</HelpText>
|
||||||
/>
|
</div>
|
||||||
|
<div className={"w-full"}>
|
||||||
|
<Input
|
||||||
|
placeholder={
|
||||||
|
isNetBirdHosted() ? "netbird.cloud" : "netbird.selfhosted"
|
||||||
|
}
|
||||||
|
errorTooltip={true}
|
||||||
|
errorTooltipPosition={"top"}
|
||||||
|
error={domainError}
|
||||||
|
value={customDNSDomain}
|
||||||
|
onChange={(e) => setCustomDNSDomain(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<FancyToggleSwitch
|
||||||
|
value={routingPeerDNSSetting}
|
||||||
|
onChange={toggleNetworkDNSSetting}
|
||||||
|
label={
|
||||||
|
<>
|
||||||
|
<GlobeIcon size={15} />
|
||||||
|
Enable DNS Wildcard Routing
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
helpText={
|
||||||
|
<>
|
||||||
|
Allow routing using DNS wildcards. This requires NetBird client
|
||||||
|
v0.35 or higher. Changes will only take effect after restarting
|
||||||
|
the clients.{" "}
|
||||||
|
<InlineLink
|
||||||
|
href={
|
||||||
|
"https://docs.netbird.io/how-to/accessing-entire-domains-within-networks#enabling-dns-wildcard-routing"
|
||||||
|
}
|
||||||
|
target={"_blank"}
|
||||||
|
>
|
||||||
|
Learn more
|
||||||
|
<ExternalLinkIcon size={12} />
|
||||||
|
</InlineLink>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Tabs.Content>
|
</Tabs.Content>
|
||||||
|
|||||||
Reference in New Issue
Block a user