diff --git a/src/clients/help.ts b/src/clients/help.ts index b29402e290..190267f883 100644 --- a/src/clients/help.ts +++ b/src/clients/help.ts @@ -92,7 +92,12 @@ export default { "Contains all default client scopes and selected optional scopes. All protocol mappers and role scope mappings of all those client scopes will be used when generating access token issued for your client", effectiveRoleScopeMappings: "Selected Optional Client Scopes, which will be used when issuing access token for this client. You can see above what value of OAuth Scope Parameter needs to be used when you want to have these optional client scopes applied when the initial OpenID Connect Authentication request will be sent from your client adapter", - generatedAccessToken: "Example access token", + generatedAccessToken: + "See the example access token, which will be generated and sent to the client when selected user is authenticated. You can see claims and roles that the token will contain based on the effective protocol mappers and role scope mappings and also based on the claims/roles assigned to user himself", + generatedIdToken: + "See the example ID Token, which will be generated and sent to the client when selected user is authenticated. You can see claims and roles that the token will contain based on the effective protocol mappers and role scope mappings and also based on the claims/roles assigned to user himself", + generatedUserInfo: + "See the example User Info, which will be provided by the User Info Endpoint", scopeParameter: "You can copy/paste this value of scope parameter and use it in initial OpenID Connect Authentication Request sent from this client adapter. Default client scopes and selected optional client scopes will be used when generating token issued for this client", user: "Optionally select user, for whom the example access token will be generated. If you do not select a user, example access token will not be generated during evaluation", diff --git a/src/clients/messages.ts b/src/clients/messages.ts index 8427e82015..18390ef9c4 100644 --- a/src/clients/messages.ts +++ b/src/clients/messages.ts @@ -273,12 +273,20 @@ export default { effectiveProtocolMappers: "Effective protocol mappers", effectiveRoleScopeMappings: "Effective role scope mappings", generatedAccessToken: "Generated access token", + generatedIdToken: "Generated ID token", + generatedIdTokenNo: "No generated id token", + generatedIdTokenIsDisabled: + "Generated id token is disabled when no user is selected", + generatedUserInfo: "Generated user info", + generatedUserInfoNo: "No generated user info", + generatedUserInfoIsDisabled: + "Generated user info is disabled when no user is selected", searchForProtocol: "Search protocol mapper", parentClientScope: "Parent client scope", searchForRole: "Search role", origin: "Origin", user: "User", - noGeneratedAccessToken: "No generated access token", + generatedAccessTokenNo: "No generated access token", generatedAccessTokenIsDisabled: "Generated access token is disabled when no user is selected", clientList: "Clients", @@ -330,6 +338,9 @@ export default { initialAccessTokenDetails: "Initial access token details", copyInitialAccessToken: "Please copy and paste the initial access token before closing as it can not be retrieved later.", + copySuccess: "Successfully copied to clipboard!", + clipboardCopyError: "Error copying to clipboard.", + copyToClipboard: "Copy to clipboard", clientAuthentication: "Client authentication", authentication: "Authentication", authenticationFlow: "Authentication flow", diff --git a/src/clients/scopes/EvaluateScopes.tsx b/src/clients/scopes/EvaluateScopes.tsx index e8b526bdc5..25685482cd 100644 --- a/src/clients/scopes/EvaluateScopes.tsx +++ b/src/clients/scopes/EvaluateScopes.tsx @@ -1,7 +1,5 @@ import { ClipboardCopy, - EmptyState, - EmptyStateBody, Form, FormGroup, Grid, @@ -17,9 +15,7 @@ import { Tabs, TabTitleText, Text, - TextArea, TextContent, - Title, } from "@patternfly/react-core"; import { QuestionCircleIcon } from "@patternfly/react-icons"; import type ClientScopeRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientScopeRepresentation"; @@ -36,6 +32,7 @@ import { useAdminClient, useFetch } from "../../context/auth/AdminClient"; import { useRealm } from "../../context/realm-context/RealmContext"; import { useServerInfo } from "../../context/server-info/ServerInfoProvider"; import { prettyPrintJSON } from "../../util"; +import { GeneratedCodeTab } from "./GeneratedCodeTab"; import "./evaluate.css"; @@ -140,10 +137,14 @@ export const EvaluateScopes = ({ clientId, protocol }: EvaluateScopesProps) => { ProtocolMapperRepresentation[] >([]); const [accessToken, setAccessToken] = useState(""); + const [userInfo, setUserInfo] = useState(""); + const [idToken, setIdToken] = useState(""); const tabContent1 = useRef(null); const tabContent2 = useRef(null); const tabContent3 = useRef(null); + const tabContent4 = useRef(null); + const tabContent5 = useRef(null); useFetch( () => adminClient.clients.listOptionalClientScopes({ id: clientId }), @@ -221,20 +222,32 @@ export const EvaluateScopes = ({ clientId, protocol }: EvaluateScopesProps) => { ); useFetch( - () => { + async () => { const scope = selected.join(" "); - if (user) { - return adminClient.clients.evaluateGenerateAccessToken({ + if (!user) return []; + + return await Promise.all([ + adminClient.clients.evaluateGenerateAccessToken({ id: clientId, userId: user.id!, scope, - }); - } else { - return Promise.resolve({}); - } + }), + adminClient.clients.evaluateGenerateUserInfo({ + id: clientId, + userId: user.id!, + scope, + }), + adminClient.clients.evaluateGenerateIdToken({ + id: clientId, + userId: user.id!, + scope, + }), + ]); }, - (accessToken) => { + ([accessToken, userInfo, idToken]) => { setAccessToken(prettyPrintJSON(accessToken)); + setUserInfo(prettyPrintJSON(userInfo)); + setIdToken(prettyPrintJSON(idToken)); }, [user, selected] ); @@ -350,25 +363,43 @@ export const EvaluateScopes = ({ clientId, protocol }: EvaluateScopesProps) => {