diff --git a/src/interfaces/Account.ts b/src/interfaces/Account.ts index 70fe17f0..c87c55e5 100644 --- a/src/interfaces/Account.ts +++ b/src/interfaces/Account.ts @@ -26,6 +26,7 @@ export interface Account { lazy_connection_enabled: boolean; embedded_idp_enabled?: boolean; auto_update_version: string; + auto_update_always: boolean; local_auth_disabled?: boolean; }; onboarding?: AccountOnboarding; diff --git a/src/modules/settings/ClientSettingsTab.tsx b/src/modules/settings/ClientSettingsTab.tsx index f3851580..56bcc90e 100644 --- a/src/modules/settings/ClientSettingsTab.tsx +++ b/src/modules/settings/ClientSettingsTab.tsx @@ -11,6 +11,7 @@ import { SelectDropdown, SelectOption, } from "@components/select/SelectDropdown"; +import { Callout } from "@components/Callout"; import { useHasChanges } from "@hooks/useHasChanges"; import * as Tabs from "@radix-ui/react-tabs"; import { useApiCall } from "@utils/api"; @@ -20,6 +21,7 @@ import { ExternalLinkIcon, FlaskConicalIcon, MonitorSmartphoneIcon, + AlertTriangle, RefreshCcw, } from "lucide-react"; import React, { useMemo, useState } from "react"; @@ -84,6 +86,10 @@ function ClientSettingsTabContent({ account }: Readonly) { isCustomVersion ? autoUpdateSetting : "", ); + const [autoUpdateAlways, setAutoUpdateAlways] = useState( + account.settings?.auto_update_always ?? false, + ); + const [peerExposeEnabled, setPeerExposeEnabled] = useState( account?.settings?.peer_expose_enabled ?? false, ); @@ -99,6 +105,7 @@ function ClientSettingsTabContent({ account }: Readonly) { const { hasChanges, updateRef } = useHasChanges([ autoUpdateMethod, autoUpdateCustomVersion, + autoUpdateAlways, peerExposeEnabled, peerExposeGroupNames, ]); @@ -155,6 +162,7 @@ function ClientSettingsTabContent({ account }: Readonly) { settings: { ...account.settings, auto_update_version: autoUpdateCustomVersion || autoUpdateMethod, + auto_update_always: autoUpdateAlways, peer_expose_enabled: peerExposeEnabled, peer_expose_groups: peerExposeGroupIds, }, @@ -164,6 +172,7 @@ function ClientSettingsTabContent({ account }: Readonly) { updateRef([ autoUpdateMethod, autoUpdateCustomVersion, + autoUpdateAlways, peerExposeEnabled, peerExposeGroupNames, ]); @@ -235,9 +244,9 @@ function ClientSettingsTabContent({ account }: Readonly) { /> - Select how NetBird clients handle automatic updates by choosing - the latest version, a custom version, or disabling updates - altogether. Automatic Updates require at least NetBird{" "} + Configure how NetBird clients receive update notifications. + When enabled, users will be prompted to install the selected + version. This requires at least NetBird{" "} v0.61.0.{" "} ) { }} /> + + + Force Automatic Updates + + } + helpText={ + "When enabled, updates are installed automatically in the background without user interaction." + } + disabled={ + !permission.settings.update || autoUpdateMethod === "disabled" + } + /> + {autoUpdateAlways && autoUpdateMethod !== "disabled" && ( + + } + > + Enabling automatic updates will restart the NetBird client + during updates, which can temporarily disrupt active + connections. Use with caution in production environments. + + )}