From c157695afb4776c3c364b56f50217997873a4cde Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Fri, 17 Jan 2025 16:19:18 +0100 Subject: [PATCH] Release fixes vol. 3 (OIDC dashboard, links) (#957) * fix oidc UI * change link --- .../steps/MethodStep/MethodStep.tsx | 3 +- .../components/GatewayNotificationsForm.tsx | 18 +-- .../components/DirectorySyncSettings.tsx | 29 ++-- .../components/OpenIdGeneralSettings.tsx | 9 +- .../components/OpenIdProviderSettings.tsx | 64 ++++----- .../components/OpenIdSettingsRootForm.tsx | 131 ++++++++++-------- web/src/shared/links.ts | 3 +- 7 files changed, 120 insertions(+), 137 deletions(-) diff --git a/web/src/pages/devices/modals/AddStandaloneDeviceModal/steps/MethodStep/MethodStep.tsx b/web/src/pages/devices/modals/AddStandaloneDeviceModal/steps/MethodStep/MethodStep.tsx index 722064a62..cab409a11 100644 --- a/web/src/pages/devices/modals/AddStandaloneDeviceModal/steps/MethodStep/MethodStep.tsx +++ b/web/src/pages/devices/modals/AddStandaloneDeviceModal/steps/MethodStep/MethodStep.tsx @@ -13,6 +13,7 @@ import { } from '../../../../../../shared/defguard-ui/components/Layout/Button/types'; import { SelectOption } from '../../../../../../shared/defguard-ui/components/Layout/Select/types'; import useApi from '../../../../../../shared/hooks/useApi'; +import { externalLink } from '../../../../../../shared/links'; import { QueryKeys } from '../../../../../../shared/queries'; import { Network } from '../../../../../../shared/types'; import { DeviceSetupMethodCard } from '../../../../../addDevice/steps/AddDeviceSetupMethodStep/components/DeviceSetupMethodCard/DeviceSetupMethodCard'; @@ -111,7 +112,7 @@ export const MethodStep = () => { } selected={choice === AddStandaloneDeviceModalChoice.CLI} diff --git a/web/src/pages/settings/components/GatewayNotificationsSettings/components/GatewayNotificationsForm.tsx b/web/src/pages/settings/components/GatewayNotificationsSettings/components/GatewayNotificationsForm.tsx index 86ad77054..ec27a962c 100644 --- a/web/src/pages/settings/components/GatewayNotificationsSettings/components/GatewayNotificationsForm.tsx +++ b/web/src/pages/settings/components/GatewayNotificationsSettings/components/GatewayNotificationsForm.tsx @@ -86,17 +86,11 @@ export const GatewayNotificationsForm = () => { return res; }, [settings]); - const { control, handleSubmit, watch } = useForm({ + const { control, handleSubmit } = useForm({ defaultValues, mode: 'all', resolver: zodResolver(zodSchema), }); - const gatewayDisconnectNotificationsEnabled = watch( - 'gateway_disconnect_notifications_enabled', - ); - const gatewayDisconnectNotificationsReconnectNotificationEnabled = watch( - 'gateway_disconnect_notifications_reconnect_notification_enabled', - ); const onSubmit: SubmitHandler = (data) => { mutate(data); @@ -127,7 +121,6 @@ export const GatewayNotificationsForm = () => { { labelExtras={ {parse(localLL.form.fields.inactivityThreshold.help())} } - disabled={ - isLoading || !gatewayDisconnectNotificationsEnabled || !smtpConfigured - } + disabled={isLoading || !smtpConfigured} required />
; + isLoading: boolean; }) => { const { LL } = useI18nContext(); const localLL = LL.settingsPage.openIdSettings; @@ -101,7 +103,7 @@ export const DirsyncSettings = ({ <>
{parse(localLL.form.labels.sync_target.helper())} } - disabled={!enterpriseEnabled} + disabled={isLoading} /> {parse(localLL.form.labels.sync_interval.helper())} } - disabled={!enterpriseEnabled} + disabled={isLoading} /> {parse(localLL.form.labels.user_behavior.helper())} } - disabled={!enterpriseEnabled} + disabled={isLoading} /> {parse(localLL.form.labels.admin_behavior.helper())} } - disabled={!enterpriseEnabled} + disabled={isLoading} /> {parse(localLL.form.labels.admin_email.helper())} } required={enabled} /> -
- -
} - disabled={!enterpriseEnabled} + disabled={isLoading} required={enabled} />
@@ -221,7 +214,7 @@ export const DirsyncSettings = ({ reader.readAsText(file); } }} - disabled={!enterpriseEnabled} + disabled={isLoading} />
{' '} diff --git a/web/src/pages/settings/components/OpenIdSettings/components/OpenIdGeneralSettings.tsx b/web/src/pages/settings/components/OpenIdSettings/components/OpenIdGeneralSettings.tsx index 6c04392bf..9d2c18a7e 100644 --- a/web/src/pages/settings/components/OpenIdSettings/components/OpenIdGeneralSettings.tsx +++ b/web/src/pages/settings/components/OpenIdSettings/components/OpenIdGeneralSettings.tsx @@ -6,24 +6,21 @@ import { UseFormReturn } from 'react-hook-form'; import { useI18nContext } from '../../../../../i18n/i18n-react'; import { FormCheckBox } from '../../../../../shared/defguard-ui/components/Form/FormCheckBox/FormCheckBox'; import { Helper } from '../../../../../shared/defguard-ui/components/Layout/Helper/Helper'; -import { useAppStore } from '../../../../../shared/hooks/store/useAppStore'; import { OpenIdProvider } from '../../../../../shared/types'; -import { useSettingsPage } from '../../../hooks/useSettingsPage'; export const OpenIdGeneralSettings = ({ formControl, + isLoading, }: { formControl: UseFormReturn< OpenIdProvider & { create_account: boolean; } >; + isLoading: boolean; }) => { const { LL } = useI18nContext(); const localLL = LL.settingsPage.openIdSettings; - const settings = useSettingsPage((state) => state.settings); - const enterpriseEnabled = useAppStore((s) => s.appInfo?.license_info.enterprise); - if (!settings) return null; return (
@@ -35,13 +32,13 @@ export const OpenIdGeneralSettings = ({
{localLL.general.createAccount.helper()}
diff --git a/web/src/pages/settings/components/OpenIdSettings/components/OpenIdProviderSettings.tsx b/web/src/pages/settings/components/OpenIdSettings/components/OpenIdProviderSettings.tsx index a3166e68c..99226152c 100644 --- a/web/src/pages/settings/components/OpenIdSettings/components/OpenIdProviderSettings.tsx +++ b/web/src/pages/settings/components/OpenIdSettings/components/OpenIdProviderSettings.tsx @@ -13,25 +13,25 @@ import { SelectSelectedValue, SelectSizeVariant, } from '../../../../../shared/defguard-ui/components/Layout/Select/types'; -import { useAppStore } from '../../../../../shared/hooks/store/useAppStore'; import { OpenIdProvider } from '../../../../../shared/types'; +type FormFields = OpenIdProvider & { + create_account: boolean; +}; + export const OpenIdSettingsForm = ({ setCurrentProvider, currentProvider, formControl, + isLoading, }: { - setCurrentProvider: (provider: OpenIdProvider | null) => void; - currentProvider: OpenIdProvider | null; - formControl: UseFormReturn< - OpenIdProvider & { - create_account: boolean; - } - >; + setCurrentProvider: (provider?: OpenIdProvider) => void; + currentProvider?: OpenIdProvider; + formControl: UseFormReturn; + isLoading: boolean; }) => { const { LL } = useI18nContext(); const localLL = LL.settingsPage.openIdSettings; - const enterpriseEnabled = useAppStore((s) => s.appInfo?.license_info.enterprise); const { control } = formControl; const options: SelectOption[] = useMemo( @@ -94,28 +94,20 @@ export const OpenIdSettingsForm = ({ [], ); - const handleChange = useCallback( + const handleProviderChange = useCallback( (val: string) => { - setCurrentProvider({ - ...currentProvider, - id: currentProvider?.id ?? 0, - name: val, - base_url: getProviderUrl({ name: val }) ?? '', - client_id: currentProvider?.client_id ?? '', - client_secret: currentProvider?.client_secret ?? '', - display_name: - getProviderDisplayName({ name: val }) ?? currentProvider?.display_name ?? '', - google_service_account_email: currentProvider?.google_service_account_email ?? '', - google_service_account_key: currentProvider?.google_service_account_key ?? '', - admin_email: currentProvider?.admin_email ?? '', - directory_sync_enabled: currentProvider?.directory_sync_enabled ?? false, - directory_sync_interval: currentProvider?.directory_sync_interval ?? 600, - directory_sync_user_behavior: - currentProvider?.directory_sync_user_behavior ?? 'keep', - directory_sync_admin_behavior: - currentProvider?.directory_sync_admin_behavior ?? 'keep', - directory_sync_target: currentProvider?.directory_sync_target ?? 'all', - }); + if (currentProvider) { + setCurrentProvider({ + ...currentProvider, + id: currentProvider?.id ?? 0, + name: val, + base_url: getProviderUrl({ name: val }) ?? '', + client_id: currentProvider?.client_id ?? '', + client_secret: currentProvider?.client_secret ?? '', + display_name: + getProviderDisplayName({ name: val }) ?? currentProvider?.display_name ?? '', + }); + } }, [currentProvider, getProviderUrl, getProviderDisplayName, setCurrentProvider], ); @@ -131,23 +123,23 @@ export const OpenIdSettingsForm = ({ selected={currentProvider?.name ?? undefined} options={options} renderSelected={renderSelected} - onChangeSingle={(res) => handleChange(res)} + onChangeSingle={(res) => handleProviderChange(res)} label={localLL.form.labels.provider.label()} labelExtras={{parse(localLL.form.labels.provider.helper())}} - disabled={!enterpriseEnabled} + disabled={isLoading} /> {parse(localLL.form.labels.base_url.helper())}} - disabled={currentProvider?.name === 'Google' || !enterpriseEnabled} + disabled={currentProvider?.name === 'Google' || isLoading} required /> {parse(localLL.form.labels.client_id.helper())}} - disabled={!enterpriseEnabled} + disabled={isLoading} required /> {parse(localLL.form.labels.client_secret.helper())}} required type="password" - disabled={!enterpriseEnabled} + disabled={isLoading} /> {parse(localLL.form.labels.display_name.helper())}} - disabled={!enterpriseEnabled || currentProvider?.name !== 'Custom'} + disabled={isLoading || currentProvider?.name !== 'Custom'} /> { const { LL } = useI18nContext(); const localLL = LL.settingsPage.openIdSettings; - const [currentProvider, setCurrentProvider] = useState(null); - const [openIDSettings, setOpenIDSettings] = useState<{ - create_account: boolean; - } | null>(null); + const [openidInfo, setOpenidInfo] = useState(null); const queryClient = useQueryClient(); const enterpriseEnabled = useAppStore((s) => s.appInfo?.license_info.enterprise); @@ -51,16 +47,25 @@ export const OpenIdSettingsRootForm = () => { }); useEffect(() => { - if (openidData?.provider) { - setCurrentProvider(openidData?.provider); - } - if (openidData?.settings) { - setOpenIDSettings(openidData?.settings); + if (openidData) { + setOpenidInfo(openidData); } }, [openidData]); const toaster = useToaster(); + const setProvider = useCallback( + (provider?: OpenIdProvider) => { + if (openidInfo) { + setOpenidInfo({ + ...openidInfo, + provider, + }); + } + }, + [openidInfo], + ); + const { mutate } = useMutation({ mutationFn: addOpenIdProvider, onSuccess: () => { @@ -113,28 +118,41 @@ export const OpenIdSettingsRootForm = () => { [LL.form.error], ); - const defaultValues = useMemo( - (): FormFields => ({ - id: currentProvider?.id ?? 0, - name: currentProvider?.name ?? '', - base_url: currentProvider?.base_url ?? '', - client_id: currentProvider?.client_id ?? '', - client_secret: currentProvider?.client_secret ?? '', - display_name: currentProvider?.display_name ?? '', - admin_email: currentProvider?.admin_email ?? '', - google_service_account_email: currentProvider?.google_service_account_email ?? '', - google_service_account_key: currentProvider?.google_service_account_key ?? '', - directory_sync_enabled: currentProvider?.directory_sync_enabled ?? false, - directory_sync_interval: currentProvider?.directory_sync_interval ?? 600, - directory_sync_user_behavior: - currentProvider?.directory_sync_user_behavior ?? 'keep', - directory_sync_admin_behavior: - currentProvider?.directory_sync_admin_behavior ?? 'keep', - directory_sync_target: currentProvider?.directory_sync_target ?? 'all', - create_account: openIDSettings?.create_account ?? false, - }), - [currentProvider, openIDSettings], - ); + const defaultValues = useMemo((): FormFields => { + let defaults: FormFields = { + id: 0, + name: '', + base_url: '', + client_id: '', + client_secret: '', + display_name: '', + admin_email: '', + google_service_account_email: '', + google_service_account_key: '', + directory_sync_enabled: false, + directory_sync_interval: 600, + directory_sync_user_behavior: 'keep', + directory_sync_admin_behavior: 'keep', + directory_sync_target: 'all', + create_account: false, + }; + + if (openidInfo) { + if (openidInfo.provider) { + defaults = { + ...defaults, + ...openidInfo.provider, + }; + } + + defaults = { + ...defaults, + ...openidInfo.settings, + }; + } + + return defaults; + }, [openidInfo]); const formControl = useForm({ resolver: zodResolver(schema), @@ -178,11 +196,11 @@ export const OpenIdSettingsRootForm = () => { }; const handleDeleteProvider = useCallback(() => { - if (currentProvider) { - deleteProvider(currentProvider.name); - setCurrentProvider(null); + if (openidInfo?.provider) { + deleteProvider(openidInfo.provider.name); + setProvider(); } - }, [currentProvider, deleteProvider]); + }, [openidInfo, deleteProvider, setProvider]); return (
@@ -208,28 +226,23 @@ export const OpenIdSettingsRootForm = () => { disabled={!enterpriseEnabled} />
- {isLoading ? ( -
- -
- ) : ( - <> -
- -
-
- - -
- - )} + {/* FIXME: Change to shared state instead of passing it? */} +
+ +
+
+ + +
); }; diff --git a/web/src/shared/links.ts b/web/src/shared/links.ts index 21674a3ae..09b14d12e 100644 --- a/web/src/shared/links.ts +++ b/web/src/shared/links.ts @@ -18,6 +18,5 @@ export const externalLink = { wireguard: { download: 'https://www.wireguard.com/install/', }, - //TODO: change me - defguardCliDownload: 'https://github.com/DefGuard/client/releases', + defguardCliDownload: 'https://github.com/DefGuard/client/releases/latest', };