diff --git a/web/messages/en/openid.json b/web/messages/en/openid.json index b5605ed9c..cc0a3c60e 100644 --- a/web/messages/en/openid.json +++ b/web/messages/en/openid.json @@ -45,6 +45,8 @@ "settings_openid_provider_helper_admin_email": "", "settings_openid_provider_google_service_account_key_title": "Service account key", "settings_openid_provider_google_service_account_key_content": "Upload a new service account key file to set the service account used for synchronization. NOTE: The uploaded file won't be visible after saving the settings and reloading the page because its contents are sensitive and are never sent back to the dashboard.", + "settings_openid_provider_google_service_account_key_configured_content": "A service account key is configured. Upload a new key file to replace it.", + "settings_openid_provider_google_service_account_key_replace": "Replace service account key", "settings_openid_provider_label_sync_only_matching_groups": "Sync only matching memberships", "settings_openid_provider_helper_microsoft_group_match": "Groups Defguard should sync memberships for. Leave it empty to sync every group. If you fill it in, only those groups are kept and the rest are ignored. This only affects how group memberships are mapped, not who gets an account. Separate group names with commas.", "settings_openid_provider_prefetch_users": "Import users from your Microsoft directory to Defguard", diff --git a/web/src/pages/settings/SettingsEditOpenIdProviderPage/form/EditGoogleProviderForm.tsx b/web/src/pages/settings/SettingsEditOpenIdProviderPage/form/EditGoogleProviderForm.tsx index c07f74a57..2a4b10e28 100644 --- a/web/src/pages/settings/SettingsEditOpenIdProviderPage/form/EditGoogleProviderForm.tsx +++ b/web/src/pages/settings/SettingsEditOpenIdProviderPage/form/EditGoogleProviderForm.tsx @@ -40,30 +40,31 @@ const discriminatedSchema = z.discriminatedUnion('directory_sync_enabled', [ syncSchema, ]); -const validationSchema = syncSchema - .omit({ admin_email: true, google_service_account_file: true }) - .extend({ - admin_email: z.string().trim(), - google_service_account_file: z.file(m.form_error_required()).nullable(), - }) - .superRefine((val, ctx) => { - if (val.directory_sync_enabled) { - if (val.admin_email.trim().length === 0) { - ctx.addIssue({ - path: ['admin_email'], - code: 'custom', - message: m.form_error_required(), - }); - } - if (val.google_service_account_file === null) { - ctx.addIssue({ - path: ['google_service_account_file'], - code: 'custom', - message: m.form_error_required(), - }); +const makeValidationSchema = (hasServiceAccountKey: boolean) => + syncSchema + .omit({ admin_email: true, google_service_account_file: true }) + .extend({ + admin_email: z.string().trim(), + google_service_account_file: z.file(m.form_error_required()).nullable(), + }) + .superRefine((val, ctx) => { + if (val.directory_sync_enabled) { + if (val.admin_email.trim().length === 0) { + ctx.addIssue({ + path: ['admin_email'], + code: 'custom', + message: m.form_error_required(), + }); + } + if (!hasServiceAccountKey && val.google_service_account_file === null) { + ctx.addIssue({ + path: ['google_service_account_file'], + code: 'custom', + message: m.form_error_required(), + }); + } } - } - }); + }); type FormFields = z.infer; @@ -99,6 +100,12 @@ export const EditGoogleProviderForm = ({ }; }, [provider]); + const hasServiceAccountKey = Boolean(provider.google_service_account_email); + const validationSchema = useMemo( + () => makeValidationSchema(hasServiceAccountKey), + [hasServiceAccountKey], + ); + const form = useAppForm({ defaultValues, validationLogic: formChangeLogic, @@ -109,17 +116,24 @@ export const EditGoogleProviderForm = ({ onSubmit: async ({ value }) => { if (value.directory_sync_enabled) { const inner = value as z.infer; - const file = await parseGoogleKeyFile(inner.google_service_account_file as File); - if (!file) { - Snackbar.error(m.form_error_file_contents()); - return; + if (inner.google_service_account_file) { + const file = await parseGoogleKeyFile(inner.google_service_account_file); + if (!file) { + Snackbar.error(m.form_error_file_contents()); + return; + } + await onSubmit({ + ...omit(inner, ['google_service_account_file']), + google_service_account_email: file.client_email, + google_service_account_key: file.private_key, + directory_sync_user_groups: inner.directory_sync_user_groups ?? '', + }); + } else { + await onSubmit({ + ...omit(inner, ['google_service_account_file']), + directory_sync_user_groups: inner.directory_sync_user_groups ?? '', + }); } - await onSubmit({ - ...omit(inner, ['google_service_account_file']), - google_service_account_email: file.client_email, - google_service_account_key: file.private_key, - directory_sync_user_groups: inner.directory_sync_user_groups ?? '', - }); } else { await onSubmit(omit(value, ['google_service_account_file'])); } @@ -272,11 +286,23 @@ export const EditGoogleProviderForm = ({ -

{m.settings_openid_provider_google_service_account_key_content()}

+

+ {hasServiceAccountKey + ? m.settings_openid_provider_google_service_account_key_configured_content() + : m.settings_openid_provider_google_service_account_key_content()} +

- {(field) => } + {(field) => ( + + )} )}