Skip to content

Commit ebbe865

Browse files
authored
Add custom dns domain (#458)
* Update domain validator * Add custom dns domain
1 parent 6c0ab88 commit ebbe865

File tree

2 files changed

+118
-27
lines changed

2 files changed

+118
-27
lines changed

src/interfaces/Account.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ export interface Account {
1414
jwt_allow_groups: string[];
1515
regular_users_view_blocked: boolean;
1616
routing_peer_dns_resolution_enabled: boolean;
17+
dns_domain: string;
1718
};
1819
}

src/modules/settings/NetworkSettingsTab.tsx

Lines changed: 117 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
11
import Breadcrumbs from "@components/Breadcrumbs";
2+
import Button from "@components/Button";
23
import FancyToggleSwitch from "@components/FancyToggleSwitch";
4+
import HelpText from "@components/HelpText";
5+
import InlineLink from "@components/InlineLink";
6+
import { Input } from "@components/Input";
7+
import { Label } from "@components/Label";
38
import { notify } from "@components/Notification";
9+
import { useHasChanges } from "@hooks/useHasChanges";
410
import * as Tabs from "@radix-ui/react-tabs";
511
import { useApiCall } from "@utils/api";
6-
import { GlobeIcon, NetworkIcon } from "lucide-react";
7-
import React, { useState } from "react";
12+
import { validator } from "@utils/helpers";
13+
import { isNetBirdHosted } from "@utils/netbird";
14+
import { ExternalLinkIcon, GlobeIcon, NetworkIcon } from "lucide-react";
15+
import React, { useMemo, useState } from "react";
816
import { useSWRConfig } from "swr";
917
import SettingsIcon from "@/assets/icons/SettingsIcon";
1018
import { Account } from "@/interfaces/Account";
@@ -13,18 +21,23 @@ type Props = {
1321
account: Account;
1422
};
1523

16-
export default function NetworkSettingsTab({ account }: Props) {
24+
export default function NetworkSettingsTab({ account }: Readonly<Props>) {
1725
const { mutate } = useSWRConfig();
18-
const saveRequest = useApiCall<Account>("/accounts/" + account.id);
26+
const saveRequest = useApiCall<Account>("/accounts/" + account.id, true);
1927

2028
const [routingPeerDNSSetting, setRoutingPeerDNSSetting] = useState(
2129
account.settings.routing_peer_dns_resolution_enabled,
2230
);
31+
const [customDNSDomain, setCustomDNSDomain] = useState(
32+
account.settings.dns_domain || "",
33+
);
2334

24-
const toggleSetting = async (toggle: boolean) => {
35+
const toggleNetworkDNSSetting = async (toggle: boolean) => {
2536
notify({
26-
title: "Save Network Settings",
27-
description: "Network settings successfully saved.",
37+
title: "DNS Wildcard Routing",
38+
description: `DNS Wildcard Routing successfully ${
39+
toggle ? "enabled" : "disabled"
40+
}.`,
2841
promise: saveRequest
2942
.put({
3043
id: account.id,
@@ -37,10 +50,43 @@ export default function NetworkSettingsTab({ account }: Props) {
3750
setRoutingPeerDNSSetting(toggle);
3851
mutate("/accounts");
3952
}),
40-
loadingMessage: "Saving the network settings...",
53+
loadingMessage: "Updating DNS wildcard setting...",
4154
});
4255
};
4356

57+
const { hasChanges, updateRef } = useHasChanges([customDNSDomain]);
58+
59+
const saveChanges = async () => {
60+
notify({
61+
title: "Custom DNS Domain",
62+
description: `Custom DNS Domain successfully updated.`,
63+
promise: saveRequest
64+
.put({
65+
id: account.id,
66+
settings: {
67+
...account.settings,
68+
dns_domain: customDNSDomain || "",
69+
},
70+
})
71+
.then(() => {
72+
mutate("/accounts");
73+
updateRef([customDNSDomain]);
74+
}),
75+
loadingMessage: "Updating Custom DNS domain...",
76+
});
77+
};
78+
79+
const domainError = useMemo(() => {
80+
if (customDNSDomain == "") return "";
81+
const valid = validator.isValidDomain(customDNSDomain, {
82+
allowWildcard: false,
83+
allowOnlyTld: false,
84+
});
85+
if (!valid) {
86+
return "Please enter a valid domain, e.g. example.com or intra.example.com";
87+
}
88+
}, [customDNSDomain]);
89+
4490
return (
4591
<Tabs.Content value={"networks"}>
4692
<div className={"p-default py-6 max-w-2xl"}>
@@ -51,36 +97,80 @@ export default function NetworkSettingsTab({ account }: Props) {
5197
icon={<SettingsIcon size={13} />}
5298
/>
5399
<Breadcrumbs.Item
54-
href={"/settings#network"}
55-
label={"Network"}
100+
href={"/settings?tab=networks"}
101+
label={"Networks"}
56102
icon={<NetworkIcon size={14} />}
57103
active
58104
/>
59105
</Breadcrumbs>
60106
<div className={"flex items-start justify-between"}>
61-
<h1>Networks</h1>
107+
<div>
108+
<h1>Networks</h1>
109+
</div>
110+
<Button
111+
variant={"primary"}
112+
disabled={!hasChanges}
113+
onClick={saveChanges}
114+
>
115+
Save Changes
116+
</Button>
62117
</div>
63118

64119
<div className={"flex flex-col gap-6 w-full mt-8"}>
65120
<div>
66-
<FancyToggleSwitch
67-
value={routingPeerDNSSetting}
68-
onChange={toggleSetting}
69-
label={
70-
<>
71-
<GlobeIcon size={15} />
72-
Enable DNS Wildcard Routing
73-
</>
74-
}
75-
helpText={
76-
<>
77-
Allow routing using DNS wildcards. This requires NetBird
78-
client v0.35 or higher. Changes will only take effect after
79-
restarting the clients.
80-
</>
121+
<div
122+
className={
123+
"flex flex-col gap-1 sm:flex-row w-full sm:gap-4 items-center"
81124
}
82-
/>
125+
>
126+
<div className={"min-w-[330px]"}>
127+
<Label>DNS Domain</Label>
128+
<HelpText>
129+
Specify a custom DNS domain for your network. This will be
130+
used for all your peers.
131+
</HelpText>
132+
</div>
133+
<div className={"w-full"}>
134+
<Input
135+
placeholder={
136+
isNetBirdHosted() ? "netbird.cloud" : "netbird.selfhosted"
137+
}
138+
errorTooltip={true}
139+
errorTooltipPosition={"top"}
140+
error={domainError}
141+
value={customDNSDomain}
142+
onChange={(e) => setCustomDNSDomain(e.target.value)}
143+
/>
144+
</div>
145+
</div>
83146
</div>
147+
148+
<FancyToggleSwitch
149+
value={routingPeerDNSSetting}
150+
onChange={toggleNetworkDNSSetting}
151+
label={
152+
<>
153+
<GlobeIcon size={15} />
154+
Enable DNS Wildcard Routing
155+
</>
156+
}
157+
helpText={
158+
<>
159+
Allow routing using DNS wildcards. This requires NetBird client
160+
v0.35 or higher. Changes will only take effect after restarting
161+
the clients.{" "}
162+
<InlineLink
163+
href={
164+
"https://docs.netbird.io/how-to/accessing-entire-domains-within-networks#enabling-dns-wildcard-routing"
165+
}
166+
target={"_blank"}
167+
>
168+
Learn more
169+
<ExternalLinkIcon size={12} />
170+
</InlineLink>
171+
</>
172+
}
173+
/>
84174
</div>
85175
</div>
86176
</Tabs.Content>

0 commit comments

Comments
 (0)