From 645fb9afa0ad0594d39243083d8f1a0174c39d78 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Wed, 31 Jul 2024 10:40:10 +0530 Subject: [PATCH 01/23] jwt access token atributes --- .../auto-complete-render-option.tsx | 72 ++++++++++++ .../components/forms/inbound-oidc-form.tsx | 107 +++++++++++++++++- .../models/application-inbound.ts | 1 + 3 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 features/admin.applications.v1/components/auto-complete-render-option.tsx diff --git a/features/admin.applications.v1/components/auto-complete-render-option.tsx b/features/admin.applications.v1/components/auto-complete-render-option.tsx new file mode 100644 index 00000000000..39cee3d8860 --- /dev/null +++ b/features/admin.applications.v1/components/auto-complete-render-option.tsx @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import Checkbox from "@oxygen-ui/react/Checkbox"; +import Grid from "@oxygen-ui/react/Grid"; +import ListItemText from "@oxygen-ui/react/ListItemText"; +import { IdentifiableComponentInterface } from "@wso2is/core/models"; +import React, { + FunctionComponent, + HTMLAttributes, + ReactElement +} from "react"; + +interface AutoCompleteRenderOption extends IdentifiableComponentInterface { + /** + * Is the option selected. + */ + selected?: boolean; + /** + * The display name of the option. + */ + displayName: string; + /** + * The props passed to the option. + */ + renderOptionProps: HTMLAttributes +} + +export const AutoCompleteRenderOption: FunctionComponent = ( + props: AutoCompleteRenderOption +): ReactElement => { + + const { + selected, + displayName, + renderOptionProps + } = props; + + return ( +
  • + + + + { + typeof selected === "boolean" && ( + + ) + } + + + + + + +
  • + ); +}; diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index 0a49d99131b..26d37e580e2 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -16,12 +16,17 @@ * under the License. */ +import Autocomplete, { + AutocompleteRenderGetTagProps, + AutocompleteRenderInputParams +} from "@oxygen-ui/react/Autocomplete"; import Box from "@oxygen-ui/react/Box"; import Chip from "@oxygen-ui/react/Chip"; import { AppState, ConfigReducerStateInterface } from "@wso2is/admin.core.v1"; import useGlobalVariables from "@wso2is/admin.core.v1/hooks/use-global-variables"; import { applicationConfig } from "@wso2is/admin.extensions.v1"; import { getSharedOrganizations } from "@wso2is/admin.organizations.v1/api"; +import { getAllExternalClaims } from "@wso2is/admin.claims.v1/api"; import { OrganizationType } from "@wso2is/admin.organizations.v1/constants"; import { OrganizationInterface, OrganizationResponseInterface } from "@wso2is/admin.organizations.v1/models"; import { IdentityAppsApiException } from "@wso2is/core/exceptions"; @@ -44,6 +49,8 @@ import { Text, URLInput } from "@wso2is/react-components"; +import TextField from "@oxygen-ui/react/TextField"; +import { AutoCompleteRenderOption } from "./../auto-complete-render-option"; import { FormValidation } from "@wso2is/validation"; import { AxiosResponse } from "axios"; import get from "lodash-es/get"; @@ -54,13 +61,16 @@ import React, { ChangeEvent, Fragment, FunctionComponent, + HTMLAttributes, MouseEvent, MutableRefObject, ReactElement, + SyntheticEvent, useEffect, useRef, useState } from "react"; +import { ExternalClaim } from "@wso2is/core/models"; import { Trans, useTranslation } from "react-i18next"; import { useDispatch, useSelector } from "react-redux"; import { Dispatch } from "redux"; @@ -241,6 +251,9 @@ export const InboundOIDCForm: FunctionComponent = isRefreshTokenWithoutAllowedGrantType, setRefreshTokenWithoutAlllowdGrantType ] = useState(false); + const [ activeOption, setActiveOption ] = useState(undefined); + const [ selectedJwtAccessTokenAttributes, setSelectedJwtAccessTokenAttributes ] = useState(undefined); + const [ jwtAccessTokenAttributes, setJwtAccessTokenAttributes ] = useState([]); const config: ConfigReducerStateInterface = useSelector((state: AppState) => state.config); const clientSecret: MutableRefObject = useRef(); @@ -418,6 +431,28 @@ export const InboundOIDCForm: FunctionComponent = ); }, [ application ]); + useEffect(() => { + getAllExternalClaims("aHR0cDovL3dzbzIub3JnL29pZGMvY2xhaW0", null) + .then((response: ExternalClaim[]) => { + console.log("External claims response: ", response); + setJwtAccessTokenAttributes(response); + }) + .catch(() => { + console.log("Error while fetching external claims"); + }); + }, []); + + useEffect(() => { + if (!initialValues.accessToken.jwtAccessTokenClaims) { + return; + } + const selectedClaims = initialValues.accessToken.jwtAccessTokenClaims + .map((claim: string) => jwtAccessTokenAttributes.find((claimObj: ExternalClaim) => claimObj.claimURI === claim)) + .filter((claimObj: ExternalClaim | undefined) => claimObj !== undefined); + + setSelectedJwtAccessTokenAttributes(selectedClaims); + }, [jwtAccessTokenAttributes]); + useEffect(() => { const isSharedWithAll: additionalSpProperty[] = application?.advancedConfigurations ?.additionalSpProperties?.filter((property: additionalSpProperty) => @@ -1162,7 +1197,8 @@ export const InboundOIDCForm: FunctionComponent = revokeTokensWhenIDPSessionTerminated: values.get("RevokeAccessToken")?.length > 0, type: values.get("type"), userAccessTokenExpiryInSeconds: Number(values.get("userAccessTokenExpiryInSeconds")), - validateTokenBinding: values.get("ValidateTokenBinding")?.length > 0 + validateTokenBinding: values.get("ValidateTokenBinding")?.length > 0, + jwtAccessTokenClaims: selectedJwtAccessTokenAttributes.map((claim: ExternalClaim) => claim.claimURI) }, grantTypes: values.get("grant"), idToken: { @@ -2482,6 +2518,75 @@ export const InboundOIDCForm: FunctionComponent = readOnly={ readOnly } data-testid={ `${ testId }-access-token-type-radio-group` } /> + { initialValues.accessToken.type === "JWT" ? ( + + +

    + JWT Access Token Attributes +

    +
    + + claim.claimURI + } + renderInput={ (params: AutocompleteRenderInputParams) => ( + + ) } + onChange={ (event: SyntheticEvent, claims: ExternalClaim[]) => { + setIsFormStale(true); + setSelectedJwtAccessTokenAttributes(claims); + } } + isOptionEqualToValue={ + (option: ExternalClaim, value: ExternalClaim) => + option.id === value.id + } + renderTags={ ( + value: ExternalClaim[], + getTagProps: AutocompleteRenderGetTagProps + ) => value.map((option: ExternalClaim, index: number) => ( + claim.id === option.id + ) + ? "solid" + : "outlined" + } + /> + )) } + renderOption={ ( + props: HTMLAttributes, + option: ExternalClaim, + { selected }: { selected: boolean } + ) => ( + + ) } + /> + +
    + ) : null } ) diff --git a/features/admin.applications.v1/models/application-inbound.ts b/features/admin.applications.v1/models/application-inbound.ts index 8b7e704183a..512cc2a3506 100644 --- a/features/admin.applications.v1/models/application-inbound.ts +++ b/features/admin.applications.v1/models/application-inbound.ts @@ -125,6 +125,7 @@ interface AccessTokenConfigurationInterface { bindingType?: SupportedAccessTokenBindingTypes | string; revokeTokensWhenIDPSessionTerminated?: boolean; validateTokenBinding?: boolean; + jwtAccessTokenClaims?: string[]; } interface RefreshTokenConfigurationInterface { From 64cbecbb4d8f0630388b64f9d40fb4b3545a2773 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Wed, 31 Jul 2024 17:21:27 +0530 Subject: [PATCH 02/23] fix auto compete --- .gitignore | 1 + .../components/forms/inbound-oidc-form.scss | 11 ++++++++ .../components/forms/inbound-oidc-form.tsx | 27 ++++++++++++++----- .../src/models/namespaces/applications-ns.ts | 6 +++++ .../en-US/portals/applications.ts | 6 +++++ 5 files changed, 44 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 4dc86502f6c..d9c52067f0d 100644 --- a/.gitignore +++ b/.gitignore @@ -130,3 +130,4 @@ identity-apps-core/apps/*/src/main/webapp/includes/layouts .repository/ apps/console/src/extensions/i18n/tmp/** .nx +.pnpm-store/ diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.scss b/features/admin.applications.v1/components/forms/inbound-oidc-form.scss index 4d7397971c9..07b3197d484 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.scss +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.scss @@ -20,3 +20,14 @@ margin-top: 0 !important; margin-right: 1rem !important; } + +.jwt-attributes-dropdown-input { + input { + border: none !important; + width: auto !important; + } +} +.jwt-attributes-dropdown-label-column { + margin-bottom: 0.3rem !important; + font-size: 0.9rem !important; +} diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index 26d37e580e2..3cd7ced60e0 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -107,6 +107,7 @@ import { } from "../../models"; import { ApplicationManagementUtils } from "../../utils/application-management-utils"; import { ApplicationCertificateWrapper } from "../settings/certificate"; +import "./inbound-oidc-form.scss"; /** * Proptypes for the inbound OIDC form component. @@ -2520,13 +2521,14 @@ export const InboundOIDCForm: FunctionComponent = /> { initialValues.accessToken.type === "JWT" ? ( - -

    - JWT Access Token Attributes -

    + + + { t("applications:forms.inboundOIDC.sections" + + ".accessToken.fields.jwtAccessTokenAttributes.label") } + - = renderInput={ (params: AutocompleteRenderInputParams) => ( ) } onChange={ (event: SyntheticEvent, claims: ExternalClaim[]) => { @@ -2584,6 +2586,17 @@ export const InboundOIDCForm: FunctionComponent = /> ) } /> + + + Define the attributes that should be included in the JWT access token + +
    ) : null } diff --git a/modules/i18n/src/models/namespaces/applications-ns.ts b/modules/i18n/src/models/namespaces/applications-ns.ts index b1ab8b549a1..94a5fa8f634 100644 --- a/modules/i18n/src/models/namespaces/applications-ns.ts +++ b/modules/i18n/src/models/namespaces/applications-ns.ts @@ -1269,6 +1269,12 @@ export interface ApplicationsNS { invalid: string; }; }; + jwtAccessTokenAttributes: { + hint: string; + label:string; + description: string; + placeholder: string; + }; }; }; idToken: { diff --git a/modules/i18n/src/translations/en-US/portals/applications.ts b/modules/i18n/src/translations/en-US/portals/applications.ts index 0df3e957879..b137bf834ba 100644 --- a/modules/i18n/src/translations/en-US/portals/applications.ts +++ b/modules/i18n/src/translations/en-US/portals/applications.ts @@ -1518,6 +1518,12 @@ export const applications: ApplicationsNS = { empty: "Please fill the audience", invalid: "Please avoid special characters like commas (,)" } + }, + jwtAccessTokenAttributes: { + hint : "", + label: "JWT Access Token Attributes", + description: "Define the attributes that should be included in the JWT access token.", + placeholder: "Search by attribute name", } }, heading: "Access Token", From 9f46bec241e6f9088fc716b3ed65314b1312f84d Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Tue, 6 Aug 2024 14:45:14 +0530 Subject: [PATCH 03/23] add enable checkbox --- .../components/forms/inbound-oidc-form.tsx | 68 ++++++++++++++++--- .../settings/access-configuration.tsx | 3 +- .../models/application-inbound.ts | 6 +- .../src/models/namespaces/applications-ns.ts | 3 + .../en-US/portals/applications.ts | 3 + 5 files changed, 70 insertions(+), 13 deletions(-) diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index 3cd7ced60e0..b1974fc26d2 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -253,8 +253,10 @@ export const InboundOIDCForm: FunctionComponent = setRefreshTokenWithoutAlllowdGrantType ] = useState(false); const [ activeOption, setActiveOption ] = useState(undefined); + const [ selectedTokenType, setSelectedTokenType ] = useState(undefined); const [ selectedJwtAccessTokenAttributes, setSelectedJwtAccessTokenAttributes ] = useState(undefined); const [ jwtAccessTokenAttributes, setJwtAccessTokenAttributes ] = useState([]); + const [ jwtAccessTokenAttributesEnabled, setJwtAccessTokenAttributesEnabled ] = useState(false); const config: ConfigReducerStateInterface = useSelector((state: AppState) => state.config); const clientSecret: MutableRefObject = useRef(); @@ -292,6 +294,7 @@ export const InboundOIDCForm: FunctionComponent = const requestObjectSigningAlg: MutableRefObject = useRef(); const requestObjectEncryptionAlgorithm: MutableRefObject = useRef(); const requestObjectEncryptionMethod: MutableRefObject = useRef(); + const jwtAccessTokenAttributesEnabledConfig: MutableRefObject = useRef(); const [ isSPAApplication, setSPAApplication ] = useState(false); const [ isOIDCWebApplication, setOIDCWebApplication ] = useState(false); @@ -444,14 +447,15 @@ export const InboundOIDCForm: FunctionComponent = }, []); useEffect(() => { - if (!initialValues.accessToken.jwtAccessTokenClaims) { + if (!initialValues.accessToken.jwtAccessTokenAttributesConfiguration.attributes) { return; } - const selectedClaims = initialValues.accessToken.jwtAccessTokenClaims + const selectedClaims = initialValues.accessToken.jwtAccessTokenAttributesConfiguration.attributes .map((claim: string) => jwtAccessTokenAttributes.find((claimObj: ExternalClaim) => claimObj.claimURI === claim)) .filter((claimObj: ExternalClaim | undefined) => claimObj !== undefined); setSelectedJwtAccessTokenAttributes(selectedClaims); + setJwtAccessTokenAttributesEnabled(initialValues.accessToken.jwtAccessTokenAttributesConfiguration.enable) }, [jwtAccessTokenAttributes]); useEffect(() => { @@ -613,6 +617,9 @@ export const InboundOIDCForm: FunctionComponent = setAllowedOrigins(initialValues?.allowedOrigins.toString()); } + setSelectedTokenType(initialValues?.accessToken? initialValues.accessToken.type + : metadata?.accessTokenType?.defaultValue); + }, [ initialValues ]); /** @@ -692,6 +699,12 @@ export const InboundOIDCForm: FunctionComponent = setGrantChanged(!isGrantChanged); }; + const handleTokenTypeChange = (values: Map) => { + let tokenType: string = values.get("type") as string; + + setSelectedTokenType(tokenType); + }; + const getMetadataHints = (element: string) => { switch (element.toLowerCase()) { case "none": @@ -822,7 +835,7 @@ export const InboundOIDCForm: FunctionComponent = * @param isBinding - Indicate whether binding is true or false. * @returns a list of options for radio. */ - const getAllowedListForAccessToken = ( +const getAllowedListForAccessToken = ( metadataProp: MetadataPropertyInterface, isBinding?: boolean): RadioChild[] => { const allowedList: RadioChild[] = []; @@ -1199,7 +1212,10 @@ export const InboundOIDCForm: FunctionComponent = type: values.get("type"), userAccessTokenExpiryInSeconds: Number(values.get("userAccessTokenExpiryInSeconds")), validateTokenBinding: values.get("ValidateTokenBinding")?.length > 0, - jwtAccessTokenClaims: selectedJwtAccessTokenAttributes.map((claim: ExternalClaim) => claim.claimURI) + jwtAccessTokenAttributesConfiguration: { + attributes: selectedJwtAccessTokenAttributes.map((claim: ExternalClaim) => claim.claimURI), + enable: jwtAccessTokenAttributesEnabled + } }, grantTypes: values.get("grant"), idToken: { @@ -2509,17 +2525,16 @@ export const InboundOIDCForm: FunctionComponent = ".accessToken.fields.type.label") } name="type" - default={ - initialValues?.accessToken - ? initialValues.accessToken.type - : metadata?.accessTokenType?.defaultValue - } + value={ selectedTokenType ?? initialValues?.accessToken + ? initialValues.accessToken.type + : metadata?.accessTokenType?.defaultValue } type="radio" children={ getAllowedListForAccessToken(metadata?.accessTokenType, false) } readOnly={ readOnly } + listen={ (values: Map) => handleTokenTypeChange(values) } data-testid={ `${ testId }-access-token-type-radio-group` } /> - { initialValues.accessToken.type === "JWT" ? ( + { selectedTokenType === "JWT" ? ( @@ -2535,7 +2550,7 @@ export const InboundOIDCForm: FunctionComponent = loading={ isLoading } options={ jwtAccessTokenAttributes } value={ selectedJwtAccessTokenAttributes ?? [] } - disabled = { false } + disabled = { !initialValues?.accessToken?.jwtAccessTokenAttributesConfiguration.enable } data-componentid={ `${ componentId }-assigned-jwt-attribute-list` } getOptionLabel={ (claim: ExternalClaim) => claim.claimURI @@ -2598,6 +2613,37 @@ export const InboundOIDCForm: FunctionComponent = + {!initialValues?.accessToken?.jwtAccessTokenAttributesConfiguration.enable && ( + + ): void => { + const jwtAccessTokenAttributesEnabled: boolean = values.get("jwtAccessTokenAttributesEnabledConfig") + .includes("jwtAccessTokenAttributesEnabled"); + + setJwtAccessTokenAttributesEnabled(jwtAccessTokenAttributesEnabled); + } } + value={ + initialValues?.accessToken?.jwtAccessTokenAttributesConfiguration.enable + ? [ "jwtAccessTokenAttributesEnabled" ] + : [] + } + children={ [ + { + label: t("applications:forms.inboundOIDC.sections" + + ".accessToken.fields.jwtAccessTokenAttributes.enable.label"), + value: "jwtAccessTokenAttributesEnabled" + } + ] } + readOnly={ readOnly } + data-testid={ `${ testId }-jwtAccessTokenAttributesEnabled-checkbox` } + /> + + )} ) : null } diff --git a/features/admin.applications.v1/components/settings/access-configuration.tsx b/features/admin.applications.v1/components/settings/access-configuration.tsx index efcadc478b6..c13a92810ed 100644 --- a/features/admin.applications.v1/components/settings/access-configuration.tsx +++ b/features/admin.applications.v1/components/settings/access-configuration.tsx @@ -216,6 +216,7 @@ export const AccessConfiguration: FunctionComponent { - onUpdate(appId); + onProtocolUpdate(); if (!updateError) { createSAMLApplication(); } diff --git a/features/admin.applications.v1/models/application-inbound.ts b/features/admin.applications.v1/models/application-inbound.ts index 512cc2a3506..e86939c4c6a 100644 --- a/features/admin.applications.v1/models/application-inbound.ts +++ b/features/admin.applications.v1/models/application-inbound.ts @@ -125,9 +125,13 @@ interface AccessTokenConfigurationInterface { bindingType?: SupportedAccessTokenBindingTypes | string; revokeTokensWhenIDPSessionTerminated?: boolean; validateTokenBinding?: boolean; - jwtAccessTokenClaims?: string[]; + jwtAccessTokenAttributesConfiguration?: JWTAccessTokenConfigurationInterface; } +interface JWTAccessTokenConfigurationInterface { + enable?: boolean; + attributes?: string[]; +} interface RefreshTokenConfigurationInterface { expiryInSeconds?: number; renewRefreshToken?: boolean; diff --git a/modules/i18n/src/models/namespaces/applications-ns.ts b/modules/i18n/src/models/namespaces/applications-ns.ts index 94a5fa8f634..03dcd75e2a7 100644 --- a/modules/i18n/src/models/namespaces/applications-ns.ts +++ b/modules/i18n/src/models/namespaces/applications-ns.ts @@ -1274,6 +1274,9 @@ export interface ApplicationsNS { label:string; description: string; placeholder: string; + enable: { + label: string; + }; }; }; }; diff --git a/modules/i18n/src/translations/en-US/portals/applications.ts b/modules/i18n/src/translations/en-US/portals/applications.ts index b137bf834ba..1e6dd3b5202 100644 --- a/modules/i18n/src/translations/en-US/portals/applications.ts +++ b/modules/i18n/src/translations/en-US/portals/applications.ts @@ -1524,6 +1524,9 @@ export const applications: ApplicationsNS = { label: "JWT Access Token Attributes", description: "Define the attributes that should be included in the JWT access token.", placeholder: "Search by attribute name", + enable: { + label: "Enable JWT Access Token Attributes Feature" + } } }, heading: "Access Token", From 98ac02c62ebef14c55833cab553fcf6d96c7342e Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Thu, 8 Aug 2024 10:46:04 +0530 Subject: [PATCH 04/23] fixed for api changes --- .../components/forms/inbound-oidc-form.tsx | 75 ++++++++----------- .../models/application-inbound.ts | 8 +- .../src/models/namespaces/applications-ns.ts | 2 +- .../en-US/portals/applications.ts | 2 +- 4 files changed, 37 insertions(+), 50 deletions(-) diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index 862d637d785..1181b2ecd0b 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -261,9 +261,9 @@ export const InboundOIDCForm: FunctionComponent = ] = useState(false); const [ activeOption, setActiveOption ] = useState(undefined); const [ selectedTokenType, setSelectedTokenType ] = useState(undefined); - const [ selectedJwtAccessTokenAttributes, setSelectedJwtAccessTokenAttributes ] = useState(undefined); - const [ jwtAccessTokenAttributes, setJwtAccessTokenAttributes ] = useState([]); - const [ jwtAccessTokenAttributesEnabled, setJwtAccessTokenAttributesEnabled ] = useState(false); + const [ selectedAccessTokenAttributes, setSelectedAccessTokenAttributes ] = useState(undefined); + const [ accessTokenAttributes, setAccessTokenAttributes ] = useState([]); + const [ accessTokenAttributesEnabled, setAccessTokenAttributesEnabled ] = useState(false); const [ isSubjectTokenEnabled, setIsSubjectTokenEnabled ] = useState(false); const [ isSubjectTokenFeatureAvailable, setIsSubjectTokenFeatureAvailable ] = useState(false); const config: ConfigReducerStateInterface = useSelector((state: AppState) => state.config); @@ -304,7 +304,7 @@ export const InboundOIDCForm: FunctionComponent = const requestObjectSigningAlg: MutableRefObject = useRef(); const requestObjectEncryptionAlgorithm: MutableRefObject = useRef(); const requestObjectEncryptionMethod: MutableRefObject = useRef(); - const jwtAccessTokenAttributesEnabledConfig: MutableRefObject = useRef(); + const accessTokenAttributesEnabledConfig: MutableRefObject = useRef(); const subjectToken: MutableRefObject = useRef(); const applicationSubjectTokenExpiryInSeconds: MutableRefObject = useRef(); @@ -456,7 +456,7 @@ export const InboundOIDCForm: FunctionComponent = getAllExternalClaims("aHR0cDovL3dzbzIub3JnL29pZGMvY2xhaW0", null) .then((response: ExternalClaim[]) => { console.log("External claims response: ", response); - setJwtAccessTokenAttributes(response); + setAccessTokenAttributes(response); }) .catch(() => { console.log("Error while fetching external claims"); @@ -464,16 +464,16 @@ export const InboundOIDCForm: FunctionComponent = }, []); useEffect(() => { - if (!initialValues.accessToken.jwtAccessTokenAttributesConfiguration.attributes) { + if (!initialValues.accessToken.accessTokenAttributes) { return; } - const selectedClaims = initialValues.accessToken.jwtAccessTokenAttributesConfiguration.attributes - .map((claim: string) => jwtAccessTokenAttributes.find((claimObj: ExternalClaim) => claimObj.claimURI === claim)) + const selectedClaims = initialValues.accessToken.accessTokenAttributes + .map((claim: string) => accessTokenAttributes.find((claimObj: ExternalClaim) => claimObj.claimURI === claim)) .filter((claimObj: ExternalClaim | undefined) => claimObj !== undefined); - setSelectedJwtAccessTokenAttributes(selectedClaims); - setJwtAccessTokenAttributesEnabled(initialValues.accessToken.jwtAccessTokenAttributesConfiguration.enable) - }, [jwtAccessTokenAttributes]); + setSelectedAccessTokenAttributes(selectedClaims); + setAccessTokenAttributesEnabled(initialValues.accessToken.accessTokenAttributesEnabled) + }, [accessTokenAttributes]); useEffect(() => { const isSharedWithAll: additionalSpProperty[] = application?.advancedConfigurations @@ -754,12 +754,6 @@ export const InboundOIDCForm: FunctionComponent = setGrantChanged(!isGrantChanged); }; - const handleTokenTypeChange = (values: Map) => { - let tokenType: string = values.get("type") as string; - - setSelectedTokenType(tokenType); - }; - const getMetadataHints = (element: string) => { switch (element.toLowerCase()) { case "none": @@ -1267,10 +1261,8 @@ const getAllowedListForAccessToken = ( type: values.get("type"), userAccessTokenExpiryInSeconds: Number(values.get("userAccessTokenExpiryInSeconds")), validateTokenBinding: values.get("ValidateTokenBinding")?.length > 0, - jwtAccessTokenAttributesConfiguration: { - attributes: selectedJwtAccessTokenAttributes.map((claim: ExternalClaim) => claim.claimURI), - enable: jwtAccessTokenAttributesEnabled - } + accessTokenAttributes: selectedAccessTokenAttributes.map((claim: ExternalClaim) => claim.claimURI), + accessTokenAttributesEnabled: accessTokenAttributesEnabled }, grantTypes: values.get("grant"), idToken: { @@ -2652,15 +2644,14 @@ const getAllowedListForAccessToken = ( ); } } readOnly={ readOnly } - listen={ (values: Map) => handleTokenTypeChange(values) } data-testid={ `${ testId }-access-token-type-radio-group` } /> - { selectedTokenType === "JWT" ? ( + { isJWTAccessTokenTypeSelected ? ( { t("applications:forms.inboundOIDC.sections" + - ".accessToken.fields.jwtAccessTokenAttributes.label") } + ".accessToken.fields.accessTokenAttributes.label") } @@ -2669,9 +2660,9 @@ const getAllowedListForAccessToken = ( multiple disableCloseOnSelect loading={ isLoading } - options={ jwtAccessTokenAttributes } - value={ selectedJwtAccessTokenAttributes ?? [] } - disabled = { !initialValues?.accessToken?.jwtAccessTokenAttributesConfiguration.enable } + options={ accessTokenAttributes } + value={ selectedAccessTokenAttributes ?? [] } + disabled = { !initialValues?.accessToken?.accessTokenAttributesEnabled } data-componentid={ `${ componentId }-assigned-jwt-attribute-list` } getOptionLabel={ (claim: ExternalClaim) => claim.claimURI @@ -2680,12 +2671,12 @@ const getAllowedListForAccessToken = ( ) } onChange={ (event: SyntheticEvent, claims: ExternalClaim[]) => { setIsFormStale(true); - setSelectedJwtAccessTokenAttributes(claims); + setSelectedAccessTokenAttributes(claims); } } isOptionEqualToValue={ (option: ExternalClaim, value: ExternalClaim) => @@ -2702,7 +2693,7 @@ const getAllowedListForAccessToken = ( activeOption={ activeOption } setActiveOption={ setActiveOption } variant={ - jwtAccessTokenAttributes?.find( + accessTokenAttributes?.find( (claim: ExternalClaim) => claim.id === option.id ) ? "solid" @@ -2727,41 +2718,41 @@ const getAllowedListForAccessToken = ( values={ { productName: config.ui.productName } } i18nKey={ "applications:forms.inboundOIDC.sections." + - "jwtAccessTokenAttributes.description" + "accessTokenAttributes.description" } > Define the attributes that should be included in the JWT access token - {!initialValues?.accessToken?.jwtAccessTokenAttributesConfiguration.enable && ( + {!initialValues?.accessToken?.accessTokenAttributesEnabled && ( ): void => { - const jwtAccessTokenAttributesEnabled: boolean = values.get("jwtAccessTokenAttributesEnabledConfig") - .includes("jwtAccessTokenAttributesEnabled"); + const accessTokenAttributesEnabled: boolean = values.get("accessTokenAttributesEnabledConfig") + .includes("accessTokenAttributesEnabled"); - setJwtAccessTokenAttributesEnabled(jwtAccessTokenAttributesEnabled); + setAccessTokenAttributesEnabled(accessTokenAttributesEnabled); } } value={ - initialValues?.accessToken?.jwtAccessTokenAttributesConfiguration.enable - ? [ "jwtAccessTokenAttributesEnabled" ] + initialValues?.accessToken?.accessTokenAttributesEnabled + ? [ "accessTokenAttributesEnabled" ] : [] } children={ [ { label: t("applications:forms.inboundOIDC.sections" + - ".accessToken.fields.jwtAccessTokenAttributes.enable.label"), - value: "jwtAccessTokenAttributesEnabled" + ".accessToken.fields.accessTokenAttributes.enable.label"), + value: "accessTokenAttributesEnabled" } ] } readOnly={ readOnly } - data-testid={ `${ testId }-jwtAccessTokenAttributesEnabled-checkbox` } + data-testid={ `${ testId }-access-token-attributes-enabled-checkbox` } /> )} diff --git a/features/admin.applications.v1/models/application-inbound.ts b/features/admin.applications.v1/models/application-inbound.ts index d95bfb5fae5..753bff2ca37 100644 --- a/features/admin.applications.v1/models/application-inbound.ts +++ b/features/admin.applications.v1/models/application-inbound.ts @@ -127,12 +127,8 @@ interface AccessTokenConfigurationInterface { bindingType?: SupportedAccessTokenBindingTypes | string; revokeTokensWhenIDPSessionTerminated?: boolean; validateTokenBinding?: boolean; - jwtAccessTokenAttributesConfiguration?: JWTAccessTokenConfigurationInterface; -} - -interface JWTAccessTokenConfigurationInterface { - enable?: boolean; - attributes?: string[]; + accessTokenAttributes?: string[]; + accessTokenAttributesEnabled?: boolean; } interface RefreshTokenConfigurationInterface { expiryInSeconds?: number; diff --git a/modules/i18n/src/models/namespaces/applications-ns.ts b/modules/i18n/src/models/namespaces/applications-ns.ts index cd3898f142d..5c252124904 100644 --- a/modules/i18n/src/models/namespaces/applications-ns.ts +++ b/modules/i18n/src/models/namespaces/applications-ns.ts @@ -1323,7 +1323,7 @@ export interface ApplicationsNS { invalid: string; }; }; - jwtAccessTokenAttributes: { + accessTokenAttributes: { hint: string; label:string; description: string; diff --git a/modules/i18n/src/translations/en-US/portals/applications.ts b/modules/i18n/src/translations/en-US/portals/applications.ts index 04bdf407bbc..05fee4c6fb7 100644 --- a/modules/i18n/src/translations/en-US/portals/applications.ts +++ b/modules/i18n/src/translations/en-US/portals/applications.ts @@ -1575,7 +1575,7 @@ export const applications: ApplicationsNS = { invalid: "Please avoid special characters like commas (,)" } }, - jwtAccessTokenAttributes: { + accessTokenAttributes: { hint : "", label: "JWT Access Token Attributes", description: "Define the attributes that should be included in the JWT access token.", From 3a887ca7fa0a314b2adb27a5983869ba9fe914d5 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Fri, 9 Aug 2024 14:17:11 +0530 Subject: [PATCH 05/23] add atributes display names --- .../access-token-attribute-option.tsx} | 15 ++- .../components/forms/inbound-oidc-form.tsx | 106 +++++++++++++----- .../src/models/namespaces/applications-ns.ts | 2 +- .../en-US/portals/applications.ts | 8 +- 4 files changed, 94 insertions(+), 37 deletions(-) rename features/admin.applications.v1/components/{auto-complete-render-option.tsx => components/access-token-attribute-option.tsx} (81%) diff --git a/features/admin.applications.v1/components/auto-complete-render-option.tsx b/features/admin.applications.v1/components/components/access-token-attribute-option.tsx similarity index 81% rename from features/admin.applications.v1/components/auto-complete-render-option.tsx rename to features/admin.applications.v1/components/components/access-token-attribute-option.tsx index 39cee3d8860..8caff9eef35 100644 --- a/features/admin.applications.v1/components/auto-complete-render-option.tsx +++ b/features/admin.applications.v1/components/components/access-token-attribute-option.tsx @@ -1,5 +1,5 @@ /** - * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). * * WSO2 LLC. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -20,13 +20,14 @@ import Checkbox from "@oxygen-ui/react/Checkbox"; import Grid from "@oxygen-ui/react/Grid"; import ListItemText from "@oxygen-ui/react/ListItemText"; import { IdentifiableComponentInterface } from "@wso2is/core/models"; +import { Code } from "@wso2is/react-components"; import React, { FunctionComponent, HTMLAttributes, ReactElement } from "react"; -interface AutoCompleteRenderOption extends IdentifiableComponentInterface { +interface AccessTokenAttributeOption extends IdentifiableComponentInterface { /** * Is the option selected. */ @@ -35,19 +36,24 @@ interface AutoCompleteRenderOption extends IdentifiableComponentInterface { * The display name of the option. */ displayName: string; + /** + * The claim URI of the option. + */ + claimURI: string; /** * The props passed to the option. */ renderOptionProps: HTMLAttributes } -export const AutoCompleteRenderOption: FunctionComponent = ( - props: AutoCompleteRenderOption +export const AccessTokenAttributeOption: FunctionComponent = ( + props: AccessTokenAttributeOption ): ReactElement => { const { selected, displayName, + claimURI, renderOptionProps } = props; @@ -64,6 +70,7 @@ export const AutoCompleteRenderOption: FunctionComponent + {claimURI} diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index 1181b2ecd0b..9ef7f0a7435 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -28,7 +28,7 @@ import { applicationConfig } from "@wso2is/admin.extensions.v1"; import FeatureStatusLabel from "@wso2is/admin.extensions.v1/components/feature-gate/models/feature-gate"; import { ImpersonationConfigConstants } from "@wso2is/admin.impersonation.v1/constants/impersonation-configuration"; import { getSharedOrganizations } from "@wso2is/admin.organizations.v1/api"; -import { getAllExternalClaims } from "@wso2is/admin.claims.v1/api"; +import { getAllExternalClaims, getAllLocalClaims } from "@wso2is/admin.claims.v1/api"; import { OrganizationType } from "@wso2is/admin.organizations.v1/constants"; import { OrganizationInterface, OrganizationResponseInterface } from "@wso2is/admin.organizations.v1/models"; import { IdentityAppsApiException } from "@wso2is/core/exceptions"; @@ -58,7 +58,7 @@ import { URLInput } from "@wso2is/react-components"; import TextField from "@oxygen-ui/react/TextField"; -import { AutoCompleteRenderOption } from "./../auto-complete-render-option"; +import { AccessTokenAttributeOption } from "../components/access-token-attribute-option"; import { FormValidation } from "@wso2is/validation"; import { AxiosResponse } from "axios"; import get from "lodash-es/get"; @@ -74,11 +74,12 @@ import React, { MutableRefObject, ReactElement, SyntheticEvent, + useCallback, useEffect, useRef, useState } from "react"; -import { ExternalClaim } from "@wso2is/core/models"; +import { ExternalClaim, Claim } from "@wso2is/core/models"; import { Trans, useTranslation } from "react-i18next"; import { useDispatch, useSelector } from "react-redux"; import { Dispatch } from "redux"; @@ -113,7 +114,9 @@ import { } from "../../models"; import { ApplicationManagementUtils } from "../../utils/application-management-utils"; import { ApplicationCertificateWrapper } from "../settings/certificate"; +import { OIDCScopesManagementConstants } from "../../../admin.oidc-scopes.v1/constants"; import "./inbound-oidc-form.scss"; +import InputLabel from "@oxygen-ui/react/InputLabel"; /** * Proptypes for the inbound OIDC form component. @@ -260,7 +263,8 @@ export const InboundOIDCForm: FunctionComponent = setRefreshTokenWithoutAlllowdGrantType ] = useState(false); const [ activeOption, setActiveOption ] = useState(undefined); - const [ selectedTokenType, setSelectedTokenType ] = useState(undefined); + const [ claims, setClaims ] = useState([]); + const [ externalClaims, setExternalClaims ] = useState([]); const [ selectedAccessTokenAttributes, setSelectedAccessTokenAttributes ] = useState(undefined); const [ accessTokenAttributes, setAccessTokenAttributes ] = useState([]); const [ accessTokenAttributesEnabled, setAccessTokenAttributesEnabled ] = useState(false); @@ -452,26 +456,69 @@ export const InboundOIDCForm: FunctionComponent = ); }, [ application ]); - useEffect(() => { - getAllExternalClaims("aHR0cDovL3dzbzIub3JnL29pZGMvY2xhaW0", null) + const fetchLocalClaims = useCallback(() => { + getAllLocalClaims(null) + .then((response: Claim[]) => { + setClaims(response); + }) + .catch(() => { + dispatch(addAlert({ + description: t("claims:local.notifications.fetchLocalClaims.genericError.description"), + level: AlertLevels.ERROR, + message: t("claims:local.notifications.fetchLocalClaims.genericError.message") + })); + }); + }, []); + + const fetchExternalClaims = useCallback(() => { + getAllExternalClaims(OIDCScopesManagementConstants.OIDC_ATTRIBUTE_ID, null) .then((response: ExternalClaim[]) => { - console.log("External claims response: ", response); - setAccessTokenAttributes(response); + setExternalClaims(response); }) .catch(() => { - console.log("Error while fetching external claims"); + dispatch(addAlert({ + description: t("claims:external.notifications.fetchExternalClaims.genericError.description"), + level: AlertLevels.ERROR, + message: t("claims:external.notifications.fetchExternalClaims.genericError.message") + })); }); }, []); + useEffect(() => { + fetchLocalClaims(); + fetchExternalClaims(); + }, []); + + + useEffect(() => { + if (claims.length && externalClaims.length) { + const updatedAttributes = externalClaims.map((externalClaim) => { + const matchedLocalClaim = claims.find((localClaim) => + localClaim.claimURI === externalClaim.mappedLocalClaimURI + ); + + if (matchedLocalClaim && matchedLocalClaim.displayName) { + return { + ...externalClaim, + localClaimDisplayName: matchedLocalClaim.displayName + }; + } + return externalClaim; + }); + console.log(updatedAttributes); + setAccessTokenAttributes(updatedAttributes); + } + }, [claims, externalClaims]); + useEffect(() => { if (!initialValues.accessToken.accessTokenAttributes) { return; } - const selectedClaims = initialValues.accessToken.accessTokenAttributes + const selectedAttributes = initialValues.accessToken.accessTokenAttributes .map((claim: string) => accessTokenAttributes.find((claimObj: ExternalClaim) => claimObj.claimURI === claim)) .filter((claimObj: ExternalClaim | undefined) => claimObj !== undefined); - setSelectedAccessTokenAttributes(selectedClaims); + setSelectedAccessTokenAttributes(selectedAttributes); setAccessTokenAttributesEnabled(initialValues.accessToken.accessTokenAttributesEnabled) }, [accessTokenAttributes]); @@ -636,9 +683,6 @@ export const InboundOIDCForm: FunctionComponent = setAllowedOrigins(initialValues.allowedOrigins.toString()); } - setSelectedTokenType(initialValues?.accessToken? initialValues.accessToken.type - : metadata?.accessTokenType?.defaultValue); - }, [ initialValues ]); @@ -2633,9 +2677,11 @@ const getAllowedListForAccessToken = ( ".accessToken.fields.type.label") } name="type" - value={ selectedTokenType ?? initialValues?.accessToken - ? initialValues.accessToken.type - : metadata?.accessTokenType?.defaultValue } + default={ + initialValues?.accessToken + ? initialValues.accessToken.type + : metadata?.accessTokenType?.defaultValue + } type="radio" children={ getAllowedListForAccessToken(metadata?.accessTokenType, false) } listen={ (values: Map) => { @@ -2648,12 +2694,6 @@ const getAllowedListForAccessToken = ( /> { isJWTAccessTokenTypeSelected ? ( - - - { t("applications:forms.inboundOIDC.sections" + - ".accessToken.fields.accessTokenAttributes.label") } - - claim.claimURI } renderInput={ (params: AutocompleteRenderInputParams) => ( + <> + + { t( + "applications:forms.inboundOIDC.sections" + + ".accessToken.fields.accessTokenAttributes.label" + ) } + + ) } onChange={ (event: SyntheticEvent, claims: ExternalClaim[]) => { + console.log(accessTokenAttributes) setIsFormStale(true); setSelectedAccessTokenAttributes(claims); } } @@ -2706,9 +2755,10 @@ const getAllowedListForAccessToken = ( option: ExternalClaim, { selected }: { selected: boolean } ) => ( - ) } @@ -2718,10 +2768,10 @@ const getAllowedListForAccessToken = ( values={ { productName: config.ui.productName } } i18nKey={ "applications:forms.inboundOIDC.sections." + - "accessTokenAttributes.description" + "accessTokenAttributes.hint" } > - Define the attributes that should be included in the JWT access token + Select the attributes that should be included in the access token diff --git a/modules/i18n/src/models/namespaces/applications-ns.ts b/modules/i18n/src/models/namespaces/applications-ns.ts index 5c252124904..687ee0883a2 100644 --- a/modules/i18n/src/models/namespaces/applications-ns.ts +++ b/modules/i18n/src/models/namespaces/applications-ns.ts @@ -1326,9 +1326,9 @@ export interface ApplicationsNS { accessTokenAttributes: { hint: string; label:string; - description: string; placeholder: string; enable: { + hint: string; label: string; }; }; diff --git a/modules/i18n/src/translations/en-US/portals/applications.ts b/modules/i18n/src/translations/en-US/portals/applications.ts index 05fee4c6fb7..ffc7196251f 100644 --- a/modules/i18n/src/translations/en-US/portals/applications.ts +++ b/modules/i18n/src/translations/en-US/portals/applications.ts @@ -1576,12 +1576,12 @@ export const applications: ApplicationsNS = { } }, accessTokenAttributes: { - hint : "", - label: "JWT Access Token Attributes", - description: "Define the attributes that should be included in the JWT access token.", + hint : "Select the attributes that should be included in the <1>access_token.", + label: "Access Token Attributes", placeholder: "Search by attribute name", enable: { - label: "Enable JWT Access Token Attributes Feature" + hint : "", + label: "Enable Access Token Attributes Feature" } } }, From 1325a5574e0e05db8f11854605229e7ec0340411 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Fri, 9 Aug 2024 14:19:08 +0530 Subject: [PATCH 06/23] remove css class --- .../components/forms/inbound-oidc-form.scss | 4 ---- 1 file changed, 4 deletions(-) diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.scss b/features/admin.applications.v1/components/forms/inbound-oidc-form.scss index 07b3197d484..eb839f25c2f 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.scss +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.scss @@ -27,7 +27,3 @@ width: auto !important; } } -.jwt-attributes-dropdown-label-column { - margin-bottom: 0.3rem !important; - font-size: 0.9rem !important; -} From 0b466c75ab75c7fb39d2ba452db2b337dc70d1e1 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Fri, 9 Aug 2024 14:19:50 +0530 Subject: [PATCH 07/23] fix .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index d9c52067f0d..4dc86502f6c 100644 --- a/.gitignore +++ b/.gitignore @@ -130,4 +130,3 @@ identity-apps-core/apps/*/src/main/webapp/includes/layouts .repository/ apps/console/src/extensions/i18n/tmp/** .nx -.pnpm-store/ From 273b4deba535bf8063cbea1f5f4a3b463ee0b7b4 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Fri, 9 Aug 2024 15:20:12 +0530 Subject: [PATCH 08/23] fix lint --- .../access-token-attribute-option.tsx | 4 +- .../components/forms/inbound-oidc-form.tsx | 268 +++++++++--------- 2 files changed, 139 insertions(+), 133 deletions(-) diff --git a/features/admin.applications.v1/components/components/access-token-attribute-option.tsx b/features/admin.applications.v1/components/components/access-token-attribute-option.tsx index 8caff9eef35..5b9a8735b4f 100644 --- a/features/admin.applications.v1/components/components/access-token-attribute-option.tsx +++ b/features/admin.applications.v1/components/components/access-token-attribute-option.tsx @@ -69,8 +69,8 @@ export const AccessTokenAttributeOption: FunctionComponent - - {claimURI} + + { claimURI } diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index 9ef7f0a7435..44e2f796d4b 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -22,19 +22,23 @@ import Autocomplete, { } from "@oxygen-ui/react/Autocomplete"; import Box from "@oxygen-ui/react/Box"; import Chip from "@oxygen-ui/react/Chip"; +import InputLabel from "@oxygen-ui/react/InputLabel"; +import TextField from "@oxygen-ui/react/TextField"; +import { getAllExternalClaims, getAllLocalClaims } from "@wso2is/admin.claims.v1/api"; import { AppState, ConfigReducerStateInterface } from "@wso2is/admin.core.v1"; import useGlobalVariables from "@wso2is/admin.core.v1/hooks/use-global-variables"; import { applicationConfig } from "@wso2is/admin.extensions.v1"; import FeatureStatusLabel from "@wso2is/admin.extensions.v1/components/feature-gate/models/feature-gate"; import { ImpersonationConfigConstants } from "@wso2is/admin.impersonation.v1/constants/impersonation-configuration"; import { getSharedOrganizations } from "@wso2is/admin.organizations.v1/api"; -import { getAllExternalClaims, getAllLocalClaims } from "@wso2is/admin.claims.v1/api"; import { OrganizationType } from "@wso2is/admin.organizations.v1/constants"; import { OrganizationInterface, OrganizationResponseInterface } from "@wso2is/admin.organizations.v1/models"; import { IdentityAppsApiException } from "@wso2is/core/exceptions"; import { isFeatureEnabled } from "@wso2is/core/helpers"; import { AlertLevels, + Claim, + ExternalClaim, FeatureAccessConfigInterface, IdentifiableComponentInterface, TestableComponentInterface @@ -57,8 +61,6 @@ import { Text, URLInput } from "@wso2is/react-components"; -import TextField from "@oxygen-ui/react/TextField"; -import { AccessTokenAttributeOption } from "../components/access-token-attribute-option"; import { FormValidation } from "@wso2is/validation"; import { AxiosResponse } from "axios"; import get from "lodash-es/get"; @@ -79,11 +81,11 @@ import React, { useRef, useState } from "react"; -import { ExternalClaim, Claim } from "@wso2is/core/models"; import { Trans, useTranslation } from "react-i18next"; import { useDispatch, useSelector } from "react-redux"; import { Dispatch } from "redux"; import { Button, Container, Divider, DropdownProps, Form, Grid, Label, List, Table } from "semantic-ui-react"; +import { OIDCScopesManagementConstants } from "../../../admin.oidc-scopes.v1/constants"; import { getGeneralIcons } from "../../configs/ui"; import { ApplicationManagementConstants } from "../../constants"; import CustomApplicationTemplate from @@ -113,10 +115,9 @@ import { additionalSpProperty } from "../../models"; import { ApplicationManagementUtils } from "../../utils/application-management-utils"; +import { AccessTokenAttributeOption } from "../components/access-token-attribute-option"; import { ApplicationCertificateWrapper } from "../settings/certificate"; -import { OIDCScopesManagementConstants } from "../../../admin.oidc-scopes.v1/constants"; import "./inbound-oidc-form.scss"; -import InputLabel from "@oxygen-ui/react/InputLabel"; /** * Proptypes for the inbound OIDC form component. @@ -456,7 +457,7 @@ export const InboundOIDCForm: FunctionComponent = ); }, [ application ]); - const fetchLocalClaims = useCallback(() => { + const fetchLocalClaims: () => void = useCallback(() => { getAllLocalClaims(null) .then((response: Claim[]) => { setClaims(response); @@ -470,7 +471,7 @@ export const InboundOIDCForm: FunctionComponent = }); }, []); - const fetchExternalClaims = useCallback(() => { + const fetchExternalClaims: () => void = useCallback(() => { getAllExternalClaims(OIDCScopesManagementConstants.OIDC_ATTRIBUTE_ID, null) .then((response: ExternalClaim[]) => { setExternalClaims(response); @@ -492,35 +493,37 @@ export const InboundOIDCForm: FunctionComponent = useEffect(() => { if (claims.length && externalClaims.length) { - const updatedAttributes = externalClaims.map((externalClaim) => { - const matchedLocalClaim = claims.find((localClaim) => + const updatedAttributes : ExternalClaim[] = externalClaims.map((externalClaim : ExternalClaim) => { + const matchedLocalClaim: Claim = claims.find((localClaim: Claim) => localClaim.claimURI === externalClaim.mappedLocalClaimURI ); - + if (matchedLocalClaim && matchedLocalClaim.displayName) { return { ...externalClaim, localClaimDisplayName: matchedLocalClaim.displayName }; } + return externalClaim; }); - console.log(updatedAttributes); + setAccessTokenAttributes(updatedAttributes); } - }, [claims, externalClaims]); + }, [ claims, externalClaims ]); useEffect(() => { if (!initialValues.accessToken.accessTokenAttributes) { return; } - const selectedAttributes = initialValues.accessToken.accessTokenAttributes - .map((claim: string) => accessTokenAttributes.find((claimObj: ExternalClaim) => claimObj.claimURI === claim)) - .filter((claimObj: ExternalClaim | undefined) => claimObj !== undefined); + const selectedAttributes: ExternalClaim[] = initialValues.accessToken.accessTokenAttributes + .map((claim: string) => accessTokenAttributes + .find((claimObj: ExternalClaim) => claimObj.claimURI === claim)) + .filter((claimObj: ExternalClaim | undefined) => claimObj !== undefined); setSelectedAccessTokenAttributes(selectedAttributes); - setAccessTokenAttributesEnabled(initialValues.accessToken.accessTokenAttributesEnabled) - }, [accessTokenAttributes]); + setAccessTokenAttributesEnabled(initialValues.accessToken.accessTokenAttributesEnabled); + }, [ accessTokenAttributes ]); useEffect(() => { const isSharedWithAll: additionalSpProperty[] = application?.advancedConfigurations @@ -928,7 +931,7 @@ export const InboundOIDCForm: FunctionComponent = * @param isBinding - Indicate whether binding is true or false. * @returns a list of options for radio. */ -const getAllowedListForAccessToken = ( + const getAllowedListForAccessToken = ( metadataProp: MetadataPropertyInterface, isBinding?: boolean): RadioChild[] => { const allowedList: RadioChild[] = []; @@ -2692,122 +2695,125 @@ const getAllowedListForAccessToken = ( readOnly={ readOnly } data-testid={ `${ testId }-access-token-type-radio-group` } /> - { isJWTAccessTokenTypeSelected ? ( - - - claim.claimURI - } - renderInput={ (params: AutocompleteRenderInputParams) => ( - <> - - { t( - "applications:forms.inboundOIDC.sections" + - ".accessToken.fields.accessTokenAttributes.label" + { isJWTAccessTokenTypeSelected ? ( + + + claim.claimURI + } + renderInput={ (params: AutocompleteRenderInputParams) => ( + <> + + { t( + "applications:forms.inboundOIDC.sections" + + ".accessToken.fields.accessTokenAttributes.label" + ) } + + + ) } - - - - ) } - onChange={ (event: SyntheticEvent, claims: ExternalClaim[]) => { - console.log(accessTokenAttributes) - setIsFormStale(true); - setSelectedAccessTokenAttributes(claims); - } } - isOptionEqualToValue={ - (option: ExternalClaim, value: ExternalClaim) => - option.id === value.id - } - renderTags={ ( - value: ExternalClaim[], - getTagProps: AutocompleteRenderGetTagProps - ) => value.map((option: ExternalClaim, index: number) => ( - claim.id === option.id - ) - ? "solid" - : "outlined" + onChange={ (event: SyntheticEvent, claims: ExternalClaim[]) => { + setIsFormStale(true); + setSelectedAccessTokenAttributes(claims); + } } + isOptionEqualToValue={ + (option: ExternalClaim, value: ExternalClaim) => + option.id === value.id } + renderTags={ ( + value: ExternalClaim[], + getTagProps: AutocompleteRenderGetTagProps + ) => value.map((option: ExternalClaim, index: number) => ( + claim.id === option.id + ) + ? "solid" + : "outlined" + } + /> + )) } + renderOption={ ( + props: HTMLAttributes, + option: ExternalClaim, + { selected }: { selected: boolean } + ) => ( + + ) } /> - )) } - renderOption={ ( - props: HTMLAttributes, - option: ExternalClaim, - { selected }: { selected: boolean } - ) => ( - + + + Select the attributes that should be included in + the access token + + + + { !initialValues?.accessToken?.accessTokenAttributesEnabled && ( + + ): void => { + const accessTokenAttributesEnabled: boolean = + values.get("accessTokenAttributesEnabledConfig") + .includes("accessTokenAttributesEnabled"); + + setAccessTokenAttributesEnabled(accessTokenAttributesEnabled); + } } + value={ + initialValues?.accessToken?.accessTokenAttributesEnabled + ? [ "accessTokenAttributesEnabled" ] + : [] + } + children={ [ + { + label: t("applications:forms.inboundOIDC.sections" + + ".accessToken.fields.accessTokenAttributes.enable.label"), + value: "accessTokenAttributesEnabled" + } + ] } + readOnly={ readOnly } + data-testid={ `${ testId }-access-token-attributes-enabled-checkbox` } + /> + ) } - /> - - - Select the attributes that should be included in the access token - - - - {!initialValues?.accessToken?.accessTokenAttributesEnabled && ( - - ): void => { - const accessTokenAttributesEnabled: boolean = values.get("accessTokenAttributesEnabledConfig") - .includes("accessTokenAttributesEnabled"); - - setAccessTokenAttributesEnabled(accessTokenAttributesEnabled); - } } - value={ - initialValues?.accessToken?.accessTokenAttributesEnabled - ? [ "accessTokenAttributesEnabled" ] - : [] - } - children={ [ - { - label: t("applications:forms.inboundOIDC.sections" + - ".accessToken.fields.accessTokenAttributes.enable.label"), - value: "accessTokenAttributesEnabled" - } - ] } - readOnly={ readOnly } - data-testid={ `${ testId }-access-token-attributes-enabled-checkbox` } - /> - - )} - - ) : null } + + ) : null } ) From 39b199ac5dd2ccf23a2fac5e2b5df179612afde9 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Fri, 9 Aug 2024 16:02:09 +0530 Subject: [PATCH 09/23] fix lint --- .../components/forms/inbound-oidc-form.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index 44e2f796d4b..26cb02691c1 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -1300,6 +1300,8 @@ export const InboundOIDCForm: FunctionComponent = if (!isSystemApplication && !isDefaultApplication) { let inboundConfigFormValues: any = { accessToken: { + accessTokenAttributes: selectedAccessTokenAttributes.map((claim: ExternalClaim) => claim.claimURI), + accessTokenAttributesEnabled: accessTokenAttributesEnabled, applicationAccessTokenExpiryInSeconds: values.get("applicationAccessTokenExpiryInSeconds") ? Number(values.get("applicationAccessTokenExpiryInSeconds")) : Number(metadata?.defaultApplicationAccessTokenExpiryTime), @@ -1307,9 +1309,7 @@ export const InboundOIDCForm: FunctionComponent = revokeTokensWhenIDPSessionTerminated: values.get("RevokeAccessToken")?.length > 0, type: values.get("type"), userAccessTokenExpiryInSeconds: Number(values.get("userAccessTokenExpiryInSeconds")), - validateTokenBinding: values.get("ValidateTokenBinding")?.length > 0, - accessTokenAttributes: selectedAccessTokenAttributes.map((claim: ExternalClaim) => claim.claimURI), - accessTokenAttributesEnabled: accessTokenAttributesEnabled + validateTokenBinding: values.get("ValidateTokenBinding")?.length > 0 }, grantTypes: values.get("grant"), idToken: { From 50a5328842bce83943bc2414a24d9c030aa06910 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Mon, 12 Aug 2024 09:11:21 +0530 Subject: [PATCH 10/23] fix component dir --- .../{components => }/access-token-attribute-option.tsx | 6 +----- .../components/forms/inbound-oidc-form.tsx | 7 +++---- 2 files changed, 4 insertions(+), 9 deletions(-) rename features/admin.applications.v1/components/{components => }/access-token-attribute-option.tsx (91%) diff --git a/features/admin.applications.v1/components/components/access-token-attribute-option.tsx b/features/admin.applications.v1/components/access-token-attribute-option.tsx similarity index 91% rename from features/admin.applications.v1/components/components/access-token-attribute-option.tsx rename to features/admin.applications.v1/components/access-token-attribute-option.tsx index 5b9a8735b4f..f7453b1e4aa 100644 --- a/features/admin.applications.v1/components/components/access-token-attribute-option.tsx +++ b/features/admin.applications.v1/components/access-token-attribute-option.tsx @@ -62,11 +62,7 @@ export const AccessTokenAttributeOption: FunctionComponent - { - typeof selected === "boolean" && ( - - ) - } + diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index 26cb02691c1..1ce857a6acb 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -492,13 +492,13 @@ export const InboundOIDCForm: FunctionComponent = useEffect(() => { - if (claims.length && externalClaims.length) { + if (claims?.length > 0 && externalClaims?.length > 0) { const updatedAttributes : ExternalClaim[] = externalClaims.map((externalClaim : ExternalClaim) => { const matchedLocalClaim: Claim = claims.find((localClaim: Claim) => localClaim.claimURI === externalClaim.mappedLocalClaimURI ); - if (matchedLocalClaim && matchedLocalClaim.displayName) { + if (matchedLocalClaim?.displayName) { return { ...externalClaim, localClaimDisplayName: matchedLocalClaim.displayName @@ -2721,8 +2721,7 @@ export const InboundOIDCForm: FunctionComponent = From 9dcfdeaf6ea07d73042896ef9fd7b15d5ed5f4af Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Mon, 12 Aug 2024 12:07:25 +0530 Subject: [PATCH 11/23] add existing app warning --- .../components/forms/inbound-oidc-form.scss | 6 +- .../components/forms/inbound-oidc-form.tsx | 85 +++++++++++-------- .../en-US/portals/applications.ts | 2 +- 3 files changed, 55 insertions(+), 38 deletions(-) diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.scss b/features/admin.applications.v1/components/forms/inbound-oidc-form.scss index eb839f25c2f..e4a414a20b9 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.scss +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.scss @@ -21,7 +21,11 @@ margin-right: 1rem !important; } -.jwt-attributes-dropdown-input { +.access-token-attributes-dropdown { + padding-top: 1rem !important; +} + +.access-token-attributes-dropdown-input { input { border: none !important; width: auto !important; diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index 1ce857a6acb..669bac41ab4 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -115,9 +115,10 @@ import { additionalSpProperty } from "../../models"; import { ApplicationManagementUtils } from "../../utils/application-management-utils"; -import { AccessTokenAttributeOption } from "../components/access-token-attribute-option"; +import { AccessTokenAttributeOption } from "../access-token-attribute-option"; import { ApplicationCertificateWrapper } from "../settings/certificate"; import "./inbound-oidc-form.scss"; +import Alert from "@oxygen-ui/react/Alert"; /** * Proptypes for the inbound OIDC form component. @@ -2697,8 +2698,52 @@ export const InboundOIDCForm: FunctionComponent = /> { isJWTAccessTokenTypeSelected ? ( + { !initialValues?.accessToken?.accessTokenAttributesEnabled && ( + + + To enable the new Selective Access Token Attributes feature, + select + Enable Access Token Attributes + and update your application, but be aware that this change is + irreversible and will automatically include attributes + (attributes set as requested in the User Attribute section) + in the access_token without + requiring OIDC scopes. Proceed with caution. + + ): void => { + const accessTokenAttributesEnabled: boolean = + values.get("accessTokenAttributesEnabledConfig") + .includes("accessTokenAttributesEnabled"); + + setAccessTokenAttributesEnabled(accessTokenAttributesEnabled); + } } + value={ + initialValues?.accessToken?.accessTokenAttributesEnabled + ? [ "accessTokenAttributesEnabled" ] + : [] + } + children={ [ + { + label: t("applications:forms.inboundOIDC.sections" + + ".accessToken.fields.accessTokenAttributes.enable.label"), + value: "accessTokenAttributesEnabled" + } + ] } + readOnly={ readOnly } + data-testid={ `${ testId }-access-token-attributes-enabled-checkbox` } + /> + + ) } = options={ accessTokenAttributes } value={ selectedAccessTokenAttributes ?? [] } disabled = { !initialValues?.accessToken?.accessTokenAttributesEnabled } - data-componentid={ `${ componentId }-assigned-jwt-attribute-list` } + data-componentid={ `${ componentId }-assigned-access-token-attribute-list` } getOptionLabel={ (claim: ExternalClaim) => claim.claimURI } @@ -2719,7 +2764,7 @@ export const InboundOIDCForm: FunctionComponent = ) } = } > Select the attributes that should be included in - the access token + the access_token. - { !initialValues?.accessToken?.accessTokenAttributesEnabled && ( - - ): void => { - const accessTokenAttributesEnabled: boolean = - values.get("accessTokenAttributesEnabledConfig") - .includes("accessTokenAttributesEnabled"); - - setAccessTokenAttributesEnabled(accessTokenAttributesEnabled); - } } - value={ - initialValues?.accessToken?.accessTokenAttributesEnabled - ? [ "accessTokenAttributesEnabled" ] - : [] - } - children={ [ - { - label: t("applications:forms.inboundOIDC.sections" + - ".accessToken.fields.accessTokenAttributes.enable.label"), - value: "accessTokenAttributesEnabled" - } - ] } - readOnly={ readOnly } - data-testid={ `${ testId }-access-token-attributes-enabled-checkbox` } - /> - - ) } ) : null } diff --git a/modules/i18n/src/translations/en-US/portals/applications.ts b/modules/i18n/src/translations/en-US/portals/applications.ts index ffc7196251f..721d28583e4 100644 --- a/modules/i18n/src/translations/en-US/portals/applications.ts +++ b/modules/i18n/src/translations/en-US/portals/applications.ts @@ -1581,7 +1581,7 @@ export const applications: ApplicationsNS = { placeholder: "Search by attribute name", enable: { hint : "", - label: "Enable Access Token Attributes Feature" + label: "Enable Access Token Attributes" } } }, From 655af5c676622b37f10a5d0ea7bbc7fe5e088914 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Mon, 12 Aug 2024 15:09:39 +0530 Subject: [PATCH 12/23] introduce config to disable access token attributes --- .../resources/deployment.config.json.j2 | 3 +++ apps/console/src/public/deployment.config.json | 1 + .../components/forms/inbound-oidc-form.scss | 4 ++++ .../components/forms/inbound-oidc-form.tsx | 4 ++-- features/admin.core.v1/configs/app.ts | 1 + features/admin.core.v1/models/config.ts | 4 ++++ 6 files changed, 15 insertions(+), 2 deletions(-) diff --git a/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 b/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 index aef08815dc1..e2cd5bf2137 100644 --- a/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 +++ b/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 @@ -1820,6 +1820,9 @@ {% if console.ui.administrator_role_display_name is defined %} "administratorRoleDisplayName": "{{ console.ui.administrator_role_display_name }}", {% endif %} + {% if oauth.oidc.enable_claims_separation_for_access_tokens is defined %} + "enableAccessTokenAttributes": {{ oauth.oidc.enable_claims_separation_for_access_tokens }}, + {% endif %} "legacyMode": { {% if console.ui.legacy_mode.items() is defined %} {% for key, value in console.ui.legacy_mode.items() %} diff --git a/apps/console/src/public/deployment.config.json b/apps/console/src/public/deployment.config.json index 72897c91168..905b5a06f3b 100644 --- a/apps/console/src/public/deployment.config.json +++ b/apps/console/src/public/deployment.config.json @@ -168,6 +168,7 @@ "defaultLogoUrl": "/libs/themes/default/assets/images/branding/logo.svg", "defaultWhiteLogoUrl": "/libs/themes/default/assets/images/branding/logo-inverted.svg" }, + "enableAccessTokenAttributes": true, "enableCustomEmailTemplates": true, "enableEmailDomain": false, "enableIdentityClaims": true, diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.scss b/features/admin.applications.v1/components/forms/inbound-oidc-form.scss index e4a414a20b9..d40910bbdb6 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.scss +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.scss @@ -21,6 +21,10 @@ margin-right: 1rem !important; } +.access-token-attributes-feature-banner { + padding-top: 1rem !important; +} + .access-token-attributes-dropdown { padding-top: 1rem !important; } diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index 669bac41ab4..ef6d0deed37 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -2696,10 +2696,10 @@ export const InboundOIDCForm: FunctionComponent = readOnly={ readOnly } data-testid={ `${ testId }-access-token-type-radio-group` } /> - { isJWTAccessTokenTypeSelected ? ( + { isJWTAccessTokenTypeSelected && config.ui.enableAccessTokenAttributes ? ( { !initialValues?.accessToken?.accessTokenAttributesEnabled && ( - + To enable the new Selective Access Token Attributes feature, select diff --git a/features/admin.core.v1/configs/app.ts b/features/admin.core.v1/configs/app.ts index cec6780da0a..d48e6a790b7 100644 --- a/features/admin.core.v1/configs/app.ts +++ b/features/admin.core.v1/configs/app.ts @@ -294,6 +294,7 @@ export class Config { defaultLogoUrl: window[ "AppUtils" ]?.getConfig()?.ui?.emailTemplates?.defaultLogoUrl, defaultWhiteLogoUrl: window[ "AppUtils" ]?.getConfig()?.ui?.emailTemplates?.defaultWhiteLogoUrl }, + enableAccessTokenAttributes: window["AppUtils"]?.getConfig()?.ui?.enableAccessTokenAttributes, enableCustomEmailTemplates: window[ "AppUtils" ]?.getConfig()?.ui?.enableCustomEmailTemplates, enableEmailDomain: window[ "AppUtils" ]?.getConfig()?.ui?.enableEmailDomain ?? false, enableIdentityClaims: window[ "AppUtils" ]?.getConfig()?.ui?.enableIdentityClaims ?? true, diff --git a/features/admin.core.v1/models/config.ts b/features/admin.core.v1/models/config.ts index 47e289366d9..87813922ff8 100644 --- a/features/admin.core.v1/models/config.ts +++ b/features/admin.core.v1/models/config.ts @@ -445,6 +445,10 @@ export interface UIConfigInterface extends CommonUIConfigInterface Date: Mon, 12 Aug 2024 15:15:38 +0530 Subject: [PATCH 13/23] update warning --- .../components/forms/inbound-oidc-form.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index ef6d0deed37..85aa5cd6a2c 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -2704,11 +2704,12 @@ export const InboundOIDCForm: FunctionComponent = To enable the new Selective Access Token Attributes feature, select Enable Access Token Attributes - and update your application, but be aware that this change is - irreversible and will automatically include attributes - (attributes set as requested in the User Attribute section) - in the access_token without - requiring OIDC scopes. Proceed with caution. + and update your application, but be aware that after this change, + attributes (set as requested in the User Attribute section) + will be automatically included in the + access_token without + requiring OIDC scopes, and this change is irreversible. + Proceed with caution. Date: Mon, 12 Aug 2024 16:57:36 +0530 Subject: [PATCH 14/23] add i8n for feature hint --- .../components/forms/inbound-oidc-form.tsx | 33 ++++++++++--------- .../en-US/portals/applications.ts | 8 ++++- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index 85aa5cd6a2c..263900c8816 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -16,6 +16,7 @@ * under the License. */ +import Alert from "@oxygen-ui/react/Alert"; import Autocomplete, { AutocompleteRenderGetTagProps, AutocompleteRenderInputParams @@ -76,7 +77,6 @@ import React, { MutableRefObject, ReactElement, SyntheticEvent, - useCallback, useEffect, useRef, useState @@ -118,7 +118,6 @@ import { ApplicationManagementUtils } from "../../utils/application-management-u import { AccessTokenAttributeOption } from "../access-token-attribute-option"; import { ApplicationCertificateWrapper } from "../settings/certificate"; import "./inbound-oidc-form.scss"; -import Alert from "@oxygen-ui/react/Alert"; /** * Proptypes for the inbound OIDC form component. @@ -458,7 +457,7 @@ export const InboundOIDCForm: FunctionComponent = ); }, [ application ]); - const fetchLocalClaims: () => void = useCallback(() => { + const fetchLocalClaims = () => { getAllLocalClaims(null) .then((response: Claim[]) => { setClaims(response); @@ -470,9 +469,9 @@ export const InboundOIDCForm: FunctionComponent = message: t("claims:local.notifications.fetchLocalClaims.genericError.message") })); }); - }, []); + }; - const fetchExternalClaims: () => void = useCallback(() => { + const fetchExternalClaims = () => { getAllExternalClaims(OIDCScopesManagementConstants.OIDC_ATTRIBUTE_ID, null) .then((response: ExternalClaim[]) => { setExternalClaims(response); @@ -484,7 +483,7 @@ export const InboundOIDCForm: FunctionComponent = message: t("claims:external.notifications.fetchExternalClaims.genericError.message") })); }); - }, []); + }; useEffect(() => { fetchLocalClaims(); @@ -517,6 +516,7 @@ export const InboundOIDCForm: FunctionComponent = if (!initialValues.accessToken.accessTokenAttributes) { return; } + const selectedAttributes: ExternalClaim[] = initialValues.accessToken.accessTokenAttributes .map((claim: string) => accessTokenAttributes .find((claimObj: ExternalClaim) => claimObj.claimURI === claim)) @@ -2701,15 +2701,18 @@ export const InboundOIDCForm: FunctionComponent = { !initialValues?.accessToken?.accessTokenAttributesEnabled && ( - To enable the new Selective Access Token Attributes feature, - select - Enable Access Token Attributes - and update your application, but be aware that after this change, - attributes (set as requested in the User Attribute section) - will be automatically included in the - access_token without - requiring OIDC scopes, and this change is irreversible. - Proceed with caution. + + To enable the new Selective Access Token Attributes feature, + select Enable Access Token Attributes + and update your application, but be aware that after this change, + attributes (set as requested in the User Attribute section) + will be automatically included in the + access_token without + requiring OIDC scopes, and this change is irreversible. + Proceed with caution. + Enable Access Token Attributes and update your application " + + "and update your application, but be aware that after this change, " + + "attributes (set as requested in the User Attribute section) " + + "will be automatically included in the <1>access_token<1/> without " + + "requiring OIDC scopes, and this change is irreversible. Proceed " + + "with caution.", label: "Enable Access Token Attributes" } } From 73a8a71568fc6659f73d648999c1a3945123a4c1 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Thu, 15 Aug 2024 16:10:24 +0530 Subject: [PATCH 15/23] change description of hint --- .../components/forms/inbound-oidc-form.tsx | 22 ++++++++++++------- .../en-US/portals/applications.ts | 15 +++++++------ 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index 263900c8816..50baf411b6d 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -2704,14 +2704,20 @@ export const InboundOIDCForm: FunctionComponent = - To enable the new Selective Access Token Attributes feature, - select Enable Access Token Attributes - and update your application, but be aware that after this change, - attributes (set as requested in the User Attribute section) - will be automatically included in the - access_token without - requiring OIDC scopes, and this change is irreversible. - Proceed with caution. + Previously, attributes that are set as requested in the User + Attribute section were automatically added to + access_token. + Now, you can choose which user attributes are included in the + access_token. To enable this + new feature, select + Enable Access Token Attributes + and update your application. When updating, + attributes that are set as requested in the User Attribute + section will be set as Access Token Attributes. Once updated, + only selected attributes from the Access Token Attributes will + be included in the access_token + without requiring OIDC scopes. Important: This change is + irreversible. Proceed with caution. Enable Access Token Attributes and update your application " + - "and update your application, but be aware that after this change, " + - "attributes (set as requested in the User Attribute section) " + - "will be automatically included in the <1>access_token<1/> without " + - "requiring OIDC scopes, and this change is irreversible. Proceed " + - "with caution.", + hint : "Previously, attributes that are set as requested in the User Attributes " + + "section were automatically added to <1>access_token. Now, you can choose which " + + "user attributes are included in the <1>access_token. To enable this new feature, " + + "select <1>Enable Access Token Attributes and update your application. When updating, " + + "attributes that are set as requested in the User Attribute section will be set as " + + "Access Token Attributes. Once updated, only selected attributes from the Access " + + "Token Attributes will be included in the <1>access_token without requiring OIDC scopes. " + + "Important: This change is irreversible. Proceed with caution.", label: "Enable Access Token Attributes" } } From 8cc4d015427a53c745a43dad6850a4b766fb45a8 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Fri, 16 Aug 2024 12:16:59 +0530 Subject: [PATCH 16/23] change config --- .../resources/deployment.config.json.j2 | 3 - .../console/src/public/deployment.config.json | 1 - .../components/forms/inbound-oidc-form.tsx | 273 +++++++++--------- features/admin.core.v1/configs/app.ts | 1 - features/admin.core.v1/models/config.ts | 4 - 5 files changed, 137 insertions(+), 145 deletions(-) diff --git a/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 b/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 index e2cd5bf2137..aef08815dc1 100644 --- a/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 +++ b/apps/console/java/org.wso2.identity.apps.console.server.feature/resources/deployment.config.json.j2 @@ -1820,9 +1820,6 @@ {% if console.ui.administrator_role_display_name is defined %} "administratorRoleDisplayName": "{{ console.ui.administrator_role_display_name }}", {% endif %} - {% if oauth.oidc.enable_claims_separation_for_access_tokens is defined %} - "enableAccessTokenAttributes": {{ oauth.oidc.enable_claims_separation_for_access_tokens }}, - {% endif %} "legacyMode": { {% if console.ui.legacy_mode.items() is defined %} {% for key, value in console.ui.legacy_mode.items() %} diff --git a/apps/console/src/public/deployment.config.json b/apps/console/src/public/deployment.config.json index 905b5a06f3b..72897c91168 100644 --- a/apps/console/src/public/deployment.config.json +++ b/apps/console/src/public/deployment.config.json @@ -168,7 +168,6 @@ "defaultLogoUrl": "/libs/themes/default/assets/images/branding/logo.svg", "defaultWhiteLogoUrl": "/libs/themes/default/assets/images/branding/logo-inverted.svg" }, - "enableAccessTokenAttributes": true, "enableCustomEmailTemplates": true, "enableEmailDomain": false, "enableIdentityClaims": true, diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index 50baf411b6d..1ec5dd0662a 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -1301,7 +1301,7 @@ export const InboundOIDCForm: FunctionComponent = if (!isSystemApplication && !isDefaultApplication) { let inboundConfigFormValues: any = { accessToken: { - accessTokenAttributes: selectedAccessTokenAttributes.map((claim: ExternalClaim) => claim.claimURI), + accessTokenAttributes: selectedAccessTokenAttributes?.map((claim: ExternalClaim) => claim.claimURI), accessTokenAttributesEnabled: accessTokenAttributesEnabled, applicationAccessTokenExpiryInSeconds: values.get("applicationAccessTokenExpiryInSeconds") ? Number(values.get("applicationAccessTokenExpiryInSeconds")) @@ -2696,146 +2696,147 @@ export const InboundOIDCForm: FunctionComponent = readOnly={ readOnly } data-testid={ `${ testId }-access-token-type-radio-group` } /> - { isJWTAccessTokenTypeSelected && config.ui.enableAccessTokenAttributes ? ( - - { !initialValues?.accessToken?.accessTokenAttributesEnabled && ( - - - - Previously, attributes that are set as requested in the User - Attribute section were automatically added to - access_token. - Now, you can choose which user attributes are included in the - access_token. To enable this - new feature, select - Enable Access Token Attributes - and update your application. When updating, - attributes that are set as requested in the User Attribute - section will be set as Access Token Attributes. Once updated, - only selected attributes from the Access Token Attributes will - be included in the access_token - without requiring OIDC scopes. Important: This change is - irreversible. Proceed with caution. - - - ): void => { - const accessTokenAttributesEnabled: boolean = - values.get("accessTokenAttributesEnabledConfig") - .includes("accessTokenAttributesEnabled"); + { isJWTAccessTokenTypeSelected && + isFeatureEnabled(applicationFeatureConfig, "applications.accessTokenAttributes") ? ( + + { !initialValues?.accessToken?.accessTokenAttributesEnabled && ( + + + + Previously, attributes that are set as requested in the User + Attribute section were automatically added to + access_token. + Now, you can choose which user attributes are included in the + access_token. To enable this + new feature, select + Enable Access Token Attributes + and update your application. When updating, + attributes that are set as requested in the User Attribute + section will be set as Access Token Attributes. Once updated, + only selected attributes from the Access Token Attributes will + be included in the access_token + without requiring OIDC scopes. Important: This change is + irreversible. Proceed with caution. + + + ): void => { + const accessTokenAttributesEnabled: boolean = + values.get("accessTokenAttributesEnabledConfig") + .includes("accessTokenAttributesEnabled"); - setAccessTokenAttributesEnabled(accessTokenAttributesEnabled); + setAccessTokenAttributesEnabled(accessTokenAttributesEnabled); + } } + value={ + initialValues?.accessToken?.accessTokenAttributesEnabled + ? [ "accessTokenAttributesEnabled" ] + : [] + } + children={ [ + { + label: t("applications:forms.inboundOIDC.sections" + + ".accessToken.fields.accessTokenAttributes.enable.label"), + value: "accessTokenAttributesEnabled" + } + ] } + readOnly={ readOnly } + data-testid={ `${ testId }-access-token-attributes-enabled-checkbox` } + /> + + ) } + + claim.claimURI + } + renderInput={ (params: AutocompleteRenderInputParams) => ( + <> + + { t( + "applications:forms.inboundOIDC.sections" + + ".accessToken.fields.accessTokenAttributes.label" + ) } + + + + ) } + onChange={ (event: SyntheticEvent, claims: ExternalClaim[]) => { + setIsFormStale(true); + setSelectedAccessTokenAttributes(claims); } } - value={ - initialValues?.accessToken?.accessTokenAttributesEnabled - ? [ "accessTokenAttributesEnabled" ] - : [] + isOptionEqualToValue={ + (option: ExternalClaim, value: ExternalClaim) => + option.id === value.id } - children={ [ - { - label: t("applications:forms.inboundOIDC.sections" + - ".accessToken.fields.accessTokenAttributes.enable.label"), - value: "accessTokenAttributesEnabled" - } - ] } - readOnly={ readOnly } - data-testid={ `${ testId }-access-token-attributes-enabled-checkbox` } - /> - - ) } - - claim.claimURI - } - renderInput={ (params: AutocompleteRenderInputParams) => ( - <> - - { t( - "applications:forms.inboundOIDC.sections" + - ".accessToken.fields.accessTokenAttributes.label" - ) } - - value.map((option: ExternalClaim, index: number) => ( + claim.id === option.id + ) + ? "solid" + : "outlined" + } /> - - ) } - onChange={ (event: SyntheticEvent, claims: ExternalClaim[]) => { - setIsFormStale(true); - setSelectedAccessTokenAttributes(claims); - } } - isOptionEqualToValue={ - (option: ExternalClaim, value: ExternalClaim) => - option.id === value.id - } - renderTags={ ( - value: ExternalClaim[], - getTagProps: AutocompleteRenderGetTagProps - ) => value.map((option: ExternalClaim, index: number) => ( - claim.id === option.id - ) - ? "solid" - : "outlined" + )) } + renderOption={ ( + props: HTMLAttributes, + option: ExternalClaim, + { selected }: { selected: boolean } + ) => ( + + ) } + /> + + - )) } - renderOption={ ( - props: HTMLAttributes, - option: ExternalClaim, - { selected }: { selected: boolean } - ) => ( - - ) } - /> - - - Select the attributes that should be included in - the access_token. - - - - - ) : null } + > + Select the attributes that should be included in + the access_token. + + + + + ) : null } ) diff --git a/features/admin.core.v1/configs/app.ts b/features/admin.core.v1/configs/app.ts index d48e6a790b7..cec6780da0a 100644 --- a/features/admin.core.v1/configs/app.ts +++ b/features/admin.core.v1/configs/app.ts @@ -294,7 +294,6 @@ export class Config { defaultLogoUrl: window[ "AppUtils" ]?.getConfig()?.ui?.emailTemplates?.defaultLogoUrl, defaultWhiteLogoUrl: window[ "AppUtils" ]?.getConfig()?.ui?.emailTemplates?.defaultWhiteLogoUrl }, - enableAccessTokenAttributes: window["AppUtils"]?.getConfig()?.ui?.enableAccessTokenAttributes, enableCustomEmailTemplates: window[ "AppUtils" ]?.getConfig()?.ui?.enableCustomEmailTemplates, enableEmailDomain: window[ "AppUtils" ]?.getConfig()?.ui?.enableEmailDomain ?? false, enableIdentityClaims: window[ "AppUtils" ]?.getConfig()?.ui?.enableIdentityClaims ?? true, diff --git a/features/admin.core.v1/models/config.ts b/features/admin.core.v1/models/config.ts index 87813922ff8..47e289366d9 100644 --- a/features/admin.core.v1/models/config.ts +++ b/features/admin.core.v1/models/config.ts @@ -445,10 +445,6 @@ export interface UIConfigInterface extends CommonUIConfigInterface Date: Thu, 22 Aug 2024 13:24:13 +0530 Subject: [PATCH 17/23] change update message --- .../components/forms/inbound-oidc-form.tsx | 37 ++++++++++++------- .../en-US/portals/applications.ts | 22 +++++++---- 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index 1ec5dd0662a..980e6a83373 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -2705,20 +2705,29 @@ export const InboundOIDCForm: FunctionComponent = - Previously, attributes that are set as requested in the User - Attribute section were automatically added to - access_token. - Now, you can choose which user attributes are included in the - access_token. To enable this - new feature, select - Enable Access Token Attributes - and update your application. When updating, - attributes that are set as requested in the User Attribute - section will be set as Access Token Attributes. Once updated, - only selected attributes from the Access Token Attributes will - be included in the access_token - without requiring OIDC scopes. Important: This change is - irreversible. Proceed with caution. + Previously, all attributes marked as + requested in the application's + User Attributes section (referred + to as requested attributes) were automatically included in the + access token. With the latest update, admins can now choose + which attributes to include in the access token. To enable + this feature, select + Enable Access Token Attributes. + To ensure a smooth transition from the old behavior, selecting + it for the first time will populate the + Access Token Attributes + section with all the requested attributes. Admins can then + remove any unwanted attributes. After saving the changes, + only the selected attributes will be included in the access + token. Moving forward, all requested attributes will appear + in a dropdown for admins to manage as needed. + + Important: Once updated, requested attributes are no longer + automatically included in the access token and this change is + irreversible. Admin-selected attributes will be included in + the access token even without requiring the relevant OIDC + scopes. + Proceed with caution.. access_token. Now, you can choose which " + - "user attributes are included in the <1>access_token. To enable this new feature, " + - "select <1>Enable Access Token Attributes and update your application. When updating, " + - "attributes that are set as requested in the User Attribute section will be set as " + - "Access Token Attributes. Once updated, only selected attributes from the Access " + - "Token Attributes will be included in the <1>access_token without requiring OIDC scopes. " + - "Important: This change is irreversible. Proceed with caution.", + hint : "Previously, all attributes marked as requested in the application's " + + "User Attributes section (referred to as requested attributes) were " + + "automatically included in the access token. With the latest update, " + + "admins can now choose which attributes to include in the access token. " + + "To enable this feature, select Enable Access Token Attributes. To ensure " + + "a smooth transition from the old behavior, selecting it for the first time " + + "will populate the Access Token Attributes section with all the requested " + + "attributes. Admins can then remove any unwanted attributes. After saving the " + + "changes, only the selected attributes will be included in the access token. " + + "Moving forward, all requested attributes will appear in a dropdown for admins " + + "to manage as needed. Important: Once updated, requested attributes are no " + + "longer automatically included in the access token and this change is " + + "irreversible. Admin-selected attributes will be included in the access token " + + "even without requiring the relevant OIDC scopes. Proceed with caution.", label: "Enable Access Token Attributes" } } From 09c748e1c330320fea6e85bf471c05e0ae21e17f Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Sat, 24 Aug 2024 09:57:03 +0530 Subject: [PATCH 18/23] Fix suggestions --- .../access-token-attribute-option.tsx | 4 +- .../components/forms/inbound-oidc-form.tsx | 42 +++++++++++-------- .../settings/access-configuration.tsx | 34 ++++----------- .../models/application-inbound.ts | 1 + 4 files changed, 34 insertions(+), 47 deletions(-) diff --git a/features/admin.applications.v1/components/access-token-attribute-option.tsx b/features/admin.applications.v1/components/access-token-attribute-option.tsx index f7453b1e4aa..ebb2800f06e 100644 --- a/features/admin.applications.v1/components/access-token-attribute-option.tsx +++ b/features/admin.applications.v1/components/access-token-attribute-option.tsx @@ -60,9 +60,9 @@ export const AccessTokenAttributeOption: FunctionComponent - + - + diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index 980e6a83373..a600b6802b4 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -309,7 +309,6 @@ export const InboundOIDCForm: FunctionComponent = const requestObjectSigningAlg: MutableRefObject = useRef(); const requestObjectEncryptionAlgorithm: MutableRefObject = useRef(); const requestObjectEncryptionMethod: MutableRefObject = useRef(); - const accessTokenAttributesEnabledConfig: MutableRefObject = useRef(); const subjectToken: MutableRefObject = useRef(); const applicationSubjectTokenExpiryInSeconds: MutableRefObject = useRef(); @@ -2731,7 +2730,6 @@ export const InboundOIDCForm: FunctionComponent = = } ] } readOnly={ readOnly } - data-testid={ `${ testId }-access-token-attributes-enabled-checkbox` } + data-testid={ + `${ testId }-access-token-attributes-enabled-checkbox` + } /> ) } = loading={ isLoading } options={ accessTokenAttributes } value={ selectedAccessTokenAttributes ?? [] } - disabled = { !initialValues?.accessToken?.accessTokenAttributesEnabled } - data-componentid={ `${ componentId }-assigned-access-token-attribute-list` } + disabled={ !initialValues?.accessToken?.accessTokenAttributesEnabled } + data-componentid={ + `${ componentId }-assigned-access-token-attribute-list` + } getOptionLabel={ (claim: ExternalClaim) => claim.claimURI } renderInput={ (params: AutocompleteRenderInputParams) => ( - <> - - { t( + - - + ) + } + className="access-token-attributes-dropdown-input" + { ...params } + placeholder={ t("applications:forms.inboundOIDC.sections" + + ".accessToken.fields.accessTokenAttributes.placeholder") } + /> ) } onChange={ (event: SyntheticEvent, claims: ExternalClaim[]) => { setIsFormStale(true); @@ -2843,6 +2843,12 @@ export const InboundOIDCForm: FunctionComponent = the access_token. + ) : null } diff --git a/features/admin.applications.v1/components/settings/access-configuration.tsx b/features/admin.applications.v1/components/settings/access-configuration.tsx index c13a92810ed..501a69118bb 100644 --- a/features/admin.applications.v1/components/settings/access-configuration.tsx +++ b/features/admin.applications.v1/components/settings/access-configuration.tsx @@ -16,6 +16,7 @@ * under the License. */ +import { useRequiredScopes } from "@wso2is/access-control"; import { AppState, AuthenticatorAccordion, @@ -24,7 +25,6 @@ import { store } from "@wso2is/admin.core.v1"; import { applicationConfig } from "@wso2is/admin.extensions.v1"; -import { hasRequiredScopes } from "@wso2is/core/helpers"; import { AlertLevels, IdentifiableComponentInterface, SBACInterface } from "@wso2is/core/models"; import { addAlert } from "@wso2is/core/store"; import { FormValue } from "@wso2is/forms"; @@ -241,11 +241,9 @@ export const AccessConfiguration: FunctionComponent state.application.meta.protocolMeta); - const allowedScopes: string = useSelector((state: AppState) => state?.auth?.allowedScopes); const tenantName: string = store.getState().config.deployment.tenant; const allowMultipleProtocol: boolean = useSelector( (state: AppState) => state.config.deployment.allowMultipleAppProtocols); - const organizationType: string = useSelector((state: AppState) => state?.organization?.organizationType); const [ selectedProtocol, setSelectedProtocol ] = useState(undefined); const [ inboundProtocolList, setInboundProtocolList ] = useState([]); @@ -261,6 +259,8 @@ export const AccessConfiguration: FunctionComponent = useRef(null); const [ accordionActiveIndexes, setAccordionActiveIndexes ] = useState([]); + const hasApplicationUpdatePermissions: boolean = useRequiredScopes(featureConfig?.applications?.scopes?.update); + /** * Handles the inbound config delete action. * @@ -792,12 +792,7 @@ export const AccessConfiguration: FunctionComponent Date: Sun, 25 Aug 2024 00:04:09 +0530 Subject: [PATCH 19/23] add access token attributes --- .../access-token-attribute-option.scss | 23 +++++++++++++++++++ .../access-token-attribute-option.tsx | 3 ++- .../components/forms/inbound-oidc-form.scss | 7 ++++++ .../components/forms/inbound-oidc-form.tsx | 6 ----- 4 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 features/admin.applications.v1/components/access-token-attribute-option.scss diff --git a/features/admin.applications.v1/components/access-token-attribute-option.scss b/features/admin.applications.v1/components/access-token-attribute-option.scss new file mode 100644 index 00000000000..c3961412414 --- /dev/null +++ b/features/admin.applications.v1/components/access-token-attribute-option.scss @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * WSO2 LLC. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + + .access-token-attribute-option-checkbox { + padding: 4px; +} diff --git a/features/admin.applications.v1/components/access-token-attribute-option.tsx b/features/admin.applications.v1/components/access-token-attribute-option.tsx index ebb2800f06e..7ec8e5078c1 100644 --- a/features/admin.applications.v1/components/access-token-attribute-option.tsx +++ b/features/admin.applications.v1/components/access-token-attribute-option.tsx @@ -26,6 +26,7 @@ import React, { HTMLAttributes, ReactElement } from "react"; +import "./access-token-attribute-option.scss"; interface AccessTokenAttributeOption extends IdentifiableComponentInterface { /** @@ -62,7 +63,7 @@ export const AccessTokenAttributeOption: FunctionComponent - + diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.scss b/features/admin.applications.v1/components/forms/inbound-oidc-form.scss index d40910bbdb6..1ad162e6302 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.scss +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.scss @@ -34,4 +34,11 @@ border: none !important; width: auto !important; } + .MuiInputBase-root { + margin-top: .5em !important; + } + + .MuiFormLabel-root { + font-size: .92857143em !important; + } } diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index a600b6802b4..c1a40f400a5 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -2843,12 +2843,6 @@ export const InboundOIDCForm: FunctionComponent = the access_token. - ) : null } From 54db5639986963d4c71f87d1bb0d7bfbb6450049 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Sun, 25 Aug 2024 00:05:53 +0530 Subject: [PATCH 20/23] change option interface name --- .../components/access-token-attribute-option.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/features/admin.applications.v1/components/access-token-attribute-option.tsx b/features/admin.applications.v1/components/access-token-attribute-option.tsx index 7ec8e5078c1..450cc96e6b9 100644 --- a/features/admin.applications.v1/components/access-token-attribute-option.tsx +++ b/features/admin.applications.v1/components/access-token-attribute-option.tsx @@ -28,7 +28,7 @@ import React, { } from "react"; import "./access-token-attribute-option.scss"; -interface AccessTokenAttributeOption extends IdentifiableComponentInterface { +interface AccessTokenAttributeOptionPropsInterface extends IdentifiableComponentInterface { /** * Is the option selected. */ @@ -47,8 +47,8 @@ interface AccessTokenAttributeOption extends IdentifiableComponentInterface { renderOptionProps: HTMLAttributes } -export const AccessTokenAttributeOption: FunctionComponent = ( - props: AccessTokenAttributeOption +export const AccessTokenAttributeOption: FunctionComponent = ( + props: AccessTokenAttributeOptionPropsInterface ): ReactElement => { const { From 8bbe795fbf143d2be95d8c5852ebeff8d75fbedd Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Sun, 25 Aug 2024 00:11:22 +0530 Subject: [PATCH 21/23] add change set --- .changeset/rich-laws-change.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/rich-laws-change.md diff --git a/.changeset/rich-laws-change.md b/.changeset/rich-laws-change.md new file mode 100644 index 00000000000..fbb39f43ff2 --- /dev/null +++ b/.changeset/rich-laws-change.md @@ -0,0 +1,6 @@ +--- +"@wso2is/admin.applications.v1": major +"@wso2is/i18n": major +--- + +Add Access Token Attributes From 34970e62f83ae0c96068a10e9b8cf254abd7a449 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Sun, 25 Aug 2024 00:12:30 +0530 Subject: [PATCH 22/23] remove lines --- .../components/access-token-attribute-option.scss | 2 -- 1 file changed, 2 deletions(-) diff --git a/features/admin.applications.v1/components/access-token-attribute-option.scss b/features/admin.applications.v1/components/access-token-attribute-option.scss index c3961412414..2c52b7b21c0 100644 --- a/features/admin.applications.v1/components/access-token-attribute-option.scss +++ b/features/admin.applications.v1/components/access-token-attribute-option.scss @@ -16,8 +16,6 @@ * under the License. */ - - .access-token-attribute-option-checkbox { padding: 4px; } From ebb7bd2b139d3bb2228c08b1da2774ee866c7868 Mon Sep 17 00:00:00 2001 From: Thilina Shashimal Senarath Date: Sun, 25 Aug 2024 09:19:35 +0530 Subject: [PATCH 23/23] fix lints --- .../admin.applications.v1/components/forms/inbound-oidc-form.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx index c1a40f400a5..cc9a7d74157 100644 --- a/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx +++ b/features/admin.applications.v1/components/forms/inbound-oidc-form.tsx @@ -23,7 +23,6 @@ import Autocomplete, { } from "@oxygen-ui/react/Autocomplete"; import Box from "@oxygen-ui/react/Box"; import Chip from "@oxygen-ui/react/Chip"; -import InputLabel from "@oxygen-ui/react/InputLabel"; import TextField from "@oxygen-ui/react/TextField"; import { getAllExternalClaims, getAllLocalClaims } from "@wso2is/admin.claims.v1/api"; import { AppState, ConfigReducerStateInterface } from "@wso2is/admin.core.v1";