diff --git a/CHANGELOG.md b/CHANGELOG.md index 8356601939..60eebf15e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ The types of changes are: - Edit integration modal no longer requires reentering credentials when doing partial edits [#2436](https://github.com/ethyca/fides/pull/2436) - Fixed a timing issue with tcf/gpp locator iframe naming [#5173](https://github.com/ethyca/fides/pull/5173) - Detection & Discovery: The when column will now display the correct value with a tooltip showing the full date and time [#5177](https://github.com/ethyca/fides/pull/5177) +- Fixed minor issues with the SSO providers form [#5183](https://github.com/ethyca/fides/pull/5183) ### Changed - Removed PRIVACY_REQUEST_READ scope from Viewer role [#5184](https://github.com/ethyca/fides/pull/5184) diff --git a/clients/admin-ui/src/features/configure-consent/AddModal.tsx b/clients/admin-ui/src/features/configure-consent/AddModal.tsx index b848b557c5..15a9084ec1 100644 --- a/clients/admin-ui/src/features/configure-consent/AddModal.tsx +++ b/clients/admin-ui/src/features/configure-consent/AddModal.tsx @@ -45,7 +45,7 @@ const AddModal = ({ - + {children} diff --git a/clients/admin-ui/src/features/openid-authentication/SSOProvider.tsx b/clients/admin-ui/src/features/openid-authentication/SSOProvider.tsx index e16adc7673..5a050b0200 100644 --- a/clients/admin-ui/src/features/openid-authentication/SSOProvider.tsx +++ b/clients/admin-ui/src/features/openid-authentication/SSOProvider.tsx @@ -19,21 +19,31 @@ const SSOProvider = ({ }: { openIDProvider: OpenIDProvider; }) => { - const { onOpen, isOpen, onClose } = useDisclosure(); - const { isOpen: deleteIsOpen, onClose: onDeleteClose } = useDisclosure(); + const { + onOpen: onEditOpen, + isOpen: isEditOpen, + onClose: onEditClose, + } = useDisclosure(); + const { + onOpen: onDeleteOpen, + isOpen: deleteIsOpen, + onClose: onDeleteClose, + } = useDisclosure(); const toast = useToast(); const [deleteOpenIDProviderMutation] = useDeleteOpenIDProviderMutation(); const handleDelete = async () => { - const result = await deleteOpenIDProviderMutation(openIDProvider.id); + const result = await deleteOpenIDProviderMutation( + openIDProvider.identifier, + ); if (isErrorResult(result)) { toast(errorToastParams(getErrorMessage(result.error))); onDeleteClose(); return; } - toast(successToastParams(`OpenID Provider deleted successfully`)); + toast(successToastParams(`SSO provider deleted successfully`)); onDeleteClose(); }; @@ -69,7 +79,7 @@ const SSOProvider = ({ size="sm" marginRight="12px" variant="outline" - onClick={onDeleteClose} + onClick={onDeleteOpen} data-testid="remove-sso-provider-btn" > Remove @@ -78,15 +88,15 @@ const SSOProvider = ({ size="sm" marginRight="12px" variant="outline" - onClick={onOpen} + onClick={onEditOpen} data-testid="edit-sso-provider-btn" > Edit void; } -export interface SSOProviderFormValues extends OpenIDProvider {} +export type SSOProviderFormValues = Omit< + OpenIDProviderCreate, + "provider" | "client_id" | "client_secret" +> & { + id?: string; + provider?: ProviderEnum; + client_id?: string; + client_secret?: string; +}; export const defaultInitialValues: SSOProviderFormValues = { - id: "", identifier: "", name: "", - provider: "", client_id: "", client_secret: "", }; @@ -67,21 +77,21 @@ const SSOProviderForm = ({ ) => { const handleResult = ( result: - | { data: object } + | { data: OpenIDProvider } | { error: FetchBaseQueryError | SerializedError }, ) => { if (isErrorResult(result)) { const errorMsg = getErrorMessage( result.error, - "An unexpected error occurred while editing the OpenID Provider. Please try again.", + "An unexpected error occurred while editing the SSO provider. Please try again.", ); toast(errorToastParams(errorMsg)); } else { - toast(successToastParams("OpenID Provider configuration saved.")); + toast(successToastParams("SSO provider configuration saved.")); onClose(); formikHelpers.resetForm({}); if (onSuccess) { - onSuccess(values); + onSuccess(result.data); } } }; @@ -164,6 +174,7 @@ const SSOProviderForm = ({ tooltip="Unique identifier for your provider" variant="stacked" isRequired + disabled={!!initialValues.id} /> { const renderItems: () => JSX.Element[] | undefined = () => openidProviders?.map((item: OpenIDProvider) => ( - + )); return ( diff --git a/clients/admin-ui/src/features/openid-authentication/openprovider.slice.ts b/clients/admin-ui/src/features/openid-authentication/openprovider.slice.ts index e26f94edf4..28ab8839fa 100644 --- a/clients/admin-ui/src/features/openid-authentication/openprovider.slice.ts +++ b/clients/admin-ui/src/features/openid-authentication/openprovider.slice.ts @@ -36,10 +36,10 @@ const openIDProviderApi = baseApi.injectEndpoints({ }), updateOpenIDProvider: build.mutation< OpenIDProvider, - Partial & Pick + Partial & Pick >({ query: (params) => ({ - url: `plus/openid-provider/${params.id}`, + url: `plus/openid-provider/${params.identifier}`, method: "PATCH", body: params, }), diff --git a/clients/admin-ui/src/features/user-management/UserForm.tsx b/clients/admin-ui/src/features/user-management/UserForm.tsx index 0fa92907c5..2f43772dcc 100644 --- a/clients/admin-ui/src/features/user-management/UserForm.tsx +++ b/clients/admin-ui/src/features/user-management/UserForm.tsx @@ -109,7 +109,7 @@ const UserForm = ({ onSubmit, initialValues, canEditNames }: Props) => { const { data: openidProviders } = useGetAllOpenIDProvidersQuery(); const passwordFieldIsRequired = - !flags.openIDAuthentication || !openidProviders?.length; + !flags.ssoAuthentication || !openidProviders?.length; if (!passwordFieldIsRequired) { validationSchema = ValidationSchema.shape({ diff --git a/clients/admin-ui/src/flags.json b/clients/admin-ui/src/flags.json index 973b5aae1b..678a63efe8 100644 --- a/clients/admin-ui/src/flags.json +++ b/clients/admin-ui/src/flags.json @@ -36,8 +36,8 @@ "test": true, "production": false }, - "openIDAuthentication": { - "description": "OpenID authentication", + "ssoAuthentication": { + "description": "SSO Authentication Providers (OpenID)", "development": true, "test": true, "production": false diff --git a/clients/admin-ui/src/mocks/data.ts b/clients/admin-ui/src/mocks/data.ts index 2cbb3f877c..080d980ad2 100644 --- a/clients/admin-ui/src/mocks/data.ts +++ b/clients/admin-ui/src/mocks/data.ts @@ -273,13 +273,11 @@ export const mockConsentableItems: ConsentableItem[] = [ external_id: "34419", type: "Channel", name: "Default SMS channel (SMS)", - notice_id: null, children: [ { external_id: "40007", type: "Message type", name: "Default SMS message type", - notice_id: null, children: [], unmapped: true, }, @@ -290,13 +288,11 @@ export const mockConsentableItems: ConsentableItem[] = [ external_id: "34415", type: "Channel", name: "Default InApp channel (InApp)", - notice_id: null, children: [ { external_id: "40003", type: "Message type", name: "Default InApp message type", - notice_id: null, children: [], unmapped: true, }, @@ -307,13 +303,11 @@ export const mockConsentableItems: ConsentableItem[] = [ external_id: "33843", type: "Channel", name: "Push Marketing Channel (Push)", - notice_id: null, children: [ { external_id: "39240", type: "Message type", name: "Push Marketing Message", - notice_id: null, children: [], unmapped: true, }, @@ -324,13 +318,11 @@ export const mockConsentableItems: ConsentableItem[] = [ external_id: "33842", type: "Channel", name: "Transactional Channel (Email)", - notice_id: null, children: [ { external_id: "39239", type: "Message type", name: "Transactional Message", - notice_id: null, children: [], unmapped: true, }, @@ -341,13 +333,11 @@ export const mockConsentableItems: ConsentableItem[] = [ external_id: "33841", type: "Channel", name: "Marketing Channel (Email)", - notice_id: null, children: [ { external_id: "40000", type: "Message type", name: "Untitled message type", - notice_id: null, children: [], unmapped: true, }, @@ -355,7 +345,6 @@ export const mockConsentableItems: ConsentableItem[] = [ external_id: "39238", type: "Message type", name: "Marketing Message", - notice_id: null, children: [], unmapped: true, }, diff --git a/clients/admin-ui/src/pages/settings/organization.tsx b/clients/admin-ui/src/pages/settings/organization.tsx index 5785f71531..b2462ef470 100644 --- a/clients/admin-ui/src/pages/settings/organization.tsx +++ b/clients/admin-ui/src/pages/settings/organization.tsx @@ -18,7 +18,7 @@ const OrganizationPage: NextPage = () => { ); const { plus: hasPlus, - flags: { openIDAuthentication }, + flags: { ssoAuthentication }, } = useFeatures(); return ( @@ -36,7 +36,7 @@ const OrganizationPage: NextPage = () => { - {openIDAuthentication && hasPlus && ( + {ssoAuthentication && hasPlus && ( diff --git a/clients/admin-ui/src/types/api/index.ts b/clients/admin-ui/src/types/api/index.ts index c62ab73ef0..99a1eea25e 100644 --- a/clients/admin-ui/src/types/api/index.ts +++ b/clients/admin-ui/src/types/api/index.ts @@ -197,6 +197,7 @@ export type { IdentityTypes } from "./models/IdentityTypes"; export type { IdentityVerificationConfigResponse } from "./models/IdentityVerificationConfigResponse"; export { IncludeExcludeEnum } from "./models/IncludeExcludeEnum"; export type { Language } from "./models/Language"; +export { Layer1ButtonOption } from "./models/Layer1ButtonOption"; export { LegalBasisForProcessingEnum } from "./models/LegalBasisForProcessingEnum"; export { LegalBasisForProfilingEnum } from "./models/LegalBasisForProfilingEnum"; export type { LimitedPrivacyNoticeResponseSchema } from "./models/LimitedPrivacyNoticeResponseSchema"; @@ -253,6 +254,9 @@ export type { NoticeTranslationCreate } from "./models/NoticeTranslationCreate"; export type { NoticeTranslationResponse } from "./models/NoticeTranslationResponse"; export type { NotificationApplicationConfig } from "./models/NotificationApplicationConfig"; export type { OktaConfig } from "./models/OktaConfig"; +export type { OpenIDProvider } from "./models/OpenIDProvider"; +export type { OpenIDProviderCreate } from "./models/OpenIDProviderCreate"; +export type { OpenIDProviderSimple } from "./models/OpenIDProviderSimple"; export type { Organization } from "./models/Organization"; export type { OrganizationMetadata } from "./models/OrganizationMetadata"; export type { Page_BasicSystemResponse_ } from "./models/Page_BasicSystemResponse_"; @@ -306,7 +310,6 @@ export type { PreApprovalWebhookResponse } from "./models/PreApprovalWebhookResp export type { PreApprovalWebhookUpdate } from "./models/PreApprovalWebhookUpdate"; export type { PreferencesSaved } from "./models/PreferencesSaved"; export type { PreferencesSavedExtended } from "./models/PreferencesSavedExtended"; -export type { OpenIDProvider } from "./models/OpenIDProvider"; export type { PreferenceWithNoticeInformation } from "./models/PreferenceWithNoticeInformation"; export type { PrivacyCenterConfig } from "./models/PrivacyCenterConfig"; export type { PrivacyDeclaration } from "./models/PrivacyDeclaration"; @@ -337,6 +340,7 @@ export type { PrivacyRequestVerboseResponse } from "./models/PrivacyRequestVerbo export type { PrivacyRule } from "./models/PrivacyRule"; export type { Property } from "./models/Property"; export { PropertyType } from "./models/PropertyType"; +export { ProviderEnum } from "./models/ProviderEnum"; export type { PublicPropertyResponse } from "./models/PublicPropertyResponse"; export type { PurposesResponse } from "./models/PurposesResponse"; export type { QueryParam } from "./models/QueryParam"; diff --git a/clients/admin-ui/src/types/api/models/ConsentableItem.ts b/clients/admin-ui/src/types/api/models/ConsentableItem.ts index c5b046c0bc..2d424e33fb 100644 --- a/clients/admin-ui/src/types/api/models/ConsentableItem.ts +++ b/clients/admin-ui/src/types/api/models/ConsentableItem.ts @@ -1,11 +1,15 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + /** - * 3rd-party consentable item and privacy notice relationships + * Schema to represent 3rd-party consentable items and privacy notice relationships. */ -export interface ConsentableItem { +export type ConsentableItem = { external_id: string; type: string; name: string; - notice_id?: string | null; - children?: ConsentableItem[]; + notice_id?: string; + children?: Array; unmapped?: boolean; -} +}; diff --git a/clients/admin-ui/src/types/api/models/ExperienceConfigCreate.ts b/clients/admin-ui/src/types/api/models/ExperienceConfigCreate.ts index 4e69244ffa..080b5c76f3 100644 --- a/clients/admin-ui/src/types/api/models/ExperienceConfigCreate.ts +++ b/clients/admin-ui/src/types/api/models/ExperienceConfigCreate.ts @@ -2,9 +2,9 @@ /* tslint:disable */ /* eslint-disable */ -import { Layer1ButtonOption } from "~/features/privacy-experience/form/constants"; import type { ComponentType } from "./ComponentType"; import type { ExperienceTranslationCreate } from "./ExperienceTranslationCreate"; +import type { Layer1ButtonOption } from "./Layer1ButtonOption"; import type { MinimalProperty } from "./MinimalProperty"; import type { PrivacyNoticeRegion } from "./PrivacyNoticeRegion"; diff --git a/clients/admin-ui/src/types/api/models/ExperienceConfigResponse.ts b/clients/admin-ui/src/types/api/models/ExperienceConfigResponse.ts index e27cd0119e..90a346b016 100644 --- a/clients/admin-ui/src/types/api/models/ExperienceConfigResponse.ts +++ b/clients/admin-ui/src/types/api/models/ExperienceConfigResponse.ts @@ -2,9 +2,9 @@ /* tslint:disable */ /* eslint-disable */ -import { Layer1ButtonOption } from "~/features/privacy-experience/form/constants"; import type { ComponentType } from "./ComponentType"; import type { ExperienceTranslationResponse } from "./ExperienceTranslationResponse"; +import type { Layer1ButtonOption } from "./Layer1ButtonOption"; import type { MinimalProperty } from "./MinimalProperty"; import type { PrivacyNoticeRegion } from "./PrivacyNoticeRegion"; import type { PrivacyNoticeResponse } from "./PrivacyNoticeResponse"; diff --git a/clients/admin-ui/src/types/api/models/ExperienceConfigResponseNoNotices.ts b/clients/admin-ui/src/types/api/models/ExperienceConfigResponseNoNotices.ts index 8b4cc25ae2..6e2bc81f97 100644 --- a/clients/admin-ui/src/types/api/models/ExperienceConfigResponseNoNotices.ts +++ b/clients/admin-ui/src/types/api/models/ExperienceConfigResponseNoNotices.ts @@ -2,9 +2,9 @@ /* tslint:disable */ /* eslint-disable */ -import { Layer1ButtonOption } from "~/features/privacy-experience/form/constants"; import type { ComponentType } from "./ComponentType"; import type { ExperienceTranslationResponse } from "./ExperienceTranslationResponse"; +import type { Layer1ButtonOption } from "./Layer1ButtonOption"; import type { MinimalProperty } from "./MinimalProperty"; import type { PrivacyNoticeRegion } from "./PrivacyNoticeRegion"; import type { SupportedLanguage } from "./SupportedLanguage"; diff --git a/clients/admin-ui/src/types/api/models/ExperienceConfigUpdate.ts b/clients/admin-ui/src/types/api/models/ExperienceConfigUpdate.ts index 71c63403dd..87eef69aae 100644 --- a/clients/admin-ui/src/types/api/models/ExperienceConfigUpdate.ts +++ b/clients/admin-ui/src/types/api/models/ExperienceConfigUpdate.ts @@ -2,8 +2,8 @@ /* tslint:disable */ /* eslint-disable */ -import { Layer1ButtonOption } from "~/features/privacy-experience/form/constants"; import type { ExperienceTranslation } from "./ExperienceTranslation"; +import type { Layer1ButtonOption } from "./Layer1ButtonOption"; import type { MinimalProperty } from "./MinimalProperty"; import type { PrivacyNoticeRegion } from "./PrivacyNoticeRegion"; diff --git a/clients/admin-ui/src/types/api/models/Layer1ButtonOption.ts b/clients/admin-ui/src/types/api/models/Layer1ButtonOption.ts new file mode 100644 index 0000000000..62f85a90cb --- /dev/null +++ b/clients/admin-ui/src/types/api/models/Layer1ButtonOption.ts @@ -0,0 +1,11 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * Layer 1 button options - not formalized in the db + */ +export enum Layer1ButtonOption { + ACKNOWLEDGE = "acknowledge", + OPT_IN_OPT_OUT = "opt_in_opt_out", +} diff --git a/clients/admin-ui/src/types/api/models/OpenIDProvider.ts b/clients/admin-ui/src/types/api/models/OpenIDProvider.ts index b3ecd2307d..24075664b3 100644 --- a/clients/admin-ui/src/types/api/models/OpenIDProvider.ts +++ b/clients/admin-ui/src/types/api/models/OpenIDProvider.ts @@ -2,11 +2,20 @@ /* tslint:disable */ /* eslint-disable */ +import type { ProviderEnum } from "./ProviderEnum"; + +/** + * Complete schema, does NOT include sensitive values. + */ export type OpenIDProvider = { - id: string; identifier: string; name: string; - provider: string; - client_id: string; - client_secret: string; + provider: ProviderEnum; + authorization_url?: string; + token_url?: string; + user_info_url?: string; + domain?: string; + id: string; + created_at: string; + updated_at: string; }; diff --git a/clients/admin-ui/src/types/api/models/OpenIDProviderCreate.ts b/clients/admin-ui/src/types/api/models/OpenIDProviderCreate.ts new file mode 100644 index 0000000000..b4466a5e2a --- /dev/null +++ b/clients/admin-ui/src/types/api/models/OpenIDProviderCreate.ts @@ -0,0 +1,20 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ProviderEnum } from "./ProviderEnum"; + +/** + * Schema for creating an OpenIDProvider, including sensitive values client ID and secret. + */ +export type OpenIDProviderCreate = { + identifier: string; + name: string; + provider: ProviderEnum; + authorization_url?: string; + token_url?: string; + user_info_url?: string; + domain?: string; + client_id: string; + client_secret: string; +}; diff --git a/clients/admin-ui/src/types/api/models/OpenIDProviderSimple.ts b/clients/admin-ui/src/types/api/models/OpenIDProviderSimple.ts new file mode 100644 index 0000000000..5095f92d9e --- /dev/null +++ b/clients/admin-ui/src/types/api/models/OpenIDProviderSimple.ts @@ -0,0 +1,14 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { ProviderEnum } from "./ProviderEnum"; + +/** + * Simple schema display providers in the login page. + */ +export type OpenIDProviderSimple = { + name: string; + identifier: string; + provider: ProviderEnum; +}; diff --git a/clients/admin-ui/src/types/api/models/PrivacyExperienceResponse.ts b/clients/admin-ui/src/types/api/models/PrivacyExperienceResponse.ts index fcb6b5532a..507319f409 100644 --- a/clients/admin-ui/src/types/api/models/PrivacyExperienceResponse.ts +++ b/clients/admin-ui/src/types/api/models/PrivacyExperienceResponse.ts @@ -57,6 +57,7 @@ export type PrivacyExperienceResponse = { */ experience_config?: ExperienceConfigResponseNoNotices; gvl?: any; + gvl_translations?: any; available_locales?: Array; meta?: ExperienceMeta; }; diff --git a/clients/admin-ui/src/types/api/models/ProviderEnum.ts b/clients/admin-ui/src/types/api/models/ProviderEnum.ts new file mode 100644 index 0000000000..4cc9de5194 --- /dev/null +++ b/clients/admin-ui/src/types/api/models/ProviderEnum.ts @@ -0,0 +1,12 @@ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * An enumeration. + */ +export enum ProviderEnum { + GOOGLE = "google", + OKTA = "okta", + CUSTOM = "custom", +} diff --git a/clients/admin-ui/src/types/api/models/ScopeRegistryEnum.ts b/clients/admin-ui/src/types/api/models/ScopeRegistryEnum.ts index 9905b9aea2..cbb099f484 100644 --- a/clients/admin-ui/src/types/api/models/ScopeRegistryEnum.ts +++ b/clients/admin-ui/src/types/api/models/ScopeRegistryEnum.ts @@ -91,9 +91,9 @@ export enum ScopeRegistryEnum { MESSAGING_DELETE = "messaging:delete", MESSAGING_READ = "messaging:read", OPENID_PROVIDER_CREATE = "openid_provider:create", + OPENID_PROVIDER_DELETE = "openid_provider:delete", OPENID_PROVIDER_READ = "openid_provider:read", OPENID_PROVIDER_UPDATE = "openid_provider:update", - OPENID_PROVIDER_DELETE = "openid_provider:delete", ORGANIZATION_CREATE = "organization:create", ORGANIZATION_DELETE = "organization:delete", ORGANIZATION_READ = "organization:read", diff --git a/clients/admin-ui/src/types/api/models/SnowflakeDocsSchema.ts b/clients/admin-ui/src/types/api/models/SnowflakeDocsSchema.ts index 8379feebdd..0036047ecd 100644 --- a/clients/admin-ui/src/types/api/models/SnowflakeDocsSchema.ts +++ b/clients/admin-ui/src/types/api/models/SnowflakeDocsSchema.ts @@ -15,9 +15,17 @@ export type SnowflakeDocsSchema = { */ user_login_name: string; /** - * The password used to authenticate and access the database. + * The password used to authenticate and access the database. You can use a password or a private key, but not both. */ - password: string; + password?: string; + /** + * The private key used to authenticate and access the database. If a `private_key_passphrase` is also provided, it is assumed to be encrypted; otherwise, it is assumed to be unencrypted. + */ + private_key?: string; + /** + * The passphrase used for the encrypted private key. + */ + private_key_passphrase?: string; /** * The name of the Snowflake warehouse where your queries will be executed. */