From d32aac9dee218976822caca888c7bf6df98e011e Mon Sep 17 00:00:00 2001 From: Jon Koops Date: Mon, 16 Oct 2023 13:15:43 +0200 Subject: [PATCH 01/27] Remove unused GitHub workflow files from docs (#24011) --- .../.github/workflows/test-external-links.yml | 26 ------------------- .../.github/workflows/test-guides.yml | 25 ------------------ 2 files changed, 51 deletions(-) delete mode 100644 docs/documentation/.github/workflows/test-external-links.yml delete mode 100644 docs/documentation/.github/workflows/test-guides.yml diff --git a/docs/documentation/.github/workflows/test-external-links.yml b/docs/documentation/.github/workflows/test-external-links.yml deleted file mode 100644 index 67aa6cbbb3da..000000000000 --- a/docs/documentation/.github/workflows/test-external-links.yml +++ /dev/null @@ -1,26 +0,0 @@ -# This workflow will build a Java project with Maven -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven - -name: External Links - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - schedule: - - cron: '0 5 * * *' -jobs: - test: - name: Verify links - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Build - run: mvn install -B -DskipTests - - name: Test - run: mvn test -B -pl tests -Dtest=ExternalLinksTest diff --git a/docs/documentation/.github/workflows/test-guides.yml b/docs/documentation/.github/workflows/test-guides.yml deleted file mode 100644 index 7c5db9004257..000000000000 --- a/docs/documentation/.github/workflows/test-guides.yml +++ /dev/null @@ -1,25 +0,0 @@ -# This workflow will build a Java project with Maven -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven - -name: Test - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - build: - name: Verify Keycloak documentation - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up JDK 1.8 - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Build - run: mvn install -B -DskipTests - - name: Test - run: mvn test -B -pl tests -Dtest=!ExternalLinksTest From b3e6208eecfe3d85c5000090a3265767c6c3041a Mon Sep 17 00:00:00 2001 From: Miquel Simon Date: Mon, 16 Oct 2023 13:41:13 +0200 Subject: [PATCH 02/27] Disable Account Console IT in Firefox Closes #24004 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b4ec5a0ab9b7..65da01eb46c4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -509,7 +509,7 @@ jobs: timeout-minutes: 75 strategy: matrix: - browser: [chrome, firefox] + browser: [chrome] fail-fast: false steps: - uses: actions/checkout@v4 @@ -519,7 +519,7 @@ jobs: uses: ./.github/actions/integration-test-setup - name: Run Account Console IT - run: ./mvnw test ${{ env.SUREFIRE_RETRY }} -Pauth-server-quarkus -Dtest=**.account2.**,!SigningInTest#passwordlessWebAuthnTest,!SigningInTest#twoFactorWebAuthnTest -Dbrowser=${{ matrix.browser }} "-Dwebdriver.chrome.driver=$CHROMEWEBDRIVER/chromedriver" "-Dwebdriver.gecko.driver=$GECKOWEBDRIVER/geckodriver" -f testsuite/integration-arquillian/tests/other/base-ui/pom.xml | misc/log/trimmer.sh + run: ./mvnw test ${{ env.SUREFIRE_RETRY }} -Pauth-server-quarkus -Dtest=**.account2.**,!SigningInTest#passwordlessWebAuthnTest,!SigningInTest#twoFactorWebAuthnTest -Dbrowser=${{ matrix.browser }} "-Dwebdriver.chrome.driver=$CHROMEWEBDRIVER/chromedriver" -f testsuite/integration-arquillian/tests/other/base-ui/pom.xml | misc/log/trimmer.sh - name: Upload JVM Heapdumps if: always() From f9386bd62b3f11dc7a93cd8406d4087d87ea2534 Mon Sep 17 00:00:00 2001 From: wojnarfilip Date: Mon, 18 Sep 2023 12:59:36 +0200 Subject: [PATCH 03/27] Update login flow in OCP social login --- .../testsuite/pages/social/OpenShiftLoginPage.java | 13 +++++++++++++ .../keycloak/testsuite/broker/SocialLoginTest.java | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/social/OpenShiftLoginPage.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/social/OpenShiftLoginPage.java index 055bf8e2f341..a88399469700 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/social/OpenShiftLoginPage.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/pages/social/OpenShiftLoginPage.java @@ -17,6 +17,7 @@ package org.keycloak.testsuite.pages.social; +import org.keycloak.testsuite.util.WaitUtils; import org.openqa.selenium.By; import org.openqa.selenium.Keys; import org.openqa.selenium.NoSuchElementException; @@ -35,6 +36,9 @@ public class OpenShiftLoginPage extends AbstractSocialLoginPage { @FindBy(name = "password") private WebElement passwordInput; + @FindBy(name = "approve") + private WebElement authorizeButton; + private String userLoginLinkTitle; private WebElement userLoginLink; @@ -48,9 +52,18 @@ public void login(String user, String password) { } } + WaitUtils.pause(3000); usernameInput.sendKeys(user); passwordInput.sendKeys(password); passwordInput.sendKeys(Keys.RETURN); + + try { + WaitUtils.pause(3000); + authorizeButton.click(); + } + catch (NoSuchElementException e) { + log.info("User already allowed in the app"); + } } public void setUserLoginLinkTitle(String title) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SocialLoginTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SocialLoginTest.java index 539c20da2c06..85f8ebe4e1c0 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SocialLoginTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/SocialLoginTest.java @@ -250,7 +250,7 @@ public static void setupClientExchangePermissions(KeycloakSession session) { public void openshiftLogin() { setTestProvider(OPENSHIFT); performLogin(); - assertUpdateProfile(false, false, true); + assertUpdateProfile(true, true, true); appPage.assertCurrent(); testTokenExchange(); } From 5a76ddfc2e0ff2cf7ae31b81bc1f7d1c41804cda Mon Sep 17 00:00:00 2001 From: Alice Wood <105500542+Redhat-Alice@users.noreply.github.com> Date: Thu, 12 Oct 2023 12:14:28 -0400 Subject: [PATCH 04/27] Remove realm model storage from OAuth2DeviceConfig class to avoid persisting old session and entity manager in infinispan fixes keycloak/keycloak#23943 --- .../datastore/LegacyExportImportManager.java | 8 ++--- .../map/datastore/MapExportImportManager.java | 8 ++--- .../keycloak/models/OAuth2DeviceConfig.java | 36 ++++++------------- 3 files changed, 19 insertions(+), 33 deletions(-) diff --git a/model/legacy-private/src/main/java/org/keycloak/storage/datastore/LegacyExportImportManager.java b/model/legacy-private/src/main/java/org/keycloak/storage/datastore/LegacyExportImportManager.java index 3bd77c9d66a0..0f1e31d1e584 100644 --- a/model/legacy-private/src/main/java/org/keycloak/storage/datastore/LegacyExportImportManager.java +++ b/model/legacy-private/src/main/java/org/keycloak/storage/datastore/LegacyExportImportManager.java @@ -260,8 +260,8 @@ public void importRealm(RealmRepresentation rep, RealmModel newRealm, boolean sk // OAuth 2.0 Device Authorization Grant OAuth2DeviceConfig deviceConfig = newRealm.getOAuth2DeviceConfig(); - deviceConfig.setOAuth2DeviceCodeLifespan(rep.getOAuth2DeviceCodeLifespan()); - deviceConfig.setOAuth2DevicePollingInterval(rep.getOAuth2DevicePollingInterval()); + deviceConfig.setOAuth2DeviceCodeLifespan(newRealm, rep.getOAuth2DeviceCodeLifespan()); + deviceConfig.setOAuth2DevicePollingInterval(newRealm, rep.getOAuth2DevicePollingInterval()); if (rep.getSslRequired() != null) newRealm.setSslRequired(SslRequired.valueOf(rep.getSslRequired().toUpperCase())); @@ -764,8 +764,8 @@ public void updateRealm(RealmRepresentation rep, RealmModel realm) { OAuth2DeviceConfig deviceConfig = realm.getOAuth2DeviceConfig(); - deviceConfig.setOAuth2DeviceCodeLifespan(rep.getOAuth2DeviceCodeLifespan()); - deviceConfig.setOAuth2DevicePollingInterval(rep.getOAuth2DevicePollingInterval()); + deviceConfig.setOAuth2DeviceCodeLifespan(realm, rep.getOAuth2DeviceCodeLifespan()); + deviceConfig.setOAuth2DevicePollingInterval(realm, rep.getOAuth2DevicePollingInterval()); if (rep.getNotBefore() != null) realm.setNotBefore(rep.getNotBefore()); if (rep.getDefaultSignatureAlgorithm() != null) realm.setDefaultSignatureAlgorithm(rep.getDefaultSignatureAlgorithm()); diff --git a/model/map/src/main/java/org/keycloak/models/map/datastore/MapExportImportManager.java b/model/map/src/main/java/org/keycloak/models/map/datastore/MapExportImportManager.java index d1c872c80768..93c2aa94b232 100644 --- a/model/map/src/main/java/org/keycloak/models/map/datastore/MapExportImportManager.java +++ b/model/map/src/main/java/org/keycloak/models/map/datastore/MapExportImportManager.java @@ -266,8 +266,8 @@ public void importRealm(RealmRepresentation rep, RealmModel newRealm, boolean sk // OAuth 2.0 Device Authorization Grant OAuth2DeviceConfig deviceConfig = newRealm.getOAuth2DeviceConfig(); - deviceConfig.setOAuth2DeviceCodeLifespan(rep.getOAuth2DeviceCodeLifespan()); - deviceConfig.setOAuth2DevicePollingInterval(rep.getOAuth2DevicePollingInterval()); + deviceConfig.setOAuth2DeviceCodeLifespan(newRealm, rep.getOAuth2DeviceCodeLifespan()); + deviceConfig.setOAuth2DevicePollingInterval(newRealm, rep.getOAuth2DevicePollingInterval()); if (rep.getSslRequired() != null) newRealm.setSslRequired(SslRequired.valueOf(rep.getSslRequired().toUpperCase())); @@ -1053,8 +1053,8 @@ public void updateRealm(RealmRepresentation rep, RealmModel realm) { OAuth2DeviceConfig deviceConfig = realm.getOAuth2DeviceConfig(); - deviceConfig.setOAuth2DeviceCodeLifespan(rep.getOAuth2DeviceCodeLifespan()); - deviceConfig.setOAuth2DevicePollingInterval(rep.getOAuth2DevicePollingInterval()); + deviceConfig.setOAuth2DeviceCodeLifespan(realm, rep.getOAuth2DeviceCodeLifespan()); + deviceConfig.setOAuth2DevicePollingInterval(realm, rep.getOAuth2DevicePollingInterval()); if (rep.getNotBefore() != null) realm.setNotBefore(rep.getNotBefore()); if (rep.getDefaultSignatureAlgorithm() != null) realm.setDefaultSignatureAlgorithm(rep.getDefaultSignatureAlgorithm()); diff --git a/server-spi/src/main/java/org/keycloak/models/OAuth2DeviceConfig.java b/server-spi/src/main/java/org/keycloak/models/OAuth2DeviceConfig.java index 8ea25554dbac..0815149008b2 100644 --- a/server-spi/src/main/java/org/keycloak/models/OAuth2DeviceConfig.java +++ b/server-spi/src/main/java/org/keycloak/models/OAuth2DeviceConfig.java @@ -41,17 +41,10 @@ public final class OAuth2DeviceConfig implements Serializable { public static String OAUTH2_DEVICE_POLLING_INTERVAL_PER_CLIENT = "oauth2.device.polling.interval"; public static final String OAUTH2_DEVICE_AUTHORIZATION_GRANT_ENABLED = "oauth2.device.authorization.grant.enabled"; - private transient Supplier realm; - - // Make sure setters are not called when calling this from constructor to avoid DB updates - private transient Supplier realmForWrite; - private int lifespan = DEFAULT_OAUTH2_DEVICE_CODE_LIFESPAN; private int poolingInterval = DEFAULT_OAUTH2_DEVICE_POLLING_INTERVAL; public OAuth2DeviceConfig(RealmModel realm) { - this.realm = () -> realm; - String lifespan = realm.getAttribute(OAUTH2_DEVICE_CODE_LIFESPAN); if (lifespan != null && !lifespan.trim().isEmpty()) { @@ -63,8 +56,6 @@ public OAuth2DeviceConfig(RealmModel realm) { if (pooling != null && !pooling.trim().isEmpty()) { setOAuth2DevicePollingInterval(Integer.parseInt(pooling)); } - - this.realmForWrite = () -> realm; } public int getLifespan() { @@ -72,11 +63,15 @@ public int getLifespan() { } public void setOAuth2DeviceCodeLifespan(Integer seconds) { + setOAuth2DeviceCodeLifespan(null, seconds); + } + + public void setOAuth2DeviceCodeLifespan(RealmModel realm, Integer seconds) { if (seconds == null) { seconds = DEFAULT_OAUTH2_DEVICE_CODE_LIFESPAN; } this.lifespan = seconds; - persistRealmAttribute(OAUTH2_DEVICE_CODE_LIFESPAN, lifespan); + persistRealmAttribute(realm, OAUTH2_DEVICE_CODE_LIFESPAN, lifespan); } public int getPoolingInterval() { @@ -84,14 +79,16 @@ public int getPoolingInterval() { } public void setOAuth2DevicePollingInterval(Integer seconds) { + setOAuth2DevicePollingInterval(null, seconds); + } + + public void setOAuth2DevicePollingInterval(RealmModel realm, Integer seconds) { if (seconds == null) { seconds = DEFAULT_OAUTH2_DEVICE_POLLING_INTERVAL; } this.poolingInterval = seconds; - RealmModel model = getRealm(); - - persistRealmAttribute(OAUTH2_DEVICE_POLLING_INTERVAL, poolingInterval); + persistRealmAttribute(realm, OAUTH2_DEVICE_POLLING_INTERVAL, poolingInterval); } public int getLifespan(ClientModel client) { @@ -119,18 +116,7 @@ public boolean isOAuth2DeviceAuthorizationGrantEnabled(ClientModel client) { return Boolean.parseBoolean(enabled); } - private RealmModel getRealm() { - RealmModel model = realm.get(); - - if (model == null) { - throw new RuntimeException("Can only update after invalidating the realm"); - } - - return model; - } - - private void persistRealmAttribute(String name, Integer value) { - RealmModel realm = realmForWrite == null ? null : this.realmForWrite.get(); + private void persistRealmAttribute(RealmModel realm, String name, Integer value) { if (realm != null) { realm.setAttribute(name, value); } From b3be89de9b3e81cfedd14d1b79586c26148e73b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Muzik=C3=A1=C5=99?= Date: Mon, 16 Oct 2023 11:29:28 +0200 Subject: [PATCH 05/27] Remove mentions of Crunchy Operator from docs Closes #24007 --- docs/guides/operator/basic-deployment.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/operator/basic-deployment.adoc b/docs/guides/operator/basic-deployment.adoc index 77a31adb42d4..20beee116e4f 100644 --- a/docs/guides/operator/basic-deployment.adoc +++ b/docs/guides/operator/basic-deployment.adoc @@ -28,7 +28,7 @@ Once the Keycloak Operator is installed and running in the cluster namespace, yo A database should be available and accessible from the cluster namespace where Keycloak is installed. For a list of supported databases, see <@links.server id="db"/>. -The Keycloak Operator does not manage the database and you need to provision it yourself. Consider verifying your cloud provider offering or using a database operator such as https://access.crunchydata.com/documentation/postgres-operator/latest/[Crunchy]. +The Keycloak Operator does not manage the database and you need to provision it yourself. Consider verifying your cloud provider offering or using a database operator. For development purposes, you can use an ephemeral PostgreSQL pod installation. To provision it, follow the approach below: From 7dda39312056d8b4dd5af07ffa687eebac8f4cf0 Mon Sep 17 00:00:00 2001 From: AndyMunro Date: Thu, 12 Oct 2023 17:33:25 -0400 Subject: [PATCH 06/27] Make minor changes to Getting Started Closes #23951 --- .../getting-started-openshift.adoc | 2 +- .../getting-started/getting-started-zip.adoc | 11 +++++++++-- .../getting-started/templates/realm-config.adoc | 2 +- .../templates/start-keycloak-localhost.adoc | 15 +++++++++++++++ 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/docs/guides/getting-started/getting-started-openshift.adoc b/docs/guides/getting-started/getting-started-openshift.adoc index 9373e07ad7c8..0cd34eb73b30 100644 --- a/docs/guides/getting-started/getting-started-openshift.adoc +++ b/docs/guides/getting-started/getting-started-openshift.adoc @@ -55,7 +55,7 @@ oc process -f https://raw.githubusercontent.com/keycloak/keycloak-quickstarts/la | oc create -f - ---- + -In this example, the user name and and password are `admin`. +In this example, the user name and password are `admin`. . Once the command above completes, look for a message similar to this: + diff --git a/docs/guides/getting-started/getting-started-zip.adoc b/docs/guides/getting-started/getting-started-zip.adoc index 923bb60b1227..13d3448aa15c 100644 --- a/docs/guides/getting-started/getting-started-zip.adoc +++ b/docs/guides/getting-started/getting-started-zip.adoc @@ -1,4 +1,5 @@ <#import "/templates/guide.adoc" as tmpl> +<#import "/templates/profile.adoc" as profile> <@tmpl.guide title="OpenJDK" @@ -10,14 +11,20 @@ summary="Get started with Keycloak on bare metal"> == Before you start -Make sure you have https://openjdk.java.net/[OpenJDK 17] or a higher version installed. +Make sure you have https://openjdk.java.net/[OpenJDK 17] installed. == Download Keycloak Download and extract https://github.com/keycloak/keycloak/releases/download/{version}/keycloak-{version}.zip[keycloak-{version}.zip] from the Keycloak website. -After extracting this file, you should have a directory named keycloak-{version}. +<@profile.ifCommunity> +After extracting this file, you should have a directory with a name that starts with `keycloak-{version}`. + + +<@profile.ifProduct> +After extracting this file, you should have a directory with a name that starts with `rhbk-{version}`. + include::templates/start-keycloak-localhost.adoc[] diff --git a/docs/guides/getting-started/templates/realm-config.adoc b/docs/guides/getting-started/templates/realm-config.adoc index 56325959448c..6e955169c718 100644 --- a/docs/guides/getting-started/templates/realm-config.adoc +++ b/docs/guides/getting-started/templates/realm-config.adoc @@ -37,6 +37,6 @@ This user needs a password to log in. To set the initial password: . Click *Credentials* at the top of the page. . Fill in the *Set password* form with a password. -. Toggle *Temporary* to *Off* so that the user does not need update this password at the first login. +. Toggle *Temporary* to *Off* so that the user does not need to update this password at the first login. image::set-password.png[Set password] diff --git a/docs/guides/getting-started/templates/start-keycloak-localhost.adoc b/docs/guides/getting-started/templates/start-keycloak-localhost.adoc index 0f07b18406aa..c5ddff1ed2b4 100644 --- a/docs/guides/getting-started/templates/start-keycloak-localhost.adoc +++ b/docs/guides/getting-started/templates/start-keycloak-localhost.adoc @@ -1,7 +1,18 @@ +<#import "/templates/profile.adoc" as profile> + == Start Keycloak . From a terminal, open the keycloak-{version} directory. . Enter the following command: +<@profile.ifProduct> ++ +[source,bash,subs="attributes+"] +---- +bin/kc.sh start-dev +---- + + +<@profile.ifCommunity> * On Linux, run: + [source,bash,subs="attributes+"] @@ -15,3 +26,7 @@ bin/kc.sh start-dev ---- bin\kc.bat start-dev ---- + + +Using the `start-dev` option, you are starting Keycloak development mode. In this mode, you can try out Keycloak for the first time to get it up and running quickly. This mode offers convenient defaults for developers, such as for developing a new Keycloak theme. + From 50916d58b165f1374369beef764a6a4108e82c9e Mon Sep 17 00:00:00 2001 From: Alexander Schwartz Date: Mon, 16 Oct 2023 11:12:12 +0200 Subject: [PATCH 07/27] Clean up created test user to avoid conflict with other tests Closes #23804 --- .../keycloak/testsuite/runonserver/SerializationUtil.java | 3 +++ .../federation/ldap/LDAPProvidersFullNameMapperTest.java | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/runonserver/SerializationUtil.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/runonserver/SerializationUtil.java index 1f56a807ae96..397144e00620 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/runonserver/SerializationUtil.java +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/runonserver/SerializationUtil.java @@ -51,6 +51,9 @@ public static String encodeException(Throwable t) { oos.close(); return "EXCEPTION:" + Base64.encodeBytes(os.toByteArray()); + } catch (NotSerializableException e) { + // when the exception can't be serialized, at least log the original exception, so it can be analyzed + throw new RuntimeException("Unable to serialize exception due to not serializable class " + e.getMessage(), t); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPProvidersFullNameMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPProvidersFullNameMapperTest.java index 4c713d21d582..72f58ec8fbf3 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPProvidersFullNameMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPProvidersFullNameMapperTest.java @@ -167,7 +167,7 @@ public void testUpdatingAttributesWorksEvenWithEmptyAttributes() { MatcherAssert.assertThat(Arrays.asList("one", "two", "three"), Matchers.containsInAnyOrder(fullnameUser.getAttributeStream("myAttrThreeValues").toArray(String[]::new))); - // Remove "fullnameUser" to assert he is removed from LDAP. + // Remove "fullnameUser" to prevent conflicts with other tests session.users().removeUser(appRealm, fullnameUser); }); } @@ -201,6 +201,9 @@ public void testMultiValuedAttributes() { UserModel fullnameUser = session.users().getUserByUsername(appRealm, "fullname"); Assert.assertEquals(Arrays.asList("role1", "role2"), fullnameUser.getAttributeStream("roles").collect(Collectors.toList())); + + // Remove "fullnameUser" to prevent conflicts with other tests + session.users().removeUser(appRealm, fullnameUser); }); } } From 1cd20e0e433854ab75035c9c1dd9dfe3bf65b993 Mon Sep 17 00:00:00 2001 From: Erik Jan de Wit Date: Mon, 16 Oct 2023 21:20:12 +0200 Subject: [PATCH 08/27] always allow browsing as we don't know the subgroups (#23657) fixes: #23582 --- .../components/group/GroupPickerDialog.tsx | 21 +++++++------------ .../components/group/group-picker-dialog.css | 4 ++++ .../src/groups/components/MoveDialog.tsx | 1 + 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/js/apps/admin-ui/src/components/group/GroupPickerDialog.tsx b/js/apps/admin-ui/src/components/group/GroupPickerDialog.tsx index 417660f0fd9e..a346fd390fc9 100644 --- a/js/apps/admin-ui/src/components/group/GroupPickerDialog.tsx +++ b/js/apps/admin-ui/src/components/group/GroupPickerDialog.tsx @@ -16,15 +16,14 @@ import { import { AngleRightIcon } from "@patternfly/react-icons"; import { useState } from "react"; import { useTranslation } from "react-i18next"; - import { adminClient } from "../../admin-client"; +import { fetchAdminUI } from "../../context/auth/admin-ui-endpoint"; import { useFetch } from "../../utils/useFetch"; import { ListEmptyState } from "../list-empty-state/ListEmptyState"; import { PaginatingTableToolbar } from "../table-toolbar/PaginatingTableToolbar"; import { GroupPath } from "./GroupPath"; import "./group-picker-dialog.css"; -import { fetchAdminUI } from "../../context/auth/admin-ui-endpoint"; export type GroupPickerDialogProps = { id?: string; @@ -32,6 +31,7 @@ export type GroupPickerDialogProps = { filterGroups?: GroupRepresentation[]; text: { title: string; ok: string }; canBrowse?: boolean; + isMove?: boolean; onConfirm: (groups: GroupRepresentation[] | undefined) => void; onClose: () => void; }; @@ -46,6 +46,7 @@ export const GroupPickerDialog = ({ filterGroups, text, canBrowse = true, + isMove = false, onClose, onConfirm, }: GroupPickerDialogProps) => { @@ -257,7 +258,7 @@ export const GroupPickerDialog = ({ )} {groups.length === 0 && isSearching && ( @@ -296,9 +297,6 @@ const GroupRow = ({ }: GroupRowProps) => { const { t } = useTranslation(); - const hasSubgroups = (group: GroupRepresentation) => - group.subGroups?.length !== 0; - return ( { if (type === "selectOne") { onSelect(group.id!); - } else if ( - hasSubgroups(group) && - (e.target as HTMLInputElement).type !== "checkbox" - ) { + } else if ((e.target as HTMLInputElement).type !== "checkbox") { onSelect(group.id!); setIsSearching(false); } }} > @@ -364,7 +359,7 @@ const GroupRow = ({ aria-label={t("groupName")} isPlainButtonAction > - {((hasSubgroups(group) && canBrowse) || type === "selectOne") && ( + {(canBrowse || type === "selectOne") && ( diff --git a/js/apps/admin-ui/src/components/group/group-picker-dialog.css b/js/apps/admin-ui/src/components/group/group-picker-dialog.css index cbac7b87a378..7df2ccf3dc73 100644 --- a/js/apps/admin-ui/src/components/group/group-picker-dialog.css +++ b/js/apps/admin-ui/src/components/group/group-picker-dialog.css @@ -2,4 +2,8 @@ white-space: nowrap; overflow: hidden; text-overflow: ellipsis; +} + +.join-group-dialog-row { + cursor: pointer; } \ No newline at end of file diff --git a/js/apps/admin-ui/src/groups/components/MoveDialog.tsx b/js/apps/admin-ui/src/groups/components/MoveDialog.tsx index f43e7db12371..3672f8278bd5 100644 --- a/js/apps/admin-ui/src/groups/components/MoveDialog.tsx +++ b/js/apps/admin-ui/src/groups/components/MoveDialog.tsx @@ -45,6 +45,7 @@ export const MoveDialog = ({ source, onClose, refresh }: MoveDialogProps) => { }} onClose={onClose} onConfirm={moveGroup} + isMove /> ); }; From e803cd8b84a3df42d8f6f101b50a04c91f470c1a Mon Sep 17 00:00:00 2001 From: Dimitri <56969769+DimitriDR@users.noreply.github.com> Date: Tue, 17 Oct 2023 00:11:03 +0200 Subject: [PATCH 09/27] Update Account UI French translations (#23544) Co-authored-by: Paul-Van-Uytvinck <47578994+Paul-Van-Uytvinck@users.noreply.github.com> --- .../public/locales/fr/translation.json | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/js/apps/account-ui/public/locales/fr/translation.json b/js/apps/account-ui/public/locales/fr/translation.json index 3f7462708610..b908ae392a37 100644 --- a/js/apps/account-ui/public/locales/fr/translation.json +++ b/js/apps/account-ui/public/locales/fr/translation.json @@ -2,7 +2,7 @@ "accept": "Accepter", "accessGrantedOn": "Accès autorisé le : ", "accountSecurity": "Sécurité du compte", - "accountUpdatedError": "Impossible de metter à jour votre compte à cause des erreurs de validation", + "accountUpdatedError": "Impossible de mettre à jour votre compte à cause des erreurs de validation", "accountUpdatedMessage": "Votre compte a été mis à jour.", "add": "Ajouter", "application": "Application", @@ -90,7 +90,7 @@ "permissionRequest": "Demandes d'autorisation - {{name}}", "permissionRequests": "Demandes d'autorisation", "permissions": "Autorisations", - "personalInfo": "Informations personelles", + "personalInfo": "Informations personnelles", "personalInfoDescription": "Gérez vos informations de base", "privacyPolicy": "Politique de confidentialité", "refreshPage": "Rafraichir la page", @@ -157,5 +157,18 @@ "updateSuccess": "Ressource mise à jour avec succès.", "user": "Utilisateur", "username": "Nom d'utilisateur", - "usernamePlaceholder": "Nom d'utiisateur ou courriel" + "usernamePlaceholder": "Nom d'utilisateur ou courriel", + "groupsListHeader": "En-tête de la liste des groupes", + "groupsListColumnsNames": "Nom des colonnes de la liste des groupes", + "aliasHelp": "Nom de la configuration", + "flowTypeHelp": "De quel genre de formulaire s'agit-il", + "createFlowHelp": "Vous pouvez créer un flow de premier niveau au sein de ce formulaire", + "rolesScope": "S'il n'y a aucun mappage de portée de rôle défini, chaque utilisateur est autorisé à utiliser cette portée du client. S'il y a des mappages de portée de rôle, l'utilisateur doit être membre d'au moins l'un des rôles.", + "scopeNameHelp": "Nom de la portée du client. Doit être unique dans le domaine. Le nom ne doit pas contenir d'espace car il est utilisé comme valeur du paramètre de la portée", + "scopeDescriptionHelp": "Description de la portée du client", + "scopeTypeHelp": "Portées du client, qui seront ajoutées comme portées par défaut à chacun des clients créés", + "clientDescriptionHelp": "Spécifie la description du client. Par exemple, « Mon client pour TimeSheet ». Prend également en charge les clés pour les valeurs localisées. Par exemple : ${my_client_description}", + "clientTypeHelp": "Le type de cette ressource. Il peut être utilisé pour grouper ensemble différentes instances de ressources avec le même type.", + "scopesHelp": "Les portées associées à cette ressource." } + From 7f9ea3afbb27b0c4ad91bffb59b5de57e93e59c0 Mon Sep 17 00:00:00 2001 From: Erik Jan de Wit Date: Tue, 17 Oct 2023 07:42:38 +0200 Subject: [PATCH 10/27] added test for resources (#23706) * added test for resources fixes: #21251 * pr comments * Rename `data-testId` to `data-testid` --------- Co-authored-by: Jon Koops --- js/apps/account-ui/playwright.config.ts | 11 +---- .../account-ui/src/resources/Resources.tsx | 2 + .../account-ui/src/resources/ResourcesTab.tsx | 1 + .../src/resources/ShareTheResource.tsx | 5 +- .../account-ui/src/resources/SharedWith.tsx | 10 ++-- js/apps/account-ui/test/my-resources.spec.ts | 46 ++++++++++++++++++- 6 files changed, 58 insertions(+), 17 deletions(-) diff --git a/js/apps/account-ui/playwright.config.ts b/js/apps/account-ui/playwright.config.ts index eb4fef4479a8..c2c8825cf690 100644 --- a/js/apps/account-ui/playwright.config.ts +++ b/js/apps/account-ui/playwright.config.ts @@ -8,7 +8,7 @@ export default defineConfig({ fullyParallel: true, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, - workers: process.env.CI ? 1 : undefined, + workers: 1, reporter: "html", use: { baseURL: process.env.CI @@ -38,15 +38,6 @@ export default defineConfig({ dependencies: ["setup", "import realms"], testIgnore: ["**/personal-info.spec.ts"], }, - { - name: "firefox", - use: { - ...devices["Desktop Firefox"], - storageState: ".auth/user.json", - }, - dependencies: ["setup", "import realms"], - testIgnore: ["**/personal-info.spec.ts"], - }, { name: "personal-info", use: { diff --git a/js/apps/account-ui/src/resources/Resources.tsx b/js/apps/account-ui/src/resources/Resources.tsx index 086cbc2d9f83..ecac9ace83a6 100644 --- a/js/apps/account-ui/src/resources/Resources.tsx +++ b/js/apps/account-ui/src/resources/Resources.tsx @@ -18,12 +18,14 @@ const Resources = () => { unmountOnExit > {t("myResources")}} > {t("sharedWithMe")}} > diff --git a/js/apps/account-ui/src/resources/ResourcesTab.tsx b/js/apps/account-ui/src/resources/ResourcesTab.tsx index a3915da15686..e8ceb935b686 100644 --- a/js/apps/account-ui/src/resources/ResourcesTab.tsx +++ b/js/apps/account-ui/src/resources/ResourcesTab.tsx @@ -166,6 +166,7 @@ export const ResourcesTab = ({ isShared = false }: ResourcesTabProps) => { > append({ value: "" })} isDisabled={isDisabled} > diff --git a/js/apps/account-ui/src/resources/SharedWith.tsx b/js/apps/account-ui/src/resources/SharedWith.tsx index a61c597d10e9..a622d777b0ca 100644 --- a/js/apps/account-ui/src/resources/SharedWith.tsx +++ b/js/apps/account-ui/src/resources/SharedWith.tsx @@ -6,8 +6,10 @@ type SharedWithProps = { permissions?: Permission[]; }; -export const SharedWith = ({ permissions: p = [] }: SharedWithProps) => { - return ( +export const SharedWith = ({ permissions: p = [] }: SharedWithProps) => ( +
e.username) : "none"}`} + > {{ @@ -20,5 +22,5 @@ export const SharedWith = ({ permissions: p = [] }: SharedWithProps) => { }} - ); -}; +
+); diff --git a/js/apps/account-ui/test/my-resources.spec.ts b/js/apps/account-ui/test/my-resources.spec.ts index 0cf32b708715..d08ab9c3fe4e 100644 --- a/js/apps/account-ui/test/my-resources.spec.ts +++ b/js/apps/account-ui/test/my-resources.spec.ts @@ -5,7 +5,51 @@ test.describe("My resources page", () => { test("List my resources", async ({ page }) => { await login(page, "jdoe", "jdoe", "photoz"); await page.getByTestId("resources").click(); - //await expect(page.getByTestId("row[0].name")).toHaveText("one"); + await expect(page.getByRole("gridcell", { name: "one" })).toBeVisible(); }); + + test("Nothing is shared with alice", async ({ page }) => { + await login(page, "alice", "alice", "photoz"); + await page.getByTestId("resources").click(); + + await page.getByTestId("sharedWithMe").click(); + const tableData = await page.locator("table > tr").count(); + expect(tableData).toBe(0); + }); + + test("Share one with alice", async ({ page }) => { + await login(page, "jdoe", "jdoe", "photoz"); + await page.getByTestId("resources").click(); + + await page.getByTestId("expand-one").click(); + await expect(page.getByText("This resource is not shared.")).toBeVisible(); + + await page.getByTestId("share-one").click(); + await page.getByTestId("users").click(); + await page.getByTestId("users").fill("alice"); + await page.getByTestId("add").click(); + + await expect(page.getByRole("group", { name: "Share with" })).toHaveText( + "Share with alice", + ); + + await page.getByRole("button", { name: "Options menu" }).click(); + await page.getByRole("option", { name: "album:view" }).click(); + await page.getByRole("button", { name: "Options menu" }).click(); + + await page.getByTestId("done").click(); + + await page.getByTestId("expand-one").click(); + expect(page.getByTestId("shared-with-alice")).toBeDefined(); + }); + + test("One is shared with alice", async ({ page }) => { + await login(page, "alice", "alice", "photoz"); + await page.getByTestId("resources").click(); + + await page.getByTestId("sharedWithMe").click(); + const rowData = await page.getByTestId("row[0].name").allTextContents(); + expect(rowData).toEqual(["one"]); + }); }); From 13207aabac98df7c45d55e7b1015170154e09673 Mon Sep 17 00:00:00 2001 From: Erik Jan de Wit Date: Tue, 17 Oct 2023 09:36:26 +0200 Subject: [PATCH 11/27] Encode parameters for React Router links in URL-safe manner (#23667) Closes #22600 Co-authored-by: Jon Koops --- .../authentication/routes/Authentication.tsx | 4 ++-- .../src/authentication/routes/CreateFlow.tsx | 4 ++-- .../admin-ui/src/authentication/routes/Flow.tsx | 4 ++-- .../src/client-scopes/routes/ClientScope.tsx | 4 ++-- .../src/client-scopes/routes/ClientScopes.tsx | 4 ++-- .../src/client-scopes/routes/Mapper.tsx | 4 ++-- .../src/client-scopes/routes/NewClientScope.tsx | 4 ++-- .../admin-ui/src/clients/routes/AddClient.tsx | 4 ++-- .../clients/routes/AddRegistrationProvider.tsx | 4 ++-- .../src/clients/routes/AuthenticationTab.tsx | 4 ++-- js/apps/admin-ui/src/clients/routes/Client.tsx | 4 ++-- .../src/clients/routes/ClientRegistration.tsx | 4 ++-- .../admin-ui/src/clients/routes/ClientRole.tsx | 4 ++-- .../src/clients/routes/ClientScopeTab.tsx | 4 ++-- js/apps/admin-ui/src/clients/routes/Clients.tsx | 4 ++-- .../clients/routes/CreateInitialAccessToken.tsx | 4 ++-- .../clients/routes/DedicatedScopeDetails.tsx | 4 ++-- .../src/clients/routes/ImportClient.tsx | 4 ++-- js/apps/admin-ui/src/clients/routes/Mapper.tsx | 4 ++-- .../src/clients/routes/NewPermission.tsx | 4 ++-- .../admin-ui/src/clients/routes/NewPolicy.tsx | 4 ++-- .../admin-ui/src/clients/routes/NewResource.tsx | 4 ++-- js/apps/admin-ui/src/clients/routes/NewRole.tsx | 4 ++-- .../admin-ui/src/clients/routes/NewScope.tsx | 4 ++-- .../src/clients/routes/PermissionDetails.tsx | 4 ++-- .../src/clients/routes/PolicyDetails.tsx | 4 ++-- .../admin-ui/src/clients/routes/Resource.tsx | 4 ++-- js/apps/admin-ui/src/clients/routes/Scope.tsx | 4 ++-- .../admin-ui/src/dashboard/routes/Dashboard.tsx | 4 ++-- js/apps/admin-ui/src/events/routes/Events.tsx | 4 ++-- js/apps/admin-ui/src/groups/routes/Groups.tsx | 4 ++-- .../src/identity-providers/routes/AddMapper.tsx | 4 ++-- .../identity-providers/routes/EditMapper.tsx | 4 ++-- .../routes/IdentityProvider.tsx | 4 ++-- .../routes/IdentityProviderCreate.tsx | 4 ++-- .../routes/IdentityProviderKeycloakOidc.tsx | 4 ++-- .../routes/IdentityProviderOidc.tsx | 4 ++-- .../routes/IdentityProviderSaml.tsx | 4 ++-- .../routes/IdentityProviders.tsx | 4 ++-- .../admin-ui/src/realm-roles/routes/AddRole.tsx | 4 ++-- .../src/realm-roles/routes/RealmRole.tsx | 4 ++-- .../src/realm-roles/routes/RealmRoles.tsx | 4 ++-- .../src/realm-settings/routes/AddAttribute.tsx | 4 ++-- .../realm-settings/routes/AddClientPolicy.tsx | 4 ++-- .../realm-settings/routes/AddClientProfile.tsx | 4 ++-- .../src/realm-settings/routes/AddCondition.tsx | 4 ++-- .../src/realm-settings/routes/AddExecutor.tsx | 4 ++-- .../src/realm-settings/routes/Attribute.tsx | 4 ++-- .../realm-settings/routes/ClientPolicies.tsx | 4 ++-- .../src/realm-settings/routes/ClientProfile.tsx | 4 ++-- .../routes/EditAttributesGroup.tsx | 4 ++-- .../realm-settings/routes/EditClientPolicy.tsx | 4 ++-- .../src/realm-settings/routes/EditCondition.tsx | 4 ++-- .../src/realm-settings/routes/Executor.tsx | 4 ++-- .../src/realm-settings/routes/KeyProvider.tsx | 4 ++-- .../src/realm-settings/routes/KeysTab.tsx | 4 ++-- .../routes/NewAttributesGroup.tsx | 4 ++-- .../src/realm-settings/routes/RealmSettings.tsx | 4 ++-- .../src/realm-settings/routes/UserProfile.tsx | 4 ++-- js/apps/admin-ui/src/realm/routes/AddRealm.tsx | 4 ++-- .../admin-ui/src/sessions/routes/Sessions.tsx | 4 ++-- .../routes/CustomUserFederation.tsx | 4 ++-- .../routes/NewCustomUserFederation.tsx | 4 ++-- .../routes/NewKerberosUserFederation.tsx | 4 ++-- .../routes/NewLdapUserFederation.tsx | 4 ++-- .../user-federation/routes/UserFederation.tsx | 4 ++-- .../routes/UserFederationKerberos.tsx | 4 ++-- .../routes/UserFederationLdap.tsx | 4 ++-- .../routes/UserFederationLdapMapper.tsx | 4 ++-- .../routes/UserFederationsKerberos.tsx | 4 ++-- .../routes/UserFederationsLdap.tsx | 4 ++-- js/apps/admin-ui/src/user/routes/AddUser.tsx | 4 ++-- js/apps/admin-ui/src/user/routes/User.tsx | 4 ++-- js/apps/admin-ui/src/user/routes/Users.tsx | 4 ++-- js/apps/admin-ui/src/util.ts | 1 - .../admin-ui/src/utils/generateEncodedPath.ts | 17 +++++++++++++++++ 76 files changed, 165 insertions(+), 149 deletions(-) create mode 100644 js/apps/admin-ui/src/utils/generateEncodedPath.ts diff --git a/js/apps/admin-ui/src/authentication/routes/Authentication.tsx b/js/apps/admin-ui/src/authentication/routes/Authentication.tsx index 31b0801b92fc..dd1cae883f40 100644 --- a/js/apps/admin-ui/src/authentication/routes/Authentication.tsx +++ b/js/apps/admin-ui/src/authentication/routes/Authentication.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type AuthenticationTab = "flows" | "required-actions" | "policies"; @@ -31,6 +31,6 @@ export const toAuthentication = ( : AuthenticationRoute.path; return { - pathname: generatePath(path, params), + pathname: generateEncodedPath(path, params), }; }; diff --git a/js/apps/admin-ui/src/authentication/routes/CreateFlow.tsx b/js/apps/admin-ui/src/authentication/routes/CreateFlow.tsx index 8d7a224c808b..29652768f1cf 100644 --- a/js/apps/admin-ui/src/authentication/routes/CreateFlow.tsx +++ b/js/apps/admin-ui/src/authentication/routes/CreateFlow.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type CreateFlowParams = { realm: string }; @@ -17,5 +17,5 @@ export const CreateFlowRoute: AppRouteObject = { }; export const toCreateFlow = (params: CreateFlowParams): Partial => ({ - pathname: generatePath(CreateFlowRoute.path, params), + pathname: generateEncodedPath(CreateFlowRoute.path, params), }); diff --git a/js/apps/admin-ui/src/authentication/routes/Flow.tsx b/js/apps/admin-ui/src/authentication/routes/Flow.tsx index 826e5a1ce76b..aa6f0cc94b30 100644 --- a/js/apps/admin-ui/src/authentication/routes/Flow.tsx +++ b/js/apps/admin-ui/src/authentication/routes/Flow.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type FlowParams = { @@ -30,6 +30,6 @@ export const toFlow = (params: FlowParams): Partial => { const path = params.builtIn ? FlowWithBuiltInRoute.path : FlowRoute.path; return { - pathname: generatePath(path, params), + pathname: generateEncodedPath(path, params), }; }; diff --git a/js/apps/admin-ui/src/client-scopes/routes/ClientScope.tsx b/js/apps/admin-ui/src/client-scopes/routes/ClientScope.tsx index 99683479f609..baf4dbf21045 100644 --- a/js/apps/admin-ui/src/client-scopes/routes/ClientScope.tsx +++ b/js/apps/admin-ui/src/client-scopes/routes/ClientScope.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type ClientScopeTab = "settings" | "mappers" | "scope"; @@ -26,6 +26,6 @@ export const toClientScope = (params: ClientScopeParams): Partial => { const path = ClientScopeRoute.path; return { - pathname: generatePath(path, params), + pathname: generateEncodedPath(path, params), }; }; diff --git a/js/apps/admin-ui/src/client-scopes/routes/ClientScopes.tsx b/js/apps/admin-ui/src/client-scopes/routes/ClientScopes.tsx index e3b2e679d2f7..0738268a101f 100644 --- a/js/apps/admin-ui/src/client-scopes/routes/ClientScopes.tsx +++ b/js/apps/admin-ui/src/client-scopes/routes/ClientScopes.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type ClientScopesParams = { realm: string }; @@ -17,5 +17,5 @@ export const ClientScopesRoute: AppRouteObject = { }; export const toClientScopes = (params: ClientScopesParams): Partial => ({ - pathname: generatePath(ClientScopesRoute.path, params), + pathname: generateEncodedPath(ClientScopesRoute.path, params), }); diff --git a/js/apps/admin-ui/src/client-scopes/routes/Mapper.tsx b/js/apps/admin-ui/src/client-scopes/routes/Mapper.tsx index 39a4c7b559ae..53aa93719a42 100644 --- a/js/apps/admin-ui/src/client-scopes/routes/Mapper.tsx +++ b/js/apps/admin-ui/src/client-scopes/routes/Mapper.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type MapperParams = { @@ -21,5 +21,5 @@ export const MapperRoute: AppRouteObject = { }; export const toMapper = (params: MapperParams): Partial => ({ - pathname: generatePath(MapperRoute.path, params), + pathname: generateEncodedPath(MapperRoute.path, params), }); diff --git a/js/apps/admin-ui/src/client-scopes/routes/NewClientScope.tsx b/js/apps/admin-ui/src/client-scopes/routes/NewClientScope.tsx index bf49153b9711..205420b8058b 100644 --- a/js/apps/admin-ui/src/client-scopes/routes/NewClientScope.tsx +++ b/js/apps/admin-ui/src/client-scopes/routes/NewClientScope.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type NewClientScopeParams = { realm: string }; @@ -19,5 +19,5 @@ export const NewClientScopeRoute: AppRouteObject = { export const toNewClientScope = ( params: NewClientScopeParams, ): Partial => ({ - pathname: generatePath(NewClientScopeRoute.path, params), + pathname: generateEncodedPath(NewClientScopeRoute.path, params), }); diff --git a/js/apps/admin-ui/src/clients/routes/AddClient.tsx b/js/apps/admin-ui/src/clients/routes/AddClient.tsx index d6430a3fba16..3efd72507cac 100644 --- a/js/apps/admin-ui/src/clients/routes/AddClient.tsx +++ b/js/apps/admin-ui/src/clients/routes/AddClient.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type AddClientParams = { realm: string }; @@ -17,5 +17,5 @@ export const AddClientRoute: AppRouteObject = { }; export const toAddClient = (params: AddClientParams): Partial => ({ - pathname: generatePath(AddClientRoute.path, params), + pathname: generateEncodedPath(AddClientRoute.path, params), }); diff --git a/js/apps/admin-ui/src/clients/routes/AddRegistrationProvider.tsx b/js/apps/admin-ui/src/clients/routes/AddRegistrationProvider.tsx index 60b63d56448b..d30b33a700d5 100644 --- a/js/apps/admin-ui/src/clients/routes/AddRegistrationProvider.tsx +++ b/js/apps/admin-ui/src/clients/routes/AddRegistrationProvider.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; import { ClientRegistrationTab } from "./ClientRegistration"; @@ -35,6 +35,6 @@ export const toRegistrationProvider = ( : AddRegistrationProviderRoute.path; return { - pathname: generatePath(path, params), + pathname: generateEncodedPath(path, params), }; }; diff --git a/js/apps/admin-ui/src/clients/routes/AuthenticationTab.tsx b/js/apps/admin-ui/src/clients/routes/AuthenticationTab.tsx index 50a5b6f61cca..16c1f6530496 100644 --- a/js/apps/admin-ui/src/clients/routes/AuthenticationTab.tsx +++ b/js/apps/admin-ui/src/clients/routes/AuthenticationTab.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type AuthorizationTab = @@ -32,5 +32,5 @@ export const AuthorizationRoute: AppRouteObject = { export const toAuthorizationTab = ( params: AuthorizationParams, ): Partial => ({ - pathname: generatePath(AuthorizationRoute.path, params), + pathname: generateEncodedPath(AuthorizationRoute.path, params), }); diff --git a/js/apps/admin-ui/src/clients/routes/Client.tsx b/js/apps/admin-ui/src/clients/routes/Client.tsx index 0b0ede17055e..2701af4f0c00 100644 --- a/js/apps/admin-ui/src/clients/routes/Client.tsx +++ b/js/apps/admin-ui/src/clients/routes/Client.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type ClientTab = @@ -34,5 +34,5 @@ export const ClientRoute: AppRouteObject = { }; export const toClient = (params: ClientParams): Partial => ({ - pathname: generatePath(ClientRoute.path, params), + pathname: generateEncodedPath(ClientRoute.path, params), }); diff --git a/js/apps/admin-ui/src/clients/routes/ClientRegistration.tsx b/js/apps/admin-ui/src/clients/routes/ClientRegistration.tsx index daf8a1d342c6..b12bd82e36ea 100644 --- a/js/apps/admin-ui/src/clients/routes/ClientRegistration.tsx +++ b/js/apps/admin-ui/src/clients/routes/ClientRegistration.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type ClientRegistrationTab = "anonymous" | "authenticated"; @@ -24,5 +24,5 @@ export const ClientRegistrationRoute: AppRouteObject = { export const toClientRegistration = ( params: ClientRegistrationParams, ): Partial => ({ - pathname: generatePath(ClientRegistrationRoute.path, params), + pathname: generateEncodedPath(ClientRegistrationRoute.path, params), }); diff --git a/js/apps/admin-ui/src/clients/routes/ClientRole.tsx b/js/apps/admin-ui/src/clients/routes/ClientRole.tsx index 66b55d94f92d..d9e5fbb54cc2 100644 --- a/js/apps/admin-ui/src/clients/routes/ClientRole.tsx +++ b/js/apps/admin-ui/src/clients/routes/ClientRole.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type ClientRoleTab = @@ -28,5 +28,5 @@ export const ClientRoleRoute: AppRouteObject = { } satisfies AppRouteObject; export const toClientRole = (params: ClientRoleParams): Partial => ({ - pathname: generatePath(ClientRoleRoute.path, params), + pathname: generateEncodedPath(ClientRoleRoute.path, params), }); diff --git a/js/apps/admin-ui/src/clients/routes/ClientScopeTab.tsx b/js/apps/admin-ui/src/clients/routes/ClientScopeTab.tsx index eee2c8e9558e..097c13fd4e7e 100644 --- a/js/apps/admin-ui/src/clients/routes/ClientScopeTab.tsx +++ b/js/apps/admin-ui/src/clients/routes/ClientScopeTab.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type ClientScopesTab = "setup" | "evaluate"; @@ -25,5 +25,5 @@ export const ClientScopesRoute: AppRouteObject = { export const toClientScopesTab = ( params: ClientScopesParams, ): Partial => ({ - pathname: generatePath(ClientScopesRoute.path, params), + pathname: generateEncodedPath(ClientScopesRoute.path, params), }); diff --git a/js/apps/admin-ui/src/clients/routes/Clients.tsx b/js/apps/admin-ui/src/clients/routes/Clients.tsx index 3a017ca9d727..1ee8ac98f59d 100644 --- a/js/apps/admin-ui/src/clients/routes/Clients.tsx +++ b/js/apps/admin-ui/src/clients/routes/Clients.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type ClientsTab = @@ -33,6 +33,6 @@ export const toClients = (params: ClientsParams): Partial => { const path = params.tab ? ClientsRouteWithTab.path : ClientsRoute.path; return { - pathname: generatePath(path, params), + pathname: generateEncodedPath(path, params), }; }; diff --git a/js/apps/admin-ui/src/clients/routes/CreateInitialAccessToken.tsx b/js/apps/admin-ui/src/clients/routes/CreateInitialAccessToken.tsx index bfd9f6b8356b..a8d4972d5ffe 100644 --- a/js/apps/admin-ui/src/clients/routes/CreateInitialAccessToken.tsx +++ b/js/apps/admin-ui/src/clients/routes/CreateInitialAccessToken.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type CreateInitialAccessTokenParams = { realm: string }; @@ -21,5 +21,5 @@ export const CreateInitialAccessTokenRoute: AppRouteObject = { export const toCreateInitialAccessToken = ( params: CreateInitialAccessTokenParams, ): Partial => ({ - pathname: generatePath(CreateInitialAccessTokenRoute.path, params), + pathname: generateEncodedPath(CreateInitialAccessTokenRoute.path, params), }); diff --git a/js/apps/admin-ui/src/clients/routes/DedicatedScopeDetails.tsx b/js/apps/admin-ui/src/clients/routes/DedicatedScopeDetails.tsx index 3868ec7ac83c..11201cfd7c21 100644 --- a/js/apps/admin-ui/src/clients/routes/DedicatedScopeDetails.tsx +++ b/js/apps/admin-ui/src/clients/routes/DedicatedScopeDetails.tsx @@ -1,7 +1,7 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; import type { AppRouteObject } from "../../routes"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; export type DedicatedScopeTab = "mappers" | "scope"; @@ -35,6 +35,6 @@ export const toDedicatedScope = ( : DedicatedScopeDetailsRoute.path; return { - pathname: generatePath(path, params), + pathname: generateEncodedPath(path, params), }; }; diff --git a/js/apps/admin-ui/src/clients/routes/ImportClient.tsx b/js/apps/admin-ui/src/clients/routes/ImportClient.tsx index 70f730b0c174..08357b51a6c3 100644 --- a/js/apps/admin-ui/src/clients/routes/ImportClient.tsx +++ b/js/apps/admin-ui/src/clients/routes/ImportClient.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type ImportClientParams = { realm: string }; @@ -17,5 +17,5 @@ export const ImportClientRoute: AppRouteObject = { }; export const toImportClient = (params: ImportClientParams): Partial => ({ - pathname: generatePath(ImportClientRoute.path, params), + pathname: generateEncodedPath(ImportClientRoute.path, params), }); diff --git a/js/apps/admin-ui/src/clients/routes/Mapper.tsx b/js/apps/admin-ui/src/clients/routes/Mapper.tsx index b361c82a3c0d..f101c39aadb0 100644 --- a/js/apps/admin-ui/src/clients/routes/Mapper.tsx +++ b/js/apps/admin-ui/src/clients/routes/Mapper.tsx @@ -1,7 +1,7 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; import type { AppRouteObject } from "../../routes"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; export type MapperParams = { realm: string; @@ -23,5 +23,5 @@ export const MapperRoute: AppRouteObject = { }; export const toMapper = (params: MapperParams): Partial => ({ - pathname: generatePath(MapperRoute.path, params), + pathname: generateEncodedPath(MapperRoute.path, params), }); diff --git a/js/apps/admin-ui/src/clients/routes/NewPermission.tsx b/js/apps/admin-ui/src/clients/routes/NewPermission.tsx index e87d85d4b786..c65dd0106941 100644 --- a/js/apps/admin-ui/src/clients/routes/NewPermission.tsx +++ b/js/apps/admin-ui/src/clients/routes/NewPermission.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type PermissionType = "resource" | "scope"; @@ -36,6 +36,6 @@ export const toNewPermission = (params: NewPermissionParams): Partial => { : NewPermissionRoute.path; return { - pathname: generatePath(path, params), + pathname: generateEncodedPath(path, params), }; }; diff --git a/js/apps/admin-ui/src/clients/routes/NewPolicy.tsx b/js/apps/admin-ui/src/clients/routes/NewPolicy.tsx index 5bb46b982e5a..5afea2aa30db 100644 --- a/js/apps/admin-ui/src/clients/routes/NewPolicy.tsx +++ b/js/apps/admin-ui/src/clients/routes/NewPolicy.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type NewPolicyParams = { realm: string; id: string; policyType: string }; @@ -19,5 +19,5 @@ export const NewPolicyRoute: AppRouteObject = { }; export const toCreatePolicy = (params: NewPolicyParams): Partial => ({ - pathname: generatePath(NewPolicyRoute.path, params), + pathname: generateEncodedPath(NewPolicyRoute.path, params), }); diff --git a/js/apps/admin-ui/src/clients/routes/NewResource.tsx b/js/apps/admin-ui/src/clients/routes/NewResource.tsx index 8f362c5ac6a7..4acf2112595f 100644 --- a/js/apps/admin-ui/src/clients/routes/NewResource.tsx +++ b/js/apps/admin-ui/src/clients/routes/NewResource.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type NewResourceParams = { realm: string; id: string }; @@ -17,5 +17,5 @@ export const NewResourceRoute: AppRouteObject = { }; export const toCreateResource = (params: NewResourceParams): Partial => ({ - pathname: generatePath(NewResourceRoute.path, params), + pathname: generateEncodedPath(NewResourceRoute.path, params), }); diff --git a/js/apps/admin-ui/src/clients/routes/NewRole.tsx b/js/apps/admin-ui/src/clients/routes/NewRole.tsx index 360835501ba5..0015c5f0812d 100644 --- a/js/apps/admin-ui/src/clients/routes/NewRole.tsx +++ b/js/apps/admin-ui/src/clients/routes/NewRole.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type NewRoleParams = { realm: string; clientId: string }; @@ -17,5 +17,5 @@ export const NewRoleRoute: AppRouteObject = { }; export const toCreateRole = (params: NewRoleParams): Partial => ({ - pathname: generatePath(NewRoleRoute.path, params), + pathname: generateEncodedPath(NewRoleRoute.path, params), }); diff --git a/js/apps/admin-ui/src/clients/routes/NewScope.tsx b/js/apps/admin-ui/src/clients/routes/NewScope.tsx index c3beb80d20a7..488a3bf9b384 100644 --- a/js/apps/admin-ui/src/clients/routes/NewScope.tsx +++ b/js/apps/admin-ui/src/clients/routes/NewScope.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type NewScopeParams = { realm: string; id: string }; @@ -17,5 +17,5 @@ export const NewScopeRoute: AppRouteObject = { }; export const toNewScope = (params: NewScopeParams): Partial => ({ - pathname: generatePath(NewScopeRoute.path, params), + pathname: generateEncodedPath(NewScopeRoute.path, params), }); diff --git a/js/apps/admin-ui/src/clients/routes/PermissionDetails.tsx b/js/apps/admin-ui/src/clients/routes/PermissionDetails.tsx index ad24dc117f6e..d3673302e1f9 100644 --- a/js/apps/admin-ui/src/clients/routes/PermissionDetails.tsx +++ b/js/apps/admin-ui/src/clients/routes/PermissionDetails.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; import type { PermissionType } from "./NewPermission"; @@ -27,5 +27,5 @@ export const PermissionDetailsRoute: AppRouteObject = { export const toPermissionDetails = ( params: PermissionDetailsParams, ): Partial => ({ - pathname: generatePath(PermissionDetailsRoute.path, params), + pathname: generateEncodedPath(PermissionDetailsRoute.path, params), }); diff --git a/js/apps/admin-ui/src/clients/routes/PolicyDetails.tsx b/js/apps/admin-ui/src/clients/routes/PolicyDetails.tsx index 870034cb5ebb..5332ce5641cd 100644 --- a/js/apps/admin-ui/src/clients/routes/PolicyDetails.tsx +++ b/js/apps/admin-ui/src/clients/routes/PolicyDetails.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type PolicyDetailsParams = { @@ -26,5 +26,5 @@ export const PolicyDetailsRoute: AppRouteObject = { export const toPolicyDetails = ( params: PolicyDetailsParams, ): Partial => ({ - pathname: generatePath(PolicyDetailsRoute.path, params), + pathname: generateEncodedPath(PolicyDetailsRoute.path, params), }); diff --git a/js/apps/admin-ui/src/clients/routes/Resource.tsx b/js/apps/admin-ui/src/clients/routes/Resource.tsx index c1ffbf10ecb4..661e1da1df2c 100644 --- a/js/apps/admin-ui/src/clients/routes/Resource.tsx +++ b/js/apps/admin-ui/src/clients/routes/Resource.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type ResourceDetailsParams = { @@ -33,6 +33,6 @@ export const toResourceDetails = ( : ResourceDetailsRoute.path; return { - pathname: generatePath(path, params), + pathname: generateEncodedPath(path, params), }; }; diff --git a/js/apps/admin-ui/src/clients/routes/Scope.tsx b/js/apps/admin-ui/src/clients/routes/Scope.tsx index 76372499d276..68d1e1222689 100644 --- a/js/apps/admin-ui/src/clients/routes/Scope.tsx +++ b/js/apps/admin-ui/src/clients/routes/Scope.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type ScopeDetailsParams = { @@ -31,6 +31,6 @@ export const toScopeDetails = (params: ScopeDetailsParams): Partial => { : ScopeDetailsRoute.path; return { - pathname: generatePath(path, params), + pathname: generateEncodedPath(path, params), }; }; diff --git a/js/apps/admin-ui/src/dashboard/routes/Dashboard.tsx b/js/apps/admin-ui/src/dashboard/routes/Dashboard.tsx index be097d0b0061..d6b7e666651e 100644 --- a/js/apps/admin-ui/src/dashboard/routes/Dashboard.tsx +++ b/js/apps/admin-ui/src/dashboard/routes/Dashboard.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type DashboardTab = "info" | "providers"; @@ -36,6 +36,6 @@ export const toDashboard = (params: DashboardParams): Partial => { : DashboardRoute.path; return { - pathname: generatePath(pathname, params), + pathname: generateEncodedPath(pathname, params), }; }; diff --git a/js/apps/admin-ui/src/events/routes/Events.tsx b/js/apps/admin-ui/src/events/routes/Events.tsx index 1ad8bc794a79..377a32762faf 100644 --- a/js/apps/admin-ui/src/events/routes/Events.tsx +++ b/js/apps/admin-ui/src/events/routes/Events.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type EventsTab = "user-events" | "admin-events"; @@ -30,6 +30,6 @@ export const toEvents = (params: EventsParams): Partial => { const path = params.tab ? EventsRouteWithTab.path : EventsRoute.path; return { - pathname: generatePath(path, params), + pathname: generateEncodedPath(path, params), }; }; diff --git a/js/apps/admin-ui/src/groups/routes/Groups.tsx b/js/apps/admin-ui/src/groups/routes/Groups.tsx index a98b5f6e4afb..2d14cc72d8f8 100644 --- a/js/apps/admin-ui/src/groups/routes/Groups.tsx +++ b/js/apps/admin-ui/src/groups/routes/Groups.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type GroupsParams = { realm: string; id?: string; lazy?: string }; @@ -24,6 +24,6 @@ export const toGroups = (params: GroupsParams): Partial => { const path = params.id ? GroupsWithIdRoute.path : GroupsRoute.path; return { - pathname: generatePath(path, params), + pathname: generateEncodedPath(path, params), }; }; diff --git a/js/apps/admin-ui/src/identity-providers/routes/AddMapper.tsx b/js/apps/admin-ui/src/identity-providers/routes/AddMapper.tsx index 1b8871db006b..3b5afdac54d7 100644 --- a/js/apps/admin-ui/src/identity-providers/routes/AddMapper.tsx +++ b/js/apps/admin-ui/src/identity-providers/routes/AddMapper.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type IdentityProviderAddMapperParams = { @@ -24,5 +24,5 @@ export const IdentityProviderAddMapperRoute: AppRouteObject = { export const toIdentityProviderAddMapper = ( params: IdentityProviderAddMapperParams, ): Partial => ({ - pathname: generatePath(IdentityProviderAddMapperRoute.path, params), + pathname: generateEncodedPath(IdentityProviderAddMapperRoute.path, params), }); diff --git a/js/apps/admin-ui/src/identity-providers/routes/EditMapper.tsx b/js/apps/admin-ui/src/identity-providers/routes/EditMapper.tsx index 341ddcde1ec7..a0be6312b908 100644 --- a/js/apps/admin-ui/src/identity-providers/routes/EditMapper.tsx +++ b/js/apps/admin-ui/src/identity-providers/routes/EditMapper.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type IdentityProviderEditMapperParams = { @@ -24,5 +24,5 @@ export const IdentityProviderEditMapperRoute: AppRouteObject = { export const toIdentityProviderEditMapper = ( params: IdentityProviderEditMapperParams, ): Partial => ({ - pathname: generatePath(IdentityProviderEditMapperRoute.path, params), + pathname: generateEncodedPath(IdentityProviderEditMapperRoute.path, params), }); diff --git a/js/apps/admin-ui/src/identity-providers/routes/IdentityProvider.tsx b/js/apps/admin-ui/src/identity-providers/routes/IdentityProvider.tsx index 016843cfe987..31090bd15ead 100644 --- a/js/apps/admin-ui/src/identity-providers/routes/IdentityProvider.tsx +++ b/js/apps/admin-ui/src/identity-providers/routes/IdentityProvider.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type IdentityProviderTab = "settings" | "mappers" | "permissions"; @@ -26,5 +26,5 @@ export const IdentityProviderRoute: AppRouteObject = { export const toIdentityProvider = ( params: IdentityProviderParams, ): Partial => ({ - pathname: generatePath(IdentityProviderRoute.path, params), + pathname: generateEncodedPath(IdentityProviderRoute.path, params), }); diff --git a/js/apps/admin-ui/src/identity-providers/routes/IdentityProviderCreate.tsx b/js/apps/admin-ui/src/identity-providers/routes/IdentityProviderCreate.tsx index 843bd2bae037..e719543ed968 100644 --- a/js/apps/admin-ui/src/identity-providers/routes/IdentityProviderCreate.tsx +++ b/js/apps/admin-ui/src/identity-providers/routes/IdentityProviderCreate.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type IdentityProviderCreateParams = { @@ -22,5 +22,5 @@ export const IdentityProviderCreateRoute: AppRouteObject = { export const toIdentityProviderCreate = ( params: IdentityProviderCreateParams, ): Partial => ({ - pathname: generatePath(IdentityProviderCreateRoute.path, params), + pathname: generateEncodedPath(IdentityProviderCreateRoute.path, params), }); diff --git a/js/apps/admin-ui/src/identity-providers/routes/IdentityProviderKeycloakOidc.tsx b/js/apps/admin-ui/src/identity-providers/routes/IdentityProviderKeycloakOidc.tsx index a3450df941d6..69f5ae3ad161 100644 --- a/js/apps/admin-ui/src/identity-providers/routes/IdentityProviderKeycloakOidc.tsx +++ b/js/apps/admin-ui/src/identity-providers/routes/IdentityProviderKeycloakOidc.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type IdentityProviderKeycloakOidcParams = { realm: string }; @@ -19,5 +19,5 @@ export const IdentityProviderKeycloakOidcRoute: AppRouteObject = { export const toIdentityProviderKeycloakOidc = ( params: IdentityProviderKeycloakOidcParams, ): Partial => ({ - pathname: generatePath(IdentityProviderKeycloakOidcRoute.path, params), + pathname: generateEncodedPath(IdentityProviderKeycloakOidcRoute.path, params), }); diff --git a/js/apps/admin-ui/src/identity-providers/routes/IdentityProviderOidc.tsx b/js/apps/admin-ui/src/identity-providers/routes/IdentityProviderOidc.tsx index 46f0335420f5..56842791e55d 100644 --- a/js/apps/admin-ui/src/identity-providers/routes/IdentityProviderOidc.tsx +++ b/js/apps/admin-ui/src/identity-providers/routes/IdentityProviderOidc.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type IdentityProviderOidcParams = { realm: string }; @@ -19,5 +19,5 @@ export const IdentityProviderOidcRoute: AppRouteObject = { export const toIdentityProviderOidc = ( params: IdentityProviderOidcParams, ): Partial => ({ - pathname: generatePath(IdentityProviderOidcRoute.path, params), + pathname: generateEncodedPath(IdentityProviderOidcRoute.path, params), }); diff --git a/js/apps/admin-ui/src/identity-providers/routes/IdentityProviderSaml.tsx b/js/apps/admin-ui/src/identity-providers/routes/IdentityProviderSaml.tsx index 7eb967f77d79..801e8cbadbc6 100644 --- a/js/apps/admin-ui/src/identity-providers/routes/IdentityProviderSaml.tsx +++ b/js/apps/admin-ui/src/identity-providers/routes/IdentityProviderSaml.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type IdentityProviderSamlParams = { realm: string }; @@ -19,5 +19,5 @@ export const IdentityProviderSamlRoute: AppRouteObject = { export const toIdentityProviderSaml = ( params: IdentityProviderSamlParams, ): Partial => ({ - pathname: generatePath(IdentityProviderSamlRoute.path, params), + pathname: generateEncodedPath(IdentityProviderSamlRoute.path, params), }); diff --git a/js/apps/admin-ui/src/identity-providers/routes/IdentityProviders.tsx b/js/apps/admin-ui/src/identity-providers/routes/IdentityProviders.tsx index 3645968b8525..83708c8b2fbd 100644 --- a/js/apps/admin-ui/src/identity-providers/routes/IdentityProviders.tsx +++ b/js/apps/admin-ui/src/identity-providers/routes/IdentityProviders.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type IdentityProvidersParams = { realm: string }; @@ -21,5 +21,5 @@ export const IdentityProvidersRoute: AppRouteObject = { export const toIdentityProviders = ( params: IdentityProvidersParams, ): Partial => ({ - pathname: generatePath(IdentityProvidersRoute.path, params), + pathname: generateEncodedPath(IdentityProvidersRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-roles/routes/AddRole.tsx b/js/apps/admin-ui/src/realm-roles/routes/AddRole.tsx index b55ce8cec0dd..9cd53799bd5f 100644 --- a/js/apps/admin-ui/src/realm-roles/routes/AddRole.tsx +++ b/js/apps/admin-ui/src/realm-roles/routes/AddRole.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type AddRoleParams = { realm: string }; @@ -17,5 +17,5 @@ export const AddRoleRoute: AppRouteObject = { }; export const toAddRole = (params: AddRoleParams): Partial => ({ - pathname: generatePath(AddRoleRoute.path, params), + pathname: generateEncodedPath(AddRoleRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-roles/routes/RealmRole.tsx b/js/apps/admin-ui/src/realm-roles/routes/RealmRole.tsx index 80d6c84e0c34..19ec0a502a85 100644 --- a/js/apps/admin-ui/src/realm-roles/routes/RealmRole.tsx +++ b/js/apps/admin-ui/src/realm-roles/routes/RealmRole.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; @@ -29,5 +29,5 @@ export const RealmRoleRoute: AppRouteObject = { }; export const toRealmRole = (params: RealmRoleParams): Partial => ({ - pathname: generatePath(RealmRoleRoute.path, params), + pathname: generateEncodedPath(RealmRoleRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-roles/routes/RealmRoles.tsx b/js/apps/admin-ui/src/realm-roles/routes/RealmRoles.tsx index 974c0f9d833f..9c906bc9b1fc 100644 --- a/js/apps/admin-ui/src/realm-roles/routes/RealmRoles.tsx +++ b/js/apps/admin-ui/src/realm-roles/routes/RealmRoles.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type RealmRolesParams = { realm: string }; @@ -17,5 +17,5 @@ export const RealmRolesRoute: AppRouteObject = { }; export const toRealmRoles = (params: RealmRolesParams): Partial => ({ - pathname: generatePath(RealmRolesRoute.path, params), + pathname: generateEncodedPath(RealmRolesRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-settings/routes/AddAttribute.tsx b/js/apps/admin-ui/src/realm-settings/routes/AddAttribute.tsx index f1f272e50b9a..f3fbe8075e8a 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/AddAttribute.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/AddAttribute.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type AddAttributeParams = { @@ -19,5 +19,5 @@ export const AddAttributeRoute: AppRouteObject = { }; export const toAddAttribute = (params: AddAttributeParams): Partial => ({ - pathname: generatePath(AddAttributeRoute.path, params), + pathname: generateEncodedPath(AddAttributeRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-settings/routes/AddClientPolicy.tsx b/js/apps/admin-ui/src/realm-settings/routes/AddClientPolicy.tsx index 303dba582572..7dd0eec2c8c2 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/AddClientPolicy.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/AddClientPolicy.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type AddClientPolicyParams = { realm: string }; @@ -19,5 +19,5 @@ export const AddClientPolicyRoute: AppRouteObject = { export const toAddClientPolicy = ( params: AddClientPolicyParams, ): Partial => ({ - pathname: generatePath(AddClientPolicyRoute.path, params), + pathname: generateEncodedPath(AddClientPolicyRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-settings/routes/AddClientProfile.tsx b/js/apps/admin-ui/src/realm-settings/routes/AddClientProfile.tsx index e50370a839d6..16b06f0f386d 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/AddClientProfile.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/AddClientProfile.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type AddClientProfileParams = { @@ -22,5 +22,5 @@ export const AddClientProfileRoute: AppRouteObject = { export const toAddClientProfile = ( params: AddClientProfileParams, ): Partial => ({ - pathname: generatePath(AddClientProfileRoute.path, params), + pathname: generateEncodedPath(AddClientProfileRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-settings/routes/AddCondition.tsx b/js/apps/admin-ui/src/realm-settings/routes/AddCondition.tsx index 8dc7e86df698..4b030ff0447f 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/AddCondition.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/AddCondition.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type NewClientPolicyConditionParams = { @@ -24,5 +24,5 @@ export const NewClientPolicyConditionRoute: AppRouteObject = { export const toNewClientPolicyCondition = ( params: NewClientPolicyConditionParams, ): Partial => ({ - pathname: generatePath(NewClientPolicyConditionRoute.path, params), + pathname: generateEncodedPath(NewClientPolicyConditionRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-settings/routes/AddExecutor.tsx b/js/apps/admin-ui/src/realm-settings/routes/AddExecutor.tsx index ba1cdef6ea90..061dcc9af4a3 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/AddExecutor.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/AddExecutor.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type AddExecutorParams = { @@ -20,5 +20,5 @@ export const AddExecutorRoute: AppRouteObject = { }; export const toAddExecutor = (params: AddExecutorParams): Partial => ({ - pathname: generatePath(AddExecutorRoute.path, params), + pathname: generateEncodedPath(AddExecutorRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-settings/routes/Attribute.tsx b/js/apps/admin-ui/src/realm-settings/routes/Attribute.tsx index 95b33614941e..964f0e537c50 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/Attribute.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/Attribute.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type AttributeParams = { @@ -20,5 +20,5 @@ export const AttributeRoute: AppRouteObject = { }; export const toAttribute = (params: AttributeParams): Partial => ({ - pathname: generatePath(AttributeRoute.path, params), + pathname: generateEncodedPath(AttributeRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-settings/routes/ClientPolicies.tsx b/js/apps/admin-ui/src/realm-settings/routes/ClientPolicies.tsx index 53877ab5c60d..c97cb97a1022 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/ClientPolicies.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/ClientPolicies.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type ClientPoliciesTab = "profiles" | "policies"; @@ -24,5 +24,5 @@ export const ClientPoliciesRoute: AppRouteObject = { export const toClientPolicies = ( params: ClientPoliciesParams, ): Partial => ({ - pathname: generatePath(ClientPoliciesRoute.path, params), + pathname: generateEncodedPath(ClientPoliciesRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-settings/routes/ClientProfile.tsx b/js/apps/admin-ui/src/realm-settings/routes/ClientProfile.tsx index 76ed590974e0..1aaec6cf8db4 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/ClientProfile.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/ClientProfile.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type ClientProfileParams = { @@ -22,5 +22,5 @@ export const ClientProfileRoute: AppRouteObject = { export const toClientProfile = ( params: ClientProfileParams, ): Partial => ({ - pathname: generatePath(ClientProfileRoute.path, params), + pathname: generateEncodedPath(ClientProfileRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-settings/routes/EditAttributesGroup.tsx b/js/apps/admin-ui/src/realm-settings/routes/EditAttributesGroup.tsx index 61d897e26c07..346f04903b50 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/EditAttributesGroup.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/EditAttributesGroup.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type EditAttributesGroupParams = { @@ -24,5 +24,5 @@ export const EditAttributesGroupRoute: AppRouteObject = { export const toEditAttributesGroup = ( params: EditAttributesGroupParams, ): Partial => ({ - pathname: generatePath(EditAttributesGroupRoute.path, params), + pathname: generateEncodedPath(EditAttributesGroupRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-settings/routes/EditClientPolicy.tsx b/js/apps/admin-ui/src/realm-settings/routes/EditClientPolicy.tsx index 41d9976450cd..218e86fc6e16 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/EditClientPolicy.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/EditClientPolicy.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type EditClientPolicyParams = { @@ -22,5 +22,5 @@ export const EditClientPolicyRoute: AppRouteObject = { export const toEditClientPolicy = ( params: EditClientPolicyParams, ): Partial => ({ - pathname: generatePath(EditClientPolicyRoute.path, params), + pathname: generateEncodedPath(EditClientPolicyRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-settings/routes/EditCondition.tsx b/js/apps/admin-ui/src/realm-settings/routes/EditCondition.tsx index 874e1068a2bb..2e966b7baccf 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/EditCondition.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/EditCondition.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type EditClientPolicyConditionParams = { @@ -25,5 +25,5 @@ export const EditClientPolicyConditionRoute: AppRouteObject = { export const toEditClientPolicyCondition = ( params: EditClientPolicyConditionParams, ): Partial => ({ - pathname: generatePath(EditClientPolicyConditionRoute.path, params), + pathname: generateEncodedPath(EditClientPolicyConditionRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-settings/routes/Executor.tsx b/js/apps/admin-ui/src/realm-settings/routes/Executor.tsx index 7c692c0c01e8..ab9933d1e8be 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/Executor.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/Executor.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type ExecutorParams = { @@ -21,5 +21,5 @@ export const ExecutorRoute: AppRouteObject = { }; export const toExecutor = (params: ExecutorParams): Partial => ({ - pathname: generatePath(ExecutorRoute.path, params), + pathname: generateEncodedPath(ExecutorRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-settings/routes/KeyProvider.tsx b/js/apps/admin-ui/src/realm-settings/routes/KeyProvider.tsx index 34c5f81e7046..82f34f20f850 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/KeyProvider.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/KeyProvider.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type ProviderType = @@ -33,5 +33,5 @@ export const KeyProviderFormRoute: AppRouteObject = { }; export const toKeyProvider = (params: KeyProviderParams): Partial => ({ - pathname: generatePath(KeyProviderFormRoute.path, params), + pathname: generateEncodedPath(KeyProviderFormRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-settings/routes/KeysTab.tsx b/js/apps/admin-ui/src/realm-settings/routes/KeysTab.tsx index 3b0ad87563c8..e86f0f9a35e6 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/KeysTab.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/KeysTab.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type KeySubTab = "list" | "providers"; @@ -22,5 +22,5 @@ export const KeysRoute: AppRouteObject = { }; export const toKeysTab = (params: KeysParams): Partial => ({ - pathname: generatePath(KeysRoute.path, params), + pathname: generateEncodedPath(KeysRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-settings/routes/NewAttributesGroup.tsx b/js/apps/admin-ui/src/realm-settings/routes/NewAttributesGroup.tsx index b22f687ec4df..ceefe5e040b0 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/NewAttributesGroup.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/NewAttributesGroup.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type NewAttributesGroupParams = { @@ -23,5 +23,5 @@ export const NewAttributesGroupRoute: AppRouteObject = { export const toNewAttributesGroup = ( params: NewAttributesGroupParams, ): Partial => ({ - pathname: generatePath(NewAttributesGroupRoute.path, params), + pathname: generateEncodedPath(NewAttributesGroupRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm-settings/routes/RealmSettings.tsx b/js/apps/admin-ui/src/realm-settings/routes/RealmSettings.tsx index a505a0dd4da7..781bc692236a 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/RealmSettings.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/RealmSettings.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type RealmSettingsTab = @@ -45,6 +45,6 @@ export const toRealmSettings = (params: RealmSettingsParams): Partial => { : RealmSettingsRoute.path; return { - pathname: generatePath(path, params), + pathname: generateEncodedPath(path, params), }; }; diff --git a/js/apps/admin-ui/src/realm-settings/routes/UserProfile.tsx b/js/apps/admin-ui/src/realm-settings/routes/UserProfile.tsx index 06e7f7d4e0fe..1a0fe9a33e7d 100644 --- a/js/apps/admin-ui/src/realm-settings/routes/UserProfile.tsx +++ b/js/apps/admin-ui/src/realm-settings/routes/UserProfile.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type UserProfileTab = "attributes" | "attributes-group" | "json-editor"; @@ -22,5 +22,5 @@ export const UserProfileRoute: AppRouteObject = { }; export const toUserProfile = (params: UserProfileParams): Partial => ({ - pathname: generatePath(UserProfileRoute.path, params), + pathname: generateEncodedPath(UserProfileRoute.path, params), }); diff --git a/js/apps/admin-ui/src/realm/routes/AddRealm.tsx b/js/apps/admin-ui/src/realm/routes/AddRealm.tsx index 5f598d26fa5b..9655d4a1e9c6 100644 --- a/js/apps/admin-ui/src/realm/routes/AddRealm.tsx +++ b/js/apps/admin-ui/src/realm/routes/AddRealm.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type AddRealmParams = { realm: string }; @@ -17,5 +17,5 @@ export const AddRealmRoute: AppRouteObject = { }; export const toAddRealm = (params: AddRealmParams): Partial => ({ - pathname: generatePath(AddRealmRoute.path, params), + pathname: generateEncodedPath(AddRealmRoute.path, params), }); diff --git a/js/apps/admin-ui/src/sessions/routes/Sessions.tsx b/js/apps/admin-ui/src/sessions/routes/Sessions.tsx index 98139db8db07..6811b61f5922 100644 --- a/js/apps/admin-ui/src/sessions/routes/Sessions.tsx +++ b/js/apps/admin-ui/src/sessions/routes/Sessions.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type SessionsParams = { realm: string }; @@ -17,5 +17,5 @@ export const SessionsRoute: AppRouteObject = { }; export const toSessions = (params: SessionsParams): Partial => ({ - pathname: generatePath(SessionsRoute.path, params), + pathname: generateEncodedPath(SessionsRoute.path, params), }); diff --git a/js/apps/admin-ui/src/user-federation/routes/CustomUserFederation.tsx b/js/apps/admin-ui/src/user-federation/routes/CustomUserFederation.tsx index 53137a2ab1a2..47c120e9fe6c 100644 --- a/js/apps/admin-ui/src/user-federation/routes/CustomUserFederation.tsx +++ b/js/apps/admin-ui/src/user-federation/routes/CustomUserFederation.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; @@ -26,5 +26,5 @@ export const CustomUserFederationRoute: AppRouteObject = { export const toCustomUserFederation = ( params: CustomUserFederationRouteParams, ): Partial => ({ - pathname: generatePath(CustomUserFederationRoute.path, params), + pathname: generateEncodedPath(CustomUserFederationRoute.path, params), }); diff --git a/js/apps/admin-ui/src/user-federation/routes/NewCustomUserFederation.tsx b/js/apps/admin-ui/src/user-federation/routes/NewCustomUserFederation.tsx index 2ec53e316cca..56af298e6c94 100644 --- a/js/apps/admin-ui/src/user-federation/routes/NewCustomUserFederation.tsx +++ b/js/apps/admin-ui/src/user-federation/routes/NewCustomUserFederation.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; @@ -25,5 +25,5 @@ export const NewCustomUserFederationRoute: AppRouteObject = { export const toNewCustomUserFederation = ( params: NewCustomUserFederationRouteParams, ): Partial => ({ - pathname: generatePath(NewCustomUserFederationRoute.path, params), + pathname: generateEncodedPath(NewCustomUserFederationRoute.path, params), }); diff --git a/js/apps/admin-ui/src/user-federation/routes/NewKerberosUserFederation.tsx b/js/apps/admin-ui/src/user-federation/routes/NewKerberosUserFederation.tsx index b6174499c4b2..7af89e4f0e21 100644 --- a/js/apps/admin-ui/src/user-federation/routes/NewKerberosUserFederation.tsx +++ b/js/apps/admin-ui/src/user-federation/routes/NewKerberosUserFederation.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type NewKerberosUserFederationParams = { realm: string }; @@ -21,5 +21,5 @@ export const NewKerberosUserFederationRoute: AppRouteObject = { export const toNewKerberosUserFederation = ( params: NewKerberosUserFederationParams, ): Partial => ({ - pathname: generatePath(NewKerberosUserFederationRoute.path, params), + pathname: generateEncodedPath(NewKerberosUserFederationRoute.path, params), }); diff --git a/js/apps/admin-ui/src/user-federation/routes/NewLdapUserFederation.tsx b/js/apps/admin-ui/src/user-federation/routes/NewLdapUserFederation.tsx index cb021242d01c..d21bff621f56 100644 --- a/js/apps/admin-ui/src/user-federation/routes/NewLdapUserFederation.tsx +++ b/js/apps/admin-ui/src/user-federation/routes/NewLdapUserFederation.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type NewLdapUserFederationParams = { realm: string }; @@ -21,5 +21,5 @@ export const NewLdapUserFederationRoute: AppRouteObject = { export const toNewLdapUserFederation = ( params: NewLdapUserFederationParams, ): Partial => ({ - pathname: generatePath(NewLdapUserFederationRoute.path, params), + pathname: generateEncodedPath(NewLdapUserFederationRoute.path, params), }); diff --git a/js/apps/admin-ui/src/user-federation/routes/UserFederation.tsx b/js/apps/admin-ui/src/user-federation/routes/UserFederation.tsx index 45ef09ee597c..b010ff0ac045 100644 --- a/js/apps/admin-ui/src/user-federation/routes/UserFederation.tsx +++ b/js/apps/admin-ui/src/user-federation/routes/UserFederation.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type UserFederationParams = { realm: string }; @@ -19,5 +19,5 @@ export const UserFederationRoute: AppRouteObject = { export const toUserFederation = ( params: UserFederationParams, ): Partial => ({ - pathname: generatePath(UserFederationRoute.path, params), + pathname: generateEncodedPath(UserFederationRoute.path, params), }); diff --git a/js/apps/admin-ui/src/user-federation/routes/UserFederationKerberos.tsx b/js/apps/admin-ui/src/user-federation/routes/UserFederationKerberos.tsx index 7b6b8a868d23..cbbe5b68fd19 100644 --- a/js/apps/admin-ui/src/user-federation/routes/UserFederationKerberos.tsx +++ b/js/apps/admin-ui/src/user-federation/routes/UserFederationKerberos.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type UserFederationKerberosParams = { @@ -24,5 +24,5 @@ export const UserFederationKerberosRoute: AppRouteObject = { export const toUserFederationKerberos = ( params: UserFederationKerberosParams, ): Partial => ({ - pathname: generatePath(UserFederationKerberosRoute.path, params), + pathname: generateEncodedPath(UserFederationKerberosRoute.path, params), }); diff --git a/js/apps/admin-ui/src/user-federation/routes/UserFederationLdap.tsx b/js/apps/admin-ui/src/user-federation/routes/UserFederationLdap.tsx index ca2a68a8f4b3..ff646872cbaa 100644 --- a/js/apps/admin-ui/src/user-federation/routes/UserFederationLdap.tsx +++ b/js/apps/admin-ui/src/user-federation/routes/UserFederationLdap.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type UserFederationLdapTab = "settings" | "mappers"; @@ -37,6 +37,6 @@ export const toUserFederationLdap = ( : UserFederationLdapRoute.path; return { - pathname: generatePath(path, params), + pathname: generateEncodedPath(path, params), }; }; diff --git a/js/apps/admin-ui/src/user-federation/routes/UserFederationLdapMapper.tsx b/js/apps/admin-ui/src/user-federation/routes/UserFederationLdapMapper.tsx index e05a9fab1085..0fa0bc961731 100644 --- a/js/apps/admin-ui/src/user-federation/routes/UserFederationLdapMapper.tsx +++ b/js/apps/admin-ui/src/user-federation/routes/UserFederationLdapMapper.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type UserFederationLdapMapperParams = { @@ -25,5 +25,5 @@ export const UserFederationLdapMapperRoute: AppRouteObject = { export const toUserFederationLdapMapper = ( params: UserFederationLdapMapperParams, ): Partial => ({ - pathname: generatePath(UserFederationLdapMapperRoute.path, params), + pathname: generateEncodedPath(UserFederationLdapMapperRoute.path, params), }); diff --git a/js/apps/admin-ui/src/user-federation/routes/UserFederationsKerberos.tsx b/js/apps/admin-ui/src/user-federation/routes/UserFederationsKerberos.tsx index 7f4a41871b0f..182ddb48de18 100644 --- a/js/apps/admin-ui/src/user-federation/routes/UserFederationsKerberos.tsx +++ b/js/apps/admin-ui/src/user-federation/routes/UserFederationsKerberos.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type UserFederationsKerberosParams = { realm: string }; @@ -18,5 +18,5 @@ export const UserFederationsKerberosRoute: AppRouteObject = { export const toUserFederationsKerberos = ( params: UserFederationsKerberosParams, ): Partial => ({ - pathname: generatePath(UserFederationsKerberosRoute.path, params), + pathname: generateEncodedPath(UserFederationsKerberosRoute.path, params), }); diff --git a/js/apps/admin-ui/src/user-federation/routes/UserFederationsLdap.tsx b/js/apps/admin-ui/src/user-federation/routes/UserFederationsLdap.tsx index b02fda3ecc6b..7445273c79e3 100644 --- a/js/apps/admin-ui/src/user-federation/routes/UserFederationsLdap.tsx +++ b/js/apps/admin-ui/src/user-federation/routes/UserFederationsLdap.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type UserFederationsLdapParams = { realm: string }; @@ -18,5 +18,5 @@ export const UserFederationsLdapRoute: AppRouteObject = { export const toUserFederationsLdap = ( params: UserFederationsLdapParams, ): Partial => ({ - pathname: generatePath(UserFederationsLdapRoute.path, params), + pathname: generateEncodedPath(UserFederationsLdapRoute.path, params), }); diff --git a/js/apps/admin-ui/src/user/routes/AddUser.tsx b/js/apps/admin-ui/src/user/routes/AddUser.tsx index 86d53bcf88b3..9743c5dae77e 100644 --- a/js/apps/admin-ui/src/user/routes/AddUser.tsx +++ b/js/apps/admin-ui/src/user/routes/AddUser.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; @@ -18,5 +18,5 @@ export const AddUserRoute: AppRouteObject = { }; export const toAddUser = (params: AddUserParams): Partial => ({ - pathname: generatePath(AddUserRoute.path, params), + pathname: generateEncodedPath(AddUserRoute.path, params), }); diff --git a/js/apps/admin-ui/src/user/routes/User.tsx b/js/apps/admin-ui/src/user/routes/User.tsx index 378dc7c23219..808e42ef9d1b 100644 --- a/js/apps/admin-ui/src/user/routes/User.tsx +++ b/js/apps/admin-ui/src/user/routes/User.tsx @@ -1,6 +1,6 @@ import { lazy } from "react"; import type { Path } from "react-router-dom"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { AppRouteObject } from "../../routes"; export type UserTab = @@ -31,5 +31,5 @@ export const UserRoute: AppRouteObject = { }; export const toUser = (params: UserParams): Partial => ({ - pathname: generatePath(UserRoute.path, params), + pathname: generateEncodedPath(UserRoute.path, params), }); diff --git a/js/apps/admin-ui/src/user/routes/Users.tsx b/js/apps/admin-ui/src/user/routes/Users.tsx index 40d2f470fab8..26f8d4ff55f5 100644 --- a/js/apps/admin-ui/src/user/routes/Users.tsx +++ b/js/apps/admin-ui/src/user/routes/Users.tsx @@ -1,5 +1,5 @@ import { lazy } from "react"; -import { generatePath } from "react-router-dom"; +import { generateEncodedPath } from "../../utils/generateEncodedPath"; import type { Path } from "react-router-dom"; import type { AppRouteObject } from "../../routes"; @@ -27,6 +27,6 @@ export const toUsers = (params: UsersParams): Partial => { const path = params.tab ? UsersRouteWithTab.path : UsersRoute.path; return { - pathname: generatePath(path, params), + pathname: generateEncodedPath(path, params), }; }; diff --git a/js/apps/admin-ui/src/util.ts b/js/apps/admin-ui/src/util.ts index bf33712aca0c..9edc1baeaa13 100644 --- a/js/apps/admin-ui/src/util.ts +++ b/js/apps/admin-ui/src/util.ts @@ -2,7 +2,6 @@ import { saveAs } from "file-saver"; import { cloneDeep } from "lodash-es"; import { FieldValues, Path, PathValue, UseFormSetValue } from "react-hook-form"; import { flatten } from "flat"; - import type ClientRepresentation from "@keycloak/keycloak-admin-client/lib/defs/clientRepresentation"; import type { ProviderRepresentation } from "@keycloak/keycloak-admin-client/lib/defs/serverInfoRepesentation"; import type { IFormatter, IFormatterValueType } from "@patternfly/react-table"; diff --git a/js/apps/admin-ui/src/utils/generateEncodedPath.ts b/js/apps/admin-ui/src/utils/generateEncodedPath.ts new file mode 100644 index 000000000000..98e1ce27d6d0 --- /dev/null +++ b/js/apps/admin-ui/src/utils/generateEncodedPath.ts @@ -0,0 +1,17 @@ +import { generatePath } from "react-router-dom"; + +export type PathParam = { [key: string]: string }; + +export function generateEncodedPath( + originalPath: Path, + params: PathParam, +): string { + const encodedParams: PathParam = {}; + + Object.entries(params).forEach( + ([k, v]) => (encodedParams[k] = encodeURIComponent(v)), + ); + + //TODO: Fix type once https://github.com/remix-run/react-router/pull/10719 is merged. + return generatePath(originalPath, encodedParams as any); +} From a3c29b88804547a5f85d60d26b99e23c1f2d0777 Mon Sep 17 00:00:00 2001 From: Alexander Schwartz Date: Tue, 17 Oct 2023 10:41:44 +0200 Subject: [PATCH 12/27] Tidy up documentation around Windows/Linux usage (#23859) Closes #23856 --- docs/documentation/server_admin/topics/vault.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/documentation/server_admin/topics/vault.adoc b/docs/documentation/server_admin/topics/vault.adoc index 2a0b0fccc440..6206d6f2081d 100644 --- a/docs/documentation/server_admin/topics/vault.adoc +++ b/docs/documentation/server_admin/topics/vault.adoc @@ -32,7 +32,7 @@ All built-in providers support the configuration of key resolvers. A key resolve [source,bash] ---- -kc.[sh.bat] start --spi-vault-file-key-resolvers=REALM_UNDERSCORE_KEY,KEY_ONLY +kc.[sh|bat] start --spi-vault-file-key-resolvers=REALM_UNDERSCORE_KEY,KEY_ONLY ---- The resolvers run in the same order you declare them in the configuration. For each resolver, {project_name} uses the last entry name the resolver produces, which combines the realm with the vault key to search for the vault's secret. If {project_name} finds a secret, it returns the secret. If not, {project_name} uses the next resolver. This search continues until {project_name} finds a non-empty secret or runs out of resolvers. If {project_name} finds no secret, {project_name} returns an empty secret. From 103cea8f855300d5d718a43c3d17911ad914f6cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 10:46:14 +0200 Subject: [PATCH 13/27] Bump rollup from 4.0.2 to 4.1.4 in /js (#24041) Bumps [rollup](https://github.com/rollup/rollup) from 4.0.2 to 4.1.4. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.0.2...v4.1.4) --- updated-dependencies: - dependency-name: rollup dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- js/libs/keycloak-js/package.json | 2 +- js/pnpm-lock.yaml | 138 +++++++++++++++---------------- 2 files changed, 70 insertions(+), 70 deletions(-) diff --git a/js/libs/keycloak-js/package.json b/js/libs/keycloak-js/package.json index be527ada4e67..71282f1c5ce1 100644 --- a/js/libs/keycloak-js/package.json +++ b/js/libs/keycloak-js/package.json @@ -48,7 +48,7 @@ "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.5", "es6-promise": "^4.2.8", - "rollup": "^4.0.2" + "rollup": "^4.1.4" }, "dependencies": { "base64-js": "^1.5.1", diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index 506e3bc85b21..de7860f624e2 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -365,25 +365,25 @@ importers: devDependencies: '@rollup/plugin-commonjs': specifier: ^25.0.5 - version: 25.0.5(rollup@4.0.2) + version: 25.0.5(rollup@4.1.4) '@rollup/plugin-inject': specifier: ^5.0.4 - version: 5.0.4(rollup@4.0.2) + version: 5.0.4(rollup@4.1.4) '@rollup/plugin-node-resolve': specifier: ^15.2.3 - version: 15.2.3(rollup@4.0.2) + version: 15.2.3(rollup@4.1.4) '@rollup/plugin-terser': specifier: ^0.4.4 - version: 0.4.4(rollup@4.0.2) + version: 0.4.4(rollup@4.1.4) '@rollup/plugin-typescript': specifier: ^11.1.5 - version: 11.1.5(rollup@4.0.2)(tslib@2.6.2)(typescript@5.2.2) + version: 11.1.5(rollup@4.1.4)(tslib@2.6.2)(typescript@5.2.2) es6-promise: specifier: ^4.2.8 version: 4.2.8 rollup: - specifier: ^4.0.2 - version: 4.0.2 + specifier: ^4.1.4 + version: 4.1.4 libs/keycloak-masthead: dependencies: @@ -414,7 +414,7 @@ importers: version: 3.4.0(vite@4.4.10) rollup-plugin-peer-deps-external: specifier: ^2.2.4 - version: 2.2.4(rollup@4.0.2) + version: 2.2.4(rollup@4.1.4) vite: specifier: ^4.4.10 version: 4.4.10(@types/node@20.8.5)(lightningcss@1.22.0) @@ -423,7 +423,7 @@ importers: version: 0.6.2(eslint@8.51.0)(typescript@5.2.2)(vite@4.4.10) vite-plugin-dts: specifier: ^3.6.0 - version: 3.6.0(@types/node@20.8.5)(rollup@4.0.2)(typescript@5.2.2)(vite@4.4.10) + version: 3.6.0(@types/node@20.8.5)(rollup@4.1.4)(typescript@5.2.2)(vite@4.4.10) libs/ui-shared: dependencies: @@ -454,7 +454,7 @@ importers: version: 3.4.0(vite@4.4.10) rollup-plugin-peer-deps-external: specifier: ^2.2.4 - version: 2.2.4(rollup@4.0.2) + version: 2.2.4(rollup@4.1.4) vite: specifier: ^4.4.10 version: 4.4.10(@types/node@20.8.5)(lightningcss@1.22.0) @@ -463,7 +463,7 @@ importers: version: 0.6.2(eslint@8.51.0)(typescript@5.2.2)(vite@4.4.10) vite-plugin-dts: specifier: ^3.6.0 - version: 3.6.0(@types/node@20.8.5)(rollup@4.0.2)(typescript@5.2.2)(vite@4.4.10) + version: 3.6.0(@types/node@20.8.5)(rollup@4.1.4)(typescript@5.2.2)(vite@4.4.10) vitest: specifier: ^0.34.6 version: 0.34.6 @@ -1283,7 +1283,7 @@ packages: engines: {node: '>=14.0.0'} dev: false - /@rollup/plugin-commonjs@25.0.5(rollup@4.0.2): + /@rollup/plugin-commonjs@25.0.5(rollup@4.1.4): resolution: {integrity: sha512-xY8r/A9oisSeSuLCTfhssyDjo9Vp/eDiRLXkg1MXCcEEgEjPmLU+ZyDB20OOD0NlyDa/8SGbK5uIggF5XTx77w==} engines: {node: '>=14.0.0'} peerDependencies: @@ -1292,16 +1292,16 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.4(rollup@4.0.2) + '@rollup/pluginutils': 5.0.4(rollup@4.1.4) commondir: 1.0.1 estree-walker: 2.0.2 glob: 8.1.0 is-reference: 1.2.1 magic-string: 0.27.0 - rollup: 4.0.2 + rollup: 4.1.4 dev: true - /@rollup/plugin-inject@5.0.4(rollup@4.0.2): + /@rollup/plugin-inject@5.0.4(rollup@4.1.4): resolution: {integrity: sha512-dM93Nyqp9Ah14jvThFFA30ifjB8cDKk3Bx69M1nIIHGytXug3VrTv5HEuYBzevu45HvZ0ho7t+40bmScmkzZhg==} engines: {node: '>=14.0.0'} peerDependencies: @@ -1310,13 +1310,13 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.4(rollup@4.0.2) + '@rollup/pluginutils': 5.0.4(rollup@4.1.4) estree-walker: 2.0.2 magic-string: 0.27.0 - rollup: 4.0.2 + rollup: 4.1.4 dev: true - /@rollup/plugin-node-resolve@15.2.3(rollup@4.0.2): + /@rollup/plugin-node-resolve@15.2.3(rollup@4.1.4): resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} engines: {node: '>=14.0.0'} peerDependencies: @@ -1325,16 +1325,16 @@ packages: rollup: optional: true dependencies: - '@rollup/pluginutils': 5.0.4(rollup@4.0.2) + '@rollup/pluginutils': 5.0.4(rollup@4.1.4) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-builtin-module: 3.2.1 is-module: 1.0.0 resolve: 1.22.4 - rollup: 4.0.2 + rollup: 4.1.4 dev: true - /@rollup/plugin-terser@0.4.4(rollup@4.0.2): + /@rollup/plugin-terser@0.4.4(rollup@4.1.4): resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} engines: {node: '>=14.0.0'} peerDependencies: @@ -1343,13 +1343,13 @@ packages: rollup: optional: true dependencies: - rollup: 4.0.2 + rollup: 4.1.4 serialize-javascript: 6.0.1 smob: 1.4.0 terser: 5.19.2 dev: true - /@rollup/plugin-typescript@11.1.5(rollup@4.0.2)(tslib@2.6.2)(typescript@5.2.2): + /@rollup/plugin-typescript@11.1.5(rollup@4.1.4)(tslib@2.6.2)(typescript@5.2.2): resolution: {integrity: sha512-rnMHrGBB0IUEv69Q8/JGRD/n4/n6b3nfpufUu26axhUcboUzv/twfZU8fIBbTOphRAe0v8EyxzeDpKXqGHfyDA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -1362,14 +1362,14 @@ packages: tslib: optional: true dependencies: - '@rollup/pluginutils': 5.0.4(rollup@4.0.2) + '@rollup/pluginutils': 5.0.4(rollup@4.1.4) resolve: 1.22.4 - rollup: 4.0.2 + rollup: 4.1.4 tslib: 2.6.2 typescript: 5.2.2 dev: true - /@rollup/pluginutils@5.0.4(rollup@4.0.2): + /@rollup/pluginutils@5.0.4(rollup@4.1.4): resolution: {integrity: sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==} engines: {node: '>=14.0.0'} peerDependencies: @@ -1381,99 +1381,99 @@ packages: '@types/estree': 1.0.1 estree-walker: 2.0.2 picomatch: 2.3.1 - rollup: 4.0.2 + rollup: 4.1.4 dev: true - /@rollup/rollup-android-arm-eabi@4.0.2: - resolution: {integrity: sha512-xDvk1pT4vaPU2BOLy0MqHMdYZyntqpaBf8RhBiezlqG9OjY8F50TyctHo8znigYKd+QCFhCmlmXHOL/LoaOl3w==} + /@rollup/rollup-android-arm-eabi@4.1.4: + resolution: {integrity: sha512-WlzkuFvpKl6CLFdc3V6ESPt7gq5Vrimd2Yv9IzKXdOpgbH4cdDSS1JLiACX8toygihtH5OlxyQzhXOph7Ovlpw==} cpu: [arm] os: [android] requiresBuild: true dev: true optional: true - /@rollup/rollup-android-arm64@4.0.2: - resolution: {integrity: sha512-lqCglytY3E6raze27DD9VQJWohbwCxzqs9aSHcj5X/8hJpzZfNdbsr4Ja9Hqp6iPyF53+5PtPx0pKRlkSvlHZg==} + /@rollup/rollup-android-arm64@4.1.4: + resolution: {integrity: sha512-D1e+ABe56T9Pq2fD+R3ybe1ylCDzu3tY4Qm2Mj24R9wXNCq35+JbFbOpc2yrroO2/tGhTobmEl2Bm5xfE/n8RA==} cpu: [arm64] os: [android] requiresBuild: true dev: true optional: true - /@rollup/rollup-darwin-arm64@4.0.2: - resolution: {integrity: sha512-nkBKItS6E6CCzvRwgiKad+j+1ibmL7SIInj7oqMWmdkCjiSX6VeVZw2mLlRKIUL+JjsBgpATTfo7BiAXc1v0jA==} + /@rollup/rollup-darwin-arm64@4.1.4: + resolution: {integrity: sha512-7vTYrgEiOrjxnjsgdPB+4i7EMxbVp7XXtS+50GJYj695xYTTEMn3HZVEvgtwjOUkAP/Q4HDejm4fIAjLeAfhtg==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /@rollup/rollup-darwin-x64@4.0.2: - resolution: {integrity: sha512-vX2C8xvWPIbpEgQht95+dY6BReKAvtDgPDGi0XN0kWJKkm4WdNmq5dnwscv/zxvi+n6jUTBhs6GtpkkWT4q8Gg==} + /@rollup/rollup-darwin-x64@4.1.4: + resolution: {integrity: sha512-eGJVZScKSLZkYjhTAESCtbyTBq9SXeW9+TX36ki5gVhDqJtnQ5k0f9F44jNK5RhAMgIj0Ht9+n6HAgH0gUUyWQ==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-arm-gnueabihf@4.0.2: - resolution: {integrity: sha512-DVFIfcHOjgmeHOAqji4xNz2wczt1Bmzy9MwBZKBa83SjBVO/i38VHDR+9ixo8QpBOiEagmNw12DucG+v55tCrg==} + /@rollup/rollup-linux-arm-gnueabihf@4.1.4: + resolution: {integrity: sha512-HnigYSEg2hOdX1meROecbk++z1nVJDpEofw9V2oWKqOWzTJlJf1UXVbDE6Hg30CapJxZu5ga4fdAQc/gODDkKg==} cpu: [arm] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-arm64-gnu@4.0.2: - resolution: {integrity: sha512-GCK/a9ItUxPI0V5hQEJjH4JtOJO90GF2Hja7TO+EZ8rmkGvEi8/ZDMhXmcuDpQT7/PWrTT9RvnG8snMd5SrhBQ==} + /@rollup/rollup-linux-arm64-gnu@4.1.4: + resolution: {integrity: sha512-TzJ+N2EoTLWkaClV2CUhBlj6ljXofaYzF/R9HXqQ3JCMnCHQZmQnbnZllw7yTDp0OG5whP4gIPozR4QiX+00MQ==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-arm64-musl@4.0.2: - resolution: {integrity: sha512-cLuBp7rOjIB1R2j/VazjCmHC7liWUur2e9mFflLJBAWCkrZ+X0+QwHLvOQakIwDymungzAKv6W9kHZnTp/Mqrg==} + /@rollup/rollup-linux-arm64-musl@4.1.4: + resolution: {integrity: sha512-aVPmNMdp6Dlo2tWkAduAD/5TL/NT5uor290YvjvFvCv0Q3L7tVdlD8MOGDL+oRSw5XKXKAsDzHhUOPUNPRHVTQ==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-x64-gnu@4.0.2: - resolution: {integrity: sha512-Zqw4iVnJr2naoyQus0yLy7sLtisCQcpdMKUCeXPBjkJtpiflRime/TMojbnl8O3oxUAj92mxr+t7im/RbgA20w==} + /@rollup/rollup-linux-x64-gnu@4.1.4: + resolution: {integrity: sha512-77Fb79ayiDad0grvVsz4/OB55wJRyw9Ao+GdOBA9XywtHpuq5iRbVyHToGxWquYWlEf6WHFQQnFEttsAzboyKg==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-x64-musl@4.0.2: - resolution: {integrity: sha512-jJRU9TyUD/iMqjf8aLAp7XiN3pIj5v6Qcu+cdzBfVTKDD0Fvua4oUoK8eVJ9ZuKBEQKt3WdlcwJXFkpmMLk6kg==} + /@rollup/rollup-linux-x64-musl@4.1.4: + resolution: {integrity: sha512-/t6C6niEQTqmQTVTD9TDwUzxG91Mlk69/v0qodIPUnjjB3wR4UA3klg+orR2SU3Ux2Cgf2pWPL9utK80/1ek8g==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-win32-arm64-msvc@4.0.2: - resolution: {integrity: sha512-ZkS2NixCxHKC4zbOnw64ztEGGDVIYP6nKkGBfOAxEPW71Sji9v8z3yaHNuae/JHPwXA+14oDefnOuVfxl59SmQ==} + /@rollup/rollup-win32-arm64-msvc@4.1.4: + resolution: {integrity: sha512-ZY5BHHrOPkMbCuGWFNpJH0t18D2LU6GMYKGaqaWTQ3CQOL57Fem4zE941/Ek5pIsVt70HyDXssVEFQXlITI5Gg==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /@rollup/rollup-win32-ia32-msvc@4.0.2: - resolution: {integrity: sha512-3SKjj+tvnZ0oZq2BKB+fI+DqYI83VrRzk7eed8tJkxeZ4zxJZcLSE8YDQLYGq1tZAnAX+H076RHHB4gTZXsQzw==} + /@rollup/rollup-win32-ia32-msvc@4.1.4: + resolution: {integrity: sha512-XG2mcRfFrJvYyYaQmvCIvgfkaGinfXrpkBuIbJrTl9SaIQ8HumheWTIwkNz2mktCKwZfXHQNpO7RgXLIGQ7HXA==} cpu: [ia32] os: [win32] requiresBuild: true dev: true optional: true - /@rollup/rollup-win32-x64-msvc@4.0.2: - resolution: {integrity: sha512-MBdJIOxRauKkry7t2q+rTHa3aWjVez2eioWg+etRVS3dE4tChhmt5oqZYr48R6bPmcwEhxQr96gVRfeQrLbqng==} + /@rollup/rollup-win32-x64-msvc@4.1.4: + resolution: {integrity: sha512-ANFqWYPwkhIqPmXw8vm0GpBEHiPpqcm99jiiAp71DbCSqLDhrtr019C5vhD0Bw4My+LmMvciZq6IsWHqQpl2ZQ==} cpu: [x64] os: [win32] requiresBuild: true @@ -6179,12 +6179,12 @@ packages: glob: 7.2.3 dev: true - /rollup-plugin-peer-deps-external@2.2.4(rollup@4.0.2): + /rollup-plugin-peer-deps-external@2.2.4(rollup@4.1.4): resolution: {integrity: sha512-AWdukIM1+k5JDdAqV/Cxd+nejvno2FVLVeZ74NKggm3Q5s9cbbcOgUPGdbxPi4BXu7xGaZ8HG12F+thImYu/0g==} peerDependencies: rollup: '*' dependencies: - rollup: 4.0.2 + rollup: 4.1.4 dev: true /rollup@3.29.4: @@ -6195,23 +6195,23 @@ packages: fsevents: 2.3.3 dev: true - /rollup@4.0.2: - resolution: {integrity: sha512-MCScu4usMPCeVFaiLcgMDaBQeYi1z6vpWxz0r0hq0Hv77Y2YuOTZldkuNJ54BdYBH3e+nkrk6j0Rre/NLDBYzg==} + /rollup@4.1.4: + resolution: {integrity: sha512-U8Yk1lQRKqCkDBip/pMYT+IKaN7b7UesK3fLSTuHBoBJacCE+oBqo/dfG/gkUdQNNB2OBmRP98cn2C2bkYZkyw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.0.2 - '@rollup/rollup-android-arm64': 4.0.2 - '@rollup/rollup-darwin-arm64': 4.0.2 - '@rollup/rollup-darwin-x64': 4.0.2 - '@rollup/rollup-linux-arm-gnueabihf': 4.0.2 - '@rollup/rollup-linux-arm64-gnu': 4.0.2 - '@rollup/rollup-linux-arm64-musl': 4.0.2 - '@rollup/rollup-linux-x64-gnu': 4.0.2 - '@rollup/rollup-linux-x64-musl': 4.0.2 - '@rollup/rollup-win32-arm64-msvc': 4.0.2 - '@rollup/rollup-win32-ia32-msvc': 4.0.2 - '@rollup/rollup-win32-x64-msvc': 4.0.2 + '@rollup/rollup-android-arm-eabi': 4.1.4 + '@rollup/rollup-android-arm64': 4.1.4 + '@rollup/rollup-darwin-arm64': 4.1.4 + '@rollup/rollup-darwin-x64': 4.1.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.1.4 + '@rollup/rollup-linux-arm64-gnu': 4.1.4 + '@rollup/rollup-linux-arm64-musl': 4.1.4 + '@rollup/rollup-linux-x64-gnu': 4.1.4 + '@rollup/rollup-linux-x64-musl': 4.1.4 + '@rollup/rollup-win32-arm64-msvc': 4.1.4 + '@rollup/rollup-win32-ia32-msvc': 4.1.4 + '@rollup/rollup-win32-x64-msvc': 4.1.4 fsevents: 2.3.3 dev: true @@ -7072,7 +7072,7 @@ packages: vscode-uri: 3.0.7 dev: true - /vite-plugin-dts@3.6.0(@types/node@20.8.5)(rollup@4.0.2)(typescript@5.2.2)(vite@4.4.10): + /vite-plugin-dts@3.6.0(@types/node@20.8.5)(rollup@4.1.4)(typescript@5.2.2)(vite@4.4.10): resolution: {integrity: sha512-doxhDRFJCZD2sGjIp4V800nm8Y19GvmwckjG5vYPuiqJ7OBjc9NlW1Vp9Gkyh2aXlUs1jTDRH/lxWfcsPLOQHg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -7083,7 +7083,7 @@ packages: optional: true dependencies: '@microsoft/api-extractor': 7.36.4(@types/node@20.8.5) - '@rollup/pluginutils': 5.0.4(rollup@4.0.2) + '@rollup/pluginutils': 5.0.4(rollup@4.1.4) '@vue/language-core': 1.8.8(typescript@5.2.2) debug: 4.3.4(supports-color@8.1.1) kolorist: 1.8.0 From 11b7362c6884e467115a8fa0fd00aa0bf19ea769 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 10:46:47 +0200 Subject: [PATCH 14/27] Bump reactflow from 11.9.3 to 11.9.4 in /js (#24040) Bumps [reactflow](https://github.com/wbkd/react-flow/tree/HEAD/packages/reactflow) from 11.9.3 to 11.9.4. - [Release notes](https://github.com/wbkd/react-flow/releases) - [Changelog](https://github.com/wbkd/react-flow/blob/main/packages/reactflow/CHANGELOG.md) - [Commits](https://github.com/wbkd/react-flow/commits/reactflow@11.9.4/packages/reactflow) --- updated-dependencies: - dependency-name: reactflow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- js/apps/admin-ui/package.json | 2 +- js/pnpm-lock.yaml | 56 +++++++++++++++++------------------ 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/js/apps/admin-ui/package.json b/js/apps/admin-ui/package.json index d028574e8697..3f7232121283 100644 --- a/js/apps/admin-ui/package.json +++ b/js/apps/admin-ui/package.json @@ -84,7 +84,7 @@ "react-hook-form": "^7.47.0", "react-i18next": "^13.2.2", "react-router-dom": "^6.15.0", - "reactflow": "^11.9.3", + "reactflow": "^11.9.4", "ui-shared": "workspace:*", "use-react-router-breadcrumbs": "^4.0.1" }, diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index de7860f624e2..580963a6e449 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -217,8 +217,8 @@ importers: specifier: ^6.15.0 version: 6.15.0(react-dom@18.2.0)(react@18.2.0) reactflow: - specifier: ^11.9.3 - version: 11.9.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) + specifier: ^11.9.4 + version: 11.9.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) ui-shared: specifier: workspace:* version: link:../../libs/ui-shared @@ -1170,13 +1170,13 @@ packages: playwright: 1.38.1 dev: true - /@reactflow/background@11.3.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-m3MR25ufbrDkZI2Yi7pHX5uewVpiaaVM5px35pk2v3qdG68adqHOgJjncUOpGiJpc3rDwt4mqmW1V7RjBqNv6Q==} + /@reactflow/background@11.3.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-bgwvqWxF09chwmdkyClpYEMaewBspdwjgLbbFlLf4SpWPFMYyuvCBQrcISsvy/EDEWO9i3Uj9ktgGAhvtSQsmA==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/core': 11.9.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.9.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) classcat: 5.0.4 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -1186,13 +1186,13 @@ packages: - immer dev: false - /@reactflow/controls@11.2.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-UTsfHE+PhgWrCZN4GUOTRU/3l8dGSyR2KslmgqV7mVNsh6EuS2cxboRczjpcIc8lF0EH+7QxLGeXSH42GWCcOQ==} + /@reactflow/controls@11.2.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-x6e5p9iHjC6gd+4SoZ3DOOp0F1MefGKQ8hT6yPVdqxfo1+rV2WhrWvrX/MCoEu12Dp7457LdLfa0giy3aho8tQ==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/core': 11.9.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.9.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) classcat: 5.0.4 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -1202,8 +1202,8 @@ packages: - immer dev: false - /@reactflow/core@11.9.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-45o8X1sjF48wSWALHybbLoWF6yo9SARgJpMKm96J8ZL8mrNhqSjll77sLRJg6zQ+VKdDwotEN30jp5eY6i28tw==} + /@reactflow/core@11.9.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Ko7nKPOYalwDTTbRHi2+QXDiidSAcpUzGN3G+0B+QysLZkcaPCkpkMjjHiDC4c/Z1BJBzs1FRJg/T6BXaBnYkg==} peerDependencies: react: '>=17' react-dom: '>=17' @@ -1224,13 +1224,13 @@ packages: - immer dev: false - /@reactflow/minimap@11.7.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-u620uYwjmA5tJ/4p+F/0kyjNojvV0axTMSw87d/CCDij96m+2/drwqMW+BE8XHEqjG0c1HyplrkXQ3WhGu6ZaA==} + /@reactflow/minimap@11.7.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Jo1R+uDey9IV7O2s3m0gK2+cZpg9M8hq2EZJb3NGfOSzMAPhj3mby0fNJIgTzycreuht0TpA51c2YfjGI3YIOw==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/core': 11.9.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.9.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) '@types/d3-selection': 3.0.6 '@types/d3-zoom': 3.0.4 classcat: 5.0.4 @@ -1244,13 +1244,13 @@ packages: - immer dev: false - /@reactflow/node-resizer@2.2.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-x1TXN4YZhBI1LxNegVsE51emUg1rf4rBgvNL8Tzj0xsKkD/av4DOzRizQ3xAGgk0joPrsOTiGiP511m/PWjsew==} + /@reactflow/node-resizer@2.2.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-+p271/hAsM5M1+RQTWW/02pbNkCHeGXwxGimIlL1tMIagyuko0NX2vOz2B8jxJnPKlF09Wj18BcXBNUm3nDcSg==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/core': 11.9.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.9.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) classcat: 5.0.4 d3-drag: 3.0.0 d3-selection: 3.0.0 @@ -1262,13 +1262,13 @@ packages: - immer dev: false - /@reactflow/node-toolbar@1.3.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-juNFBLZgC+KOYpVaQFTkSQTDf4hYK7WAagiQQ4Dw0IUcLaMY3TA31OLP6X6gMG73YGKFmkgrDwi0ZDB0jpMqdA==} + /@reactflow/node-toolbar@1.3.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-TfcmpXHRBb2mUfzKGjburiU6FWqRME9pPFs1OwIC1z5e9BjupQhNDEKEk8XHi7PKL/mAiDfwuGXaM1BVVFuPqw==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/core': 11.9.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.9.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) classcat: 5.0.4 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -6023,18 +6023,18 @@ packages: dependencies: loose-envify: 1.4.0 - /reactflow@11.9.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-GiIo20Vgy1U4h1NlLyQChWYgsl2OQkEgKHjokyQsdmm1nidywTr0n94O6w97ixLljKzJynTMjDdWP0p8xkq6NQ==} + /reactflow@11.9.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-IHAKBkJngNvU9y1vZ5Nw9rvA3Z+zc9geTgQQIi9qq9Y9knGLlDDr9KfsjbFMew9AycAAgVg8TvBEakF4IT5lqg==} peerDependencies: react: '>=17' react-dom: '>=17' dependencies: - '@reactflow/background': 11.3.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) - '@reactflow/controls': 11.2.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) - '@reactflow/core': 11.9.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) - '@reactflow/minimap': 11.7.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) - '@reactflow/node-resizer': 2.2.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) - '@reactflow/node-toolbar': 1.3.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/background': 11.3.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/controls': 11.2.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/core': 11.9.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/minimap': 11.7.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/node-resizer': 2.2.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) + '@reactflow/node-toolbar': 1.3.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) transitivePeerDependencies: @@ -7676,7 +7676,7 @@ packages: react-hook-form: 7.47.0(react@18.2.0) react-i18next: 13.2.2(i18next@23.5.1)(react-dom@18.2.0)(react@18.2.0) react-router-dom: 6.15.0(react-dom@18.2.0)(react@18.2.0) - reactflow: 11.9.3(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) + reactflow: 11.9.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) ui-shared: link:libs/ui-shared use-react-router-breadcrumbs: 4.0.1(react-router-dom@6.15.0)(react@18.2.0) transitivePeerDependencies: From 631bf091761979558f4272b9092bd56c600fc607 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 10:47:16 +0200 Subject: [PATCH 15/27] Bump @typescript-eslint/eslint-plugin from 6.7.4 to 6.8.0 in /js (#24038) Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.7.4 to 6.8.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.8.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- js/package.json | 2 +- js/pnpm-lock.yaml | 86 +++++++++++++++++++++++------------------------ 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/js/package.json b/js/package.json index e6318095df49..f2540e3c44ec 100644 --- a/js/package.json +++ b/js/package.json @@ -5,7 +5,7 @@ }, "devDependencies": { "@types/node": "^20.8.5", - "@typescript-eslint/eslint-plugin": "^6.7.4", + "@typescript-eslint/eslint-plugin": "^6.8.0", "@typescript-eslint/parser": "^6.7.5", "eslint": "^8.51.0", "eslint-config-prettier": "^9.0.0", diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index 580963a6e449..a47a52eaf536 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: ^20.8.5 version: 20.8.5 '@typescript-eslint/eslint-plugin': - specifier: ^6.7.4 - version: 6.7.4(@typescript-eslint/parser@6.7.5)(eslint@8.51.0)(typescript@5.2.2) + specifier: ^6.8.0 + version: 6.8.0(@typescript-eslint/parser@6.7.5)(eslint@8.51.0)(typescript@5.2.2) '@typescript-eslint/parser': specifier: ^6.7.5 version: 6.7.5(eslint@8.51.0)(typescript@5.2.2) @@ -2049,8 +2049,8 @@ packages: dev: true optional: true - /@typescript-eslint/eslint-plugin@6.7.4(@typescript-eslint/parser@6.7.5)(eslint@8.51.0)(typescript@5.2.2): - resolution: {integrity: sha512-DAbgDXwtX+pDkAHwiGhqP3zWUGpW49B7eqmgpPtg+BKJXwdct79ut9+ifqOFPJGClGKSHXn2PTBatCnldJRUoA==} + /@typescript-eslint/eslint-plugin@6.8.0(@typescript-eslint/parser@6.7.5)(eslint@8.51.0)(typescript@5.2.2): + resolution: {integrity: sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -2062,10 +2062,10 @@ packages: dependencies: '@eslint-community/regexpp': 4.8.0 '@typescript-eslint/parser': 6.7.5(eslint@8.51.0)(typescript@5.2.2) - '@typescript-eslint/scope-manager': 6.7.4 - '@typescript-eslint/type-utils': 6.7.4(eslint@8.51.0)(typescript@5.2.2) - '@typescript-eslint/utils': 6.7.4(eslint@8.51.0)(typescript@5.2.2) - '@typescript-eslint/visitor-keys': 6.7.4 + '@typescript-eslint/scope-manager': 6.8.0 + '@typescript-eslint/type-utils': 6.8.0(eslint@8.51.0)(typescript@5.2.2) + '@typescript-eslint/utils': 6.8.0(eslint@8.51.0)(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.8.0 debug: 4.3.4(supports-color@8.1.1) eslint: 8.51.0 graphemer: 1.4.0 @@ -2099,14 +2099,6 @@ packages: - supports-color dev: true - /@typescript-eslint/scope-manager@6.7.4: - resolution: {integrity: sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==} - engines: {node: ^16.0.0 || >=18.0.0} - dependencies: - '@typescript-eslint/types': 6.7.4 - '@typescript-eslint/visitor-keys': 6.7.4 - dev: true - /@typescript-eslint/scope-manager@6.7.5: resolution: {integrity: sha512-GAlk3eQIwWOJeb9F7MKQ6Jbah/vx1zETSDw8likab/eFcqkjSD7BI75SDAeC5N2L0MmConMoPvTsmkrg71+B1A==} engines: {node: ^16.0.0 || >=18.0.0} @@ -2115,8 +2107,16 @@ packages: '@typescript-eslint/visitor-keys': 6.7.5 dev: true - /@typescript-eslint/type-utils@6.7.4(eslint@8.51.0)(typescript@5.2.2): - resolution: {integrity: sha512-n+g3zi1QzpcAdHFP9KQF+rEFxMb2KxtnJGID3teA/nxKHOVi3ylKovaqEzGBbVY2pBttU6z85gp0D00ufLzViQ==} + /@typescript-eslint/scope-manager@6.8.0: + resolution: {integrity: sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.8.0 + '@typescript-eslint/visitor-keys': 6.8.0 + dev: true + + /@typescript-eslint/type-utils@6.8.0(eslint@8.51.0)(typescript@5.2.2): + resolution: {integrity: sha512-RYOJdlkTJIXW7GSldUIHqc/Hkto8E+fZN96dMIFhuTJcQwdRoGN2rEWA8U6oXbLo0qufH7NPElUb+MceHtz54g==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -2125,8 +2125,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.7.4(typescript@5.2.2) - '@typescript-eslint/utils': 6.7.4(eslint@8.51.0)(typescript@5.2.2) + '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.2.2) + '@typescript-eslint/utils': 6.8.0(eslint@8.51.0)(typescript@5.2.2) debug: 4.3.4(supports-color@8.1.1) eslint: 8.51.0 ts-api-utils: 1.0.2(typescript@5.2.2) @@ -2135,18 +2135,18 @@ packages: - supports-color dev: true - /@typescript-eslint/types@6.7.4: - resolution: {integrity: sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==} + /@typescript-eslint/types@6.7.5: + resolution: {integrity: sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ==} engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/types@6.7.5: - resolution: {integrity: sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ==} + /@typescript-eslint/types@6.8.0: + resolution: {integrity: sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==} engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@6.7.4(typescript@5.2.2): - resolution: {integrity: sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==} + /@typescript-eslint/typescript-estree@6.7.5(typescript@5.2.2): + resolution: {integrity: sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -2154,8 +2154,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.7.4 - '@typescript-eslint/visitor-keys': 6.7.4 + '@typescript-eslint/types': 6.7.5 + '@typescript-eslint/visitor-keys': 6.7.5 debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 @@ -2166,8 +2166,8 @@ packages: - supports-color dev: true - /@typescript-eslint/typescript-estree@6.7.5(typescript@5.2.2): - resolution: {integrity: sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg==} + /@typescript-eslint/typescript-estree@6.8.0(typescript@5.2.2): + resolution: {integrity: sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -2175,8 +2175,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.7.5 - '@typescript-eslint/visitor-keys': 6.7.5 + '@typescript-eslint/types': 6.8.0 + '@typescript-eslint/visitor-keys': 6.8.0 debug: 4.3.4(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 @@ -2187,8 +2187,8 @@ packages: - supports-color dev: true - /@typescript-eslint/utils@6.7.4(eslint@8.51.0)(typescript@5.2.2): - resolution: {integrity: sha512-PRQAs+HUn85Qdk+khAxsVV+oULy3VkbH3hQ8hxLRJXWBEd7iI+GbQxH5SEUSH7kbEoTp6oT1bOwyga24ELALTA==} + /@typescript-eslint/utils@6.8.0(eslint@8.51.0)(typescript@5.2.2): + resolution: {integrity: sha512-dKs1itdE2qFG4jr0dlYLQVppqTE+Itt7GmIf/vX6CSvsW+3ov8PbWauVKyyfNngokhIO9sKZeRGCUo1+N7U98Q==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -2196,9 +2196,9 @@ packages: '@eslint-community/eslint-utils': 4.4.0(eslint@8.51.0) '@types/json-schema': 7.0.12 '@types/semver': 7.5.1 - '@typescript-eslint/scope-manager': 6.7.4 - '@typescript-eslint/types': 6.7.4 - '@typescript-eslint/typescript-estree': 6.7.4(typescript@5.2.2) + '@typescript-eslint/scope-manager': 6.8.0 + '@typescript-eslint/types': 6.8.0 + '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.2.2) eslint: 8.51.0 semver: 7.5.4 transitivePeerDependencies: @@ -2206,19 +2206,19 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys@6.7.4: - resolution: {integrity: sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==} + /@typescript-eslint/visitor-keys@6.7.5: + resolution: {integrity: sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.7.4 + '@typescript-eslint/types': 6.7.5 eslint-visitor-keys: 3.4.3 dev: true - /@typescript-eslint/visitor-keys@6.7.5: - resolution: {integrity: sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg==} + /@typescript-eslint/visitor-keys@6.8.0: + resolution: {integrity: sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.7.5 + '@typescript-eslint/types': 6.8.0 eslint-visitor-keys: 3.4.3 dev: true From 108e866907207e01722b6c4b7a11384997df859b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 11:27:18 +0200 Subject: [PATCH 16/27] Bump @rollup/plugin-commonjs from 25.0.5 to 25.0.7 in /js (#23999) Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 25.0.5 to 25.0.7. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/commonjs-v25.0.7/packages/commonjs) --- updated-dependencies: - dependency-name: "@rollup/plugin-commonjs" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- js/libs/keycloak-js/package.json | 2 +- js/pnpm-lock.yaml | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/js/libs/keycloak-js/package.json b/js/libs/keycloak-js/package.json index 71282f1c5ce1..786ea2687e58 100644 --- a/js/libs/keycloak-js/package.json +++ b/js/libs/keycloak-js/package.json @@ -42,7 +42,7 @@ "authentication" ], "devDependencies": { - "@rollup/plugin-commonjs": "^25.0.5", + "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-inject": "^5.0.4", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-terser": "^0.4.4", diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index a47a52eaf536..884fd90d0329 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -364,8 +364,8 @@ importers: version: 3.1.2 devDependencies: '@rollup/plugin-commonjs': - specifier: ^25.0.5 - version: 25.0.5(rollup@4.1.4) + specifier: ^25.0.7 + version: 25.0.7(rollup@4.1.4) '@rollup/plugin-inject': specifier: ^5.0.4 version: 5.0.4(rollup@4.1.4) @@ -1283,8 +1283,8 @@ packages: engines: {node: '>=14.0.0'} dev: false - /@rollup/plugin-commonjs@25.0.5(rollup@4.1.4): - resolution: {integrity: sha512-xY8r/A9oisSeSuLCTfhssyDjo9Vp/eDiRLXkg1MXCcEEgEjPmLU+ZyDB20OOD0NlyDa/8SGbK5uIggF5XTx77w==} + /@rollup/plugin-commonjs@25.0.7(rollup@4.1.4): + resolution: {integrity: sha512-nEvcR+LRjEjsaSsc4x3XZfCCvZIaSMenZu/OiwOKGN2UhQpAYI7ru7czFvyWbErlpoGjnSX3D5Ch5FcMA3kRWQ==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^2.68.0||^3.0.0||^4.0.0 @@ -1297,7 +1297,7 @@ packages: estree-walker: 2.0.2 glob: 8.1.0 is-reference: 1.2.1 - magic-string: 0.27.0 + magic-string: 0.30.3 rollup: 4.1.4 dev: true From fab5622582bcde5e3d9585cde0835bb641321d59 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 11:27:45 +0200 Subject: [PATCH 17/27] Bump @types/node from 20.8.5 to 20.8.6 in /js (#23998) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.8.5 to 20.8.6. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- js/libs/keycloak-admin-client/package.json | 2 +- js/package.json | 2 +- js/pnpm-lock.yaml | 96 +++++++++++----------- 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/js/libs/keycloak-admin-client/package.json b/js/libs/keycloak-admin-client/package.json index 5f70b1b6c0c2..7696e03495c4 100644 --- a/js/libs/keycloak-admin-client/package.json +++ b/js/libs/keycloak-admin-client/package.json @@ -47,7 +47,7 @@ "@types/chai": "^4.3.7", "@types/lodash-es": "^4.17.9", "@types/mocha": "^10.0.2", - "@types/node": "^20.8.5", + "@types/node": "^20.8.6", "chai": "^4.3.10", "mocha": "^10.2.0", "ts-node": "^10.9.1" diff --git a/js/package.json b/js/package.json index f2540e3c44ec..e82bcf54142e 100644 --- a/js/package.json +++ b/js/package.json @@ -4,7 +4,7 @@ "prepare": "cd .. && husky install js/.husky" }, "devDependencies": { - "@types/node": "^20.8.5", + "@types/node": "^20.8.6", "@typescript-eslint/eslint-plugin": "^6.8.0", "@typescript-eslint/parser": "^6.7.5", "eslint": "^8.51.0", diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index 884fd90d0329..b70d994b2bda 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: devDependencies: '@types/node': - specifier: ^20.8.5 - version: 20.8.5 + specifier: ^20.8.6 + version: 20.8.6 '@typescript-eslint/eslint-plugin': specifier: ^6.8.0 version: 6.8.0(@typescript-eslint/parser@6.7.5)(eslint@8.51.0)(typescript@5.2.2) @@ -137,7 +137,7 @@ importers: version: 1.22.0 vite: specifier: ^4.4.10 - version: 4.4.10(@types/node@20.8.5)(lightningcss@1.22.0) + version: 4.4.10(@types/node@20.8.6)(lightningcss@1.22.0) vite-plugin-checker: specifier: ^0.6.2 version: 0.6.2(eslint@8.51.0)(typescript@5.2.2)(vite@4.4.10) @@ -276,13 +276,13 @@ importers: version: 1.22.0 ts-node: specifier: ^10.9.1 - version: 10.9.1(@types/node@20.8.5)(typescript@5.2.2) + version: 10.9.1(@types/node@20.8.6)(typescript@5.2.2) uuid: specifier: ^9.0.1 version: 9.0.1 vite: specifier: ^4.4.10 - version: 4.4.10(@types/node@20.8.5)(lightningcss@1.22.0) + version: 4.4.10(@types/node@20.8.6)(lightningcss@1.22.0) vite-plugin-checker: specifier: ^0.6.2 version: 0.6.2(eslint@8.51.0)(typescript@5.2.2)(vite@4.4.10) @@ -339,8 +339,8 @@ importers: specifier: ^10.0.2 version: 10.0.2 '@types/node': - specifier: ^20.8.5 - version: 20.8.5 + specifier: ^20.8.6 + version: 20.8.6 chai: specifier: ^4.3.10 version: 4.3.10 @@ -349,7 +349,7 @@ importers: version: 10.2.0 ts-node: specifier: ^10.9.1 - version: 10.9.1(@types/node@20.8.5)(typescript@5.2.2) + version: 10.9.1(@types/node@20.8.6)(typescript@5.2.2) libs/keycloak-js: dependencies: @@ -417,13 +417,13 @@ importers: version: 2.2.4(rollup@4.1.4) vite: specifier: ^4.4.10 - version: 4.4.10(@types/node@20.8.5)(lightningcss@1.22.0) + version: 4.4.10(@types/node@20.8.6)(lightningcss@1.22.0) vite-plugin-checker: specifier: ^0.6.2 version: 0.6.2(eslint@8.51.0)(typescript@5.2.2)(vite@4.4.10) vite-plugin-dts: specifier: ^3.6.0 - version: 3.6.0(@types/node@20.8.5)(rollup@4.1.4)(typescript@5.2.2)(vite@4.4.10) + version: 3.6.0(@types/node@20.8.6)(rollup@4.1.4)(typescript@5.2.2)(vite@4.4.10) libs/ui-shared: dependencies: @@ -457,13 +457,13 @@ importers: version: 2.2.4(rollup@4.1.4) vite: specifier: ^4.4.10 - version: 4.4.10(@types/node@20.8.5)(lightningcss@1.22.0) + version: 4.4.10(@types/node@20.8.6)(lightningcss@1.22.0) vite-plugin-checker: specifier: ^0.6.2 version: 0.6.2(eslint@8.51.0)(typescript@5.2.2)(vite@4.4.10) vite-plugin-dts: specifier: ^3.6.0 - version: 3.6.0(@types/node@20.8.5)(rollup@4.1.4)(typescript@5.2.2)(vite@4.4.10) + version: 3.6.0(@types/node@20.8.6)(rollup@4.1.4)(typescript@5.2.2)(vite@4.4.10) vitest: specifier: ^0.34.6 version: 0.34.6 @@ -895,24 +895,24 @@ packages: '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /@microsoft/api-extractor-model@7.27.6(@types/node@20.8.5): + /@microsoft/api-extractor-model@7.27.6(@types/node@20.8.6): resolution: {integrity: sha512-eiCnlayyum1f7fS2nA9pfIod5VCNR1G+Tq84V/ijDrKrOFVa598BLw145nCsGDMoFenV6ajNi2PR5WCwpAxW6Q==} dependencies: '@microsoft/tsdoc': 0.14.2 '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 3.59.7(@types/node@20.8.5) + '@rushstack/node-core-library': 3.59.7(@types/node@20.8.6) transitivePeerDependencies: - '@types/node' dev: true - /@microsoft/api-extractor@7.36.4(@types/node@20.8.5): + /@microsoft/api-extractor@7.36.4(@types/node@20.8.6): resolution: {integrity: sha512-21UECq8C/8CpHT23yiqTBQ10egKUacIpxkPyYR7hdswo/M5yTWdBvbq+77YC9uPKQJOUfOD1FImBQ1DzpsdeQQ==} hasBin: true dependencies: - '@microsoft/api-extractor-model': 7.27.6(@types/node@20.8.5) + '@microsoft/api-extractor-model': 7.27.6(@types/node@20.8.6) '@microsoft/tsdoc': 0.14.2 '@microsoft/tsdoc-config': 0.16.2 - '@rushstack/node-core-library': 3.59.7(@types/node@20.8.5) + '@rushstack/node-core-library': 3.59.7(@types/node@20.8.6) '@rushstack/rig-package': 0.4.1 '@rushstack/ts-command-line': 4.15.2 colors: 1.2.5 @@ -1480,7 +1480,7 @@ packages: dev: true optional: true - /@rushstack/node-core-library@3.59.7(@types/node@20.8.5): + /@rushstack/node-core-library@3.59.7(@types/node@20.8.6): resolution: {integrity: sha512-ln1Drq0h+Hwa1JVA65x5mlSgUrBa1uHL+V89FqVWQgXd1vVIMhrtqtWGQrhTnFHxru5ppX+FY39VWELF/FjQCw==} peerDependencies: '@types/node': '*' @@ -1488,7 +1488,7 @@ packages: '@types/node': optional: true dependencies: - '@types/node': 20.8.5 + '@types/node': 20.8.6 colors: 1.2.5 fs-extra: 7.0.1 import-lazy: 4.0.0 @@ -1950,7 +1950,7 @@ packages: /@types/gunzip-maybe@1.4.0: resolution: {integrity: sha512-dFP9GrYAR9KhsjTkWJ8q8Gsfql75YIKcg9DuQOj/IrlPzR7W+1zX+cclw1McV82UXAQ+Lpufvgk3e9bC8+HzgA==} dependencies: - '@types/node': 20.8.4 + '@types/node': 20.8.5 dev: false /@types/json-schema@7.0.12: @@ -1979,13 +1979,13 @@ packages: resolution: {integrity: sha512-2yrWpBk32tvV/JAd3HNHWuZn/VDN1P+72hWirHnvsvTGSqbANi+kSeuQR9yAHnbvaBvHDsoTdXV0Fe+iRtHLKA==} dev: true - /@types/node@20.8.4: - resolution: {integrity: sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A==} + /@types/node@20.8.5: + resolution: {integrity: sha512-SPlobFgbidfIeOYlzXiEjSYeIJiOCthv+9tSQVpvk4PAdIIc+2SmjNVzWXk9t0Y7dl73Zdf+OgXKHX9XtkqUpw==} dependencies: undici-types: 5.25.3 - /@types/node@20.8.5: - resolution: {integrity: sha512-SPlobFgbidfIeOYlzXiEjSYeIJiOCthv+9tSQVpvk4PAdIIc+2SmjNVzWXk9t0Y7dl73Zdf+OgXKHX9XtkqUpw==} + /@types/node@20.8.6: + resolution: {integrity: sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==} dependencies: undici-types: 5.25.3 @@ -2027,14 +2027,14 @@ packages: /@types/tar-fs@2.0.2: resolution: {integrity: sha512-XuZRAvdo7FbDfgQCNkc8NOdSae5XtG+of2mTSgJ85G4OG0miN4E8BTGT+JBTLO87RQ7iCwsIDCqCsHnf2IaSXA==} dependencies: - '@types/node': 20.8.4 + '@types/node': 20.8.5 '@types/tar-stream': 2.2.2 dev: false /@types/tar-stream@2.2.2: resolution: {integrity: sha512-1AX+Yt3icFuU6kxwmPakaiGrJUwG44MpuiqPg4dSolRFk6jmvs4b3IbUol9wKDLIgU76gevn3EwE8y/DkSJCZQ==} dependencies: - '@types/node': 20.8.5 + '@types/node': 20.8.6 dev: false /@types/uuid@9.0.5: @@ -2045,7 +2045,7 @@ packages: resolution: {integrity: sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==} requiresBuild: true dependencies: - '@types/node': 20.8.5 + '@types/node': 20.8.6 dev: true optional: true @@ -2228,7 +2228,7 @@ packages: vite: ^4 dependencies: '@swc/core': 1.3.88 - vite: 4.4.10(@types/node@20.8.5)(lightningcss@1.22.0) + vite: 4.4.10(@types/node@20.8.6)(lightningcss@1.22.0) transitivePeerDependencies: - '@swc/helpers' dev: true @@ -6716,7 +6716,7 @@ packages: typescript: 5.2.2 dev: true - /ts-node@10.9.1(@types/node@20.8.5)(typescript@5.2.2): + /ts-node@10.9.1(@types/node@20.8.6)(typescript@5.2.2): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -6735,7 +6735,7 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.8.5 + '@types/node': 20.8.6 acorn: 8.10.0 acorn-walk: 8.2.0 arg: 4.1.3 @@ -6975,7 +6975,7 @@ packages: extsprintf: 1.4.1 dev: true - /vite-node@0.34.6(@types/node@20.8.4)(lightningcss@1.22.0): + /vite-node@0.34.6(@types/node@20.8.5)(lightningcss@1.22.0): resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} engines: {node: '>=v14.18.0'} hasBin: true @@ -6985,7 +6985,7 @@ packages: mlly: 1.4.1 pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.4.10(@types/node@20.8.4)(lightningcss@1.22.0) + vite: 4.4.10(@types/node@20.8.5)(lightningcss@1.22.0) transitivePeerDependencies: - '@types/node' - less @@ -6997,7 +6997,7 @@ packages: - terser dev: true - /vite-node@0.34.6(@types/node@20.8.5): + /vite-node@0.34.6(@types/node@20.8.6): resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} engines: {node: '>=v14.18.0'} hasBin: true @@ -7007,7 +7007,7 @@ packages: mlly: 1.4.1 pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.4.10(@types/node@20.8.5)(lightningcss@1.22.0) + vite: 4.4.10(@types/node@20.8.6)(lightningcss@1.22.0) transitivePeerDependencies: - '@types/node' - less @@ -7065,14 +7065,14 @@ packages: strip-ansi: 6.0.1 tiny-invariant: 1.3.1 typescript: 5.2.2 - vite: 4.4.10(@types/node@20.8.5)(lightningcss@1.22.0) + vite: 4.4.10(@types/node@20.8.6)(lightningcss@1.22.0) vscode-languageclient: 7.0.0 vscode-languageserver: 7.0.0 vscode-languageserver-textdocument: 1.0.8 vscode-uri: 3.0.7 dev: true - /vite-plugin-dts@3.6.0(@types/node@20.8.5)(rollup@4.1.4)(typescript@5.2.2)(vite@4.4.10): + /vite-plugin-dts@3.6.0(@types/node@20.8.6)(rollup@4.1.4)(typescript@5.2.2)(vite@4.4.10): resolution: {integrity: sha512-doxhDRFJCZD2sGjIp4V800nm8Y19GvmwckjG5vYPuiqJ7OBjc9NlW1Vp9Gkyh2aXlUs1jTDRH/lxWfcsPLOQHg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -7082,13 +7082,13 @@ packages: vite: optional: true dependencies: - '@microsoft/api-extractor': 7.36.4(@types/node@20.8.5) + '@microsoft/api-extractor': 7.36.4(@types/node@20.8.6) '@rollup/pluginutils': 5.0.4(rollup@4.1.4) '@vue/language-core': 1.8.8(typescript@5.2.2) debug: 4.3.4(supports-color@8.1.1) kolorist: 1.8.0 typescript: 5.2.2 - vite: 4.4.10(@types/node@20.8.5)(lightningcss@1.22.0) + vite: 4.4.10(@types/node@20.8.6)(lightningcss@1.22.0) vue-tsc: 1.8.8(typescript@5.2.2) transitivePeerDependencies: - '@types/node' @@ -7096,7 +7096,7 @@ packages: - supports-color dev: true - /vite@4.4.10(@types/node@20.8.4)(lightningcss@1.22.0): + /vite@4.4.10(@types/node@20.8.5)(lightningcss@1.22.0): resolution: {integrity: sha512-TzIjiqx9BEXF8yzYdF2NTf1kFFbjMjUSV0LFZ3HyHoI3SGSPLnnFUKiIQtL3gl2AjHvMrprOvQ3amzaHgQlAxw==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -7124,7 +7124,7 @@ packages: terser: optional: true dependencies: - '@types/node': 20.8.4 + '@types/node': 20.8.5 esbuild: 0.18.20 lightningcss: 1.22.0 postcss: 8.4.28 @@ -7133,7 +7133,7 @@ packages: fsevents: 2.3.3 dev: true - /vite@4.4.10(@types/node@20.8.5)(lightningcss@1.22.0): + /vite@4.4.10(@types/node@20.8.6)(lightningcss@1.22.0): resolution: {integrity: sha512-TzIjiqx9BEXF8yzYdF2NTf1kFFbjMjUSV0LFZ3HyHoI3SGSPLnnFUKiIQtL3gl2AjHvMrprOvQ3amzaHgQlAxw==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -7161,7 +7161,7 @@ packages: terser: optional: true dependencies: - '@types/node': 20.8.5 + '@types/node': 20.8.6 esbuild: 0.18.20 lightningcss: 1.22.0 postcss: 8.4.28 @@ -7203,7 +7203,7 @@ packages: dependencies: '@types/chai': 4.3.7 '@types/chai-subset': 1.3.3 - '@types/node': 20.8.5 + '@types/node': 20.8.6 '@vitest/expect': 0.34.6 '@vitest/runner': 0.34.6 '@vitest/snapshot': 0.34.6 @@ -7222,8 +7222,8 @@ packages: strip-literal: 1.3.0 tinybench: 2.5.0 tinypool: 0.7.0 - vite: 4.4.10(@types/node@20.8.5)(lightningcss@1.22.0) - vite-node: 0.34.6(@types/node@20.8.5) + vite: 4.4.10(@types/node@20.8.6)(lightningcss@1.22.0) + vite-node: 0.34.6(@types/node@20.8.6) why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -7268,7 +7268,7 @@ packages: dependencies: '@types/chai': 4.3.6 '@types/chai-subset': 1.3.3 - '@types/node': 20.8.4 + '@types/node': 20.8.5 '@vitest/expect': 0.34.6 '@vitest/runner': 0.34.6 '@vitest/snapshot': 0.34.6 @@ -7288,8 +7288,8 @@ packages: strip-literal: 1.3.0 tinybench: 2.5.0 tinypool: 0.7.0 - vite: 4.4.10(@types/node@20.8.4)(lightningcss@1.22.0) - vite-node: 0.34.6(@types/node@20.8.4)(lightningcss@1.22.0) + vite: 4.4.10(@types/node@20.8.5)(lightningcss@1.22.0) + vite-node: 0.34.6(@types/node@20.8.5)(lightningcss@1.22.0) why-is-node-running: 2.2.2 transitivePeerDependencies: - less From 0844b57f64ec04c692f88ae62b3db9ffaa7903ed Mon Sep 17 00:00:00 2001 From: Jon Koops Date: Tue, 17 Oct 2023 11:43:41 +0200 Subject: [PATCH 18/27] Wait for request when testing session revocation (#24048) --- .../admin-ui/manage/sessions/SessionsPage.ts | 57 +++++++------------ 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/sessions/SessionsPage.ts b/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/sessions/SessionsPage.ts index e3f1eef436dd..31548e21cb52 100644 --- a/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/sessions/SessionsPage.ts +++ b/js/apps/admin-ui/cypress/support/pages/admin-ui/manage/sessions/SessionsPage.ts @@ -1,54 +1,41 @@ export default class SessionsPage { - sessionTypeList = ".pf-c-select__toggle + ul"; - allSessionTypesOption = "all-sessions-option"; - regularSSOOption = "regular-sso-option"; - offlineOption = "offline-option"; - directGrantOption = "direct-grant-option"; - serviceAccountOption = "service-account-option"; - selectedType = ".pf-c-select__toggle-text"; - revocationActionItem = "revocation"; - setToNowButton = "set-to-now-button"; - actionDropdown = "action-dropdown"; - clearNotBeforeButton = "clear-not-before-button"; - pushButton = "modal-test-connection-button"; - notBeforeInput = "not-before-input"; - logoutAll = "logout-all"; - logoutAllConfirm = "confirm"; + #revocationActionItem = "revocation"; + #setToNowButton = "set-to-now-button"; + #actionDropdown = "action-dropdown"; + #clearNotBeforeButton = "clear-not-before-button"; + #pushButton = "modal-test-connection-button"; + #notBeforeInput = "not-before-input"; setToNow() { - cy.findByTestId(this.actionDropdown).should("exist").click(); - cy.findByTestId(this.revocationActionItem).should("exist").click(); - cy.findByTestId(this.setToNowButton).should("exist").click(); + this.#openRevocationDialog(); + cy.findByTestId(this.#setToNowButton).click(); Cypress.session.clearAllSavedSessions(); } checkNotBeforeValueExists() { - cy.findByTestId(this.actionDropdown).should("exist").click(); - cy.findByTestId(this.revocationActionItem).should("exist").click(); - cy.findByTestId(this.notBeforeInput).should("not.have.value", "None"); + this.#openRevocationDialog(); + cy.findByTestId(this.#notBeforeInput).should("not.have.value", "None"); } clearNotBefore() { - cy.findByTestId(this.actionDropdown).should("exist").click(); - cy.findByTestId(this.revocationActionItem).should("exist").click(); - cy.findByTestId(this.clearNotBeforeButton).should("exist").click(); + this.#openRevocationDialog(); + cy.findByTestId(this.#clearNotBeforeButton).click(); } checkNotBeforeCleared() { - cy.findByTestId(this.actionDropdown).should("exist").click(); - cy.findByTestId(this.revocationActionItem).should("exist").click(); - cy.findByTestId(this.notBeforeInput).should("have.value", "None"); + this.#openRevocationDialog(); + cy.findByTestId(this.#notBeforeInput).should("have.value", "None"); } - logoutAllSessions() { - cy.findByTestId(this.actionDropdown).should("exist").click(); - cy.findByTestId(this.logoutAll).should("exist").click(); - cy.findByTestId(this.logoutAllConfirm).should("exist").click(); + pushRevocation() { + this.#openRevocationDialog(); + cy.findByTestId(this.#pushButton).click(); } - pushRevocation() { - cy.findByTestId(this.actionDropdown).should("exist").click(); - cy.findByTestId(this.revocationActionItem).should("exist").click(); - cy.findByTestId(this.pushButton).should("exist").click(); + #openRevocationDialog() { + cy.findByTestId(this.#actionDropdown).click(); + cy.intercept("/admin/realms/master").as("fetchRealm"); + cy.findByTestId(this.#revocationActionItem).click(); + cy.wait("@fetchRealm"); } } From 172bc33b91c6120d6f4f7c5236419ab08ce5d107 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 12:01:28 +0200 Subject: [PATCH 19/27] Bump @rollup/plugin-inject from 5.0.4 to 5.0.5 in /js (#24000) Bumps [@rollup/plugin-inject](https://github.com/rollup/plugins/tree/HEAD/packages/inject) from 5.0.4 to 5.0.5. - [Changelog](https://github.com/rollup/plugins/blob/master/packages/inject/CHANGELOG.md) - [Commits](https://github.com/rollup/plugins/commits/inject-v5.0.5/packages/inject) --- updated-dependencies: - dependency-name: "@rollup/plugin-inject" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- js/libs/keycloak-js/package.json | 2 +- js/pnpm-lock.yaml | 17 +++++------------ 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/js/libs/keycloak-js/package.json b/js/libs/keycloak-js/package.json index 786ea2687e58..a48ab5a9d1b5 100644 --- a/js/libs/keycloak-js/package.json +++ b/js/libs/keycloak-js/package.json @@ -43,7 +43,7 @@ ], "devDependencies": { "@rollup/plugin-commonjs": "^25.0.7", - "@rollup/plugin-inject": "^5.0.4", + "@rollup/plugin-inject": "^5.0.5", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.5", diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index b70d994b2bda..3d07984ee275 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -367,8 +367,8 @@ importers: specifier: ^25.0.7 version: 25.0.7(rollup@4.1.4) '@rollup/plugin-inject': - specifier: ^5.0.4 - version: 5.0.4(rollup@4.1.4) + specifier: ^5.0.5 + version: 5.0.5(rollup@4.1.4) '@rollup/plugin-node-resolve': specifier: ^15.2.3 version: 15.2.3(rollup@4.1.4) @@ -1301,8 +1301,8 @@ packages: rollup: 4.1.4 dev: true - /@rollup/plugin-inject@5.0.4(rollup@4.1.4): - resolution: {integrity: sha512-dM93Nyqp9Ah14jvThFFA30ifjB8cDKk3Bx69M1nIIHGytXug3VrTv5HEuYBzevu45HvZ0ho7t+40bmScmkzZhg==} + /@rollup/plugin-inject@5.0.5(rollup@4.1.4): + resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 @@ -1312,7 +1312,7 @@ packages: dependencies: '@rollup/pluginutils': 5.0.4(rollup@4.1.4) estree-walker: 2.0.2 - magic-string: 0.27.0 + magic-string: 0.30.3 rollup: 4.1.4 dev: true @@ -5278,13 +5278,6 @@ packages: hasBin: true dev: true - /magic-string@0.27.0: - resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} - engines: {node: '>=12'} - dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 - dev: true - /magic-string@0.30.3: resolution: {integrity: sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==} engines: {node: '>=12'} From be098c139e955a244fe6489314d69c92672b24fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 12:39:31 +0200 Subject: [PATCH 20/27] Bump @typescript-eslint/parser from 6.7.5 to 6.8.0 in /js (#24039) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.7.5 to 6.8.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.8.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- js/package.json | 2 +- js/pnpm-lock.yaml | 86 ++++++++++++----------------------------------- 2 files changed, 23 insertions(+), 65 deletions(-) diff --git a/js/package.json b/js/package.json index e82bcf54142e..17124c09b265 100644 --- a/js/package.json +++ b/js/package.json @@ -6,7 +6,7 @@ "devDependencies": { "@types/node": "^20.8.6", "@typescript-eslint/eslint-plugin": "^6.8.0", - "@typescript-eslint/parser": "^6.7.5", + "@typescript-eslint/parser": "^6.8.0", "eslint": "^8.51.0", "eslint-config-prettier": "^9.0.0", "eslint-import-resolver-typescript": "^3.6.1", diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index 3d07984ee275..2111e9024cd8 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -13,10 +13,10 @@ importers: version: 20.8.6 '@typescript-eslint/eslint-plugin': specifier: ^6.8.0 - version: 6.8.0(@typescript-eslint/parser@6.7.5)(eslint@8.51.0)(typescript@5.2.2) + version: 6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(typescript@5.2.2) '@typescript-eslint/parser': - specifier: ^6.7.5 - version: 6.7.5(eslint@8.51.0)(typescript@5.2.2) + specifier: ^6.8.0 + version: 6.8.0(eslint@8.51.0)(typescript@5.2.2) eslint: specifier: ^8.51.0 version: 8.51.0 @@ -25,13 +25,13 @@ importers: version: 9.0.0(eslint@8.51.0) eslint-import-resolver-typescript: specifier: ^3.6.1 - version: 3.6.1(@typescript-eslint/parser@6.7.5)(eslint-plugin-import@2.28.1)(eslint@8.51.0) + version: 3.6.1(@typescript-eslint/parser@6.8.0)(eslint-plugin-import@2.28.1)(eslint@8.51.0) eslint-plugin-cypress: specifier: ^2.15.1 version: 2.15.1(eslint@8.51.0) eslint-plugin-import: specifier: ^2.28.1 - version: 2.28.1(@typescript-eslint/parser@6.7.5)(eslint-import-resolver-typescript@3.6.1)(eslint@8.51.0) + version: 2.28.1(@typescript-eslint/parser@6.8.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.51.0) eslint-plugin-lodash: specifier: ^7.4.0 version: 7.4.0(eslint@8.51.0) @@ -2049,7 +2049,7 @@ packages: dev: true optional: true - /@typescript-eslint/eslint-plugin@6.8.0(@typescript-eslint/parser@6.7.5)(eslint@8.51.0)(typescript@5.2.2): + /@typescript-eslint/eslint-plugin@6.8.0(@typescript-eslint/parser@6.8.0)(eslint@8.51.0)(typescript@5.2.2): resolution: {integrity: sha512-GosF4238Tkes2SHPQ1i8f6rMtG6zlKwMEB0abqSJ3Npvos+doIlc/ATG+vX1G9coDF3Ex78zM3heXHLyWEwLUw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -2061,7 +2061,7 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.8.0 - '@typescript-eslint/parser': 6.7.5(eslint@8.51.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.8.0(eslint@8.51.0)(typescript@5.2.2) '@typescript-eslint/scope-manager': 6.8.0 '@typescript-eslint/type-utils': 6.8.0(eslint@8.51.0)(typescript@5.2.2) '@typescript-eslint/utils': 6.8.0(eslint@8.51.0)(typescript@5.2.2) @@ -2078,8 +2078,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser@6.7.5(eslint@8.51.0)(typescript@5.2.2): - resolution: {integrity: sha512-bIZVSGx2UME/lmhLcjdVc7ePBwn7CLqKarUBL4me1C5feOd663liTGjMBGVcGr+BhnSLeP4SgwdvNnnkbIdkCw==} + /@typescript-eslint/parser@6.8.0(eslint@8.51.0)(typescript@5.2.2): + resolution: {integrity: sha512-5tNs6Bw0j6BdWuP8Fx+VH4G9fEPDxnVI7yH1IAPkQH5RUtvKwRoqdecAPdQXv4rSOADAaz1LFBZvZG7VbXivSg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -2088,10 +2088,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 6.7.5 - '@typescript-eslint/types': 6.7.5 - '@typescript-eslint/typescript-estree': 6.7.5(typescript@5.2.2) - '@typescript-eslint/visitor-keys': 6.7.5 + '@typescript-eslint/scope-manager': 6.8.0 + '@typescript-eslint/types': 6.8.0 + '@typescript-eslint/typescript-estree': 6.8.0(typescript@5.2.2) + '@typescript-eslint/visitor-keys': 6.8.0 debug: 4.3.4(supports-color@8.1.1) eslint: 8.51.0 typescript: 5.2.2 @@ -2099,14 +2099,6 @@ packages: - supports-color dev: true - /@typescript-eslint/scope-manager@6.7.5: - resolution: {integrity: sha512-GAlk3eQIwWOJeb9F7MKQ6Jbah/vx1zETSDw8likab/eFcqkjSD7BI75SDAeC5N2L0MmConMoPvTsmkrg71+B1A==} - engines: {node: ^16.0.0 || >=18.0.0} - dependencies: - '@typescript-eslint/types': 6.7.5 - '@typescript-eslint/visitor-keys': 6.7.5 - dev: true - /@typescript-eslint/scope-manager@6.8.0: resolution: {integrity: sha512-xe0HNBVwCph7rak+ZHcFD6A+q50SMsFwcmfdjs9Kz4qDh5hWhaPhFjRs/SODEhroBI5Ruyvyz9LfwUJ624O40g==} engines: {node: ^16.0.0 || >=18.0.0} @@ -2135,37 +2127,11 @@ packages: - supports-color dev: true - /@typescript-eslint/types@6.7.5: - resolution: {integrity: sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ==} - engines: {node: ^16.0.0 || >=18.0.0} - dev: true - /@typescript-eslint/types@6.8.0: resolution: {integrity: sha512-p5qOxSum7W3k+llc7owEStXlGmSl8FcGvhYt8Vjy7FqEnmkCVlM3P57XQEGj58oqaBWDQXbJDZxwUWMS/EAPNQ==} engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@6.7.5(typescript@5.2.2): - resolution: {integrity: sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 6.7.5 - '@typescript-eslint/visitor-keys': 6.7.5 - debug: 4.3.4(supports-color@8.1.1) - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.5.4 - ts-api-utils: 1.0.2(typescript@5.2.2) - typescript: 5.2.2 - transitivePeerDependencies: - - supports-color - dev: true - /@typescript-eslint/typescript-estree@6.8.0(typescript@5.2.2): resolution: {integrity: sha512-ISgV0lQ8XgW+mvv5My/+iTUdRmGspducmQcDw5JxznasXNnZn3SKNrTRuMsEXv+V/O+Lw9AGcQCfVaOPCAk/Zg==} engines: {node: ^16.0.0 || >=18.0.0} @@ -2206,14 +2172,6 @@ packages: - typescript dev: true - /@typescript-eslint/visitor-keys@6.7.5: - resolution: {integrity: sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg==} - engines: {node: ^16.0.0 || >=18.0.0} - dependencies: - '@typescript-eslint/types': 6.7.5 - eslint-visitor-keys: 3.4.3 - dev: true - /@typescript-eslint/visitor-keys@6.8.0: resolution: {integrity: sha512-oqAnbA7c+pgOhW2OhGvxm0t1BULX5peQI/rLsNDpGM78EebV3C9IGbX5HNZabuZ6UQrYveCLjKo8Iy/lLlBkkg==} engines: {node: ^16.0.0 || >=18.0.0} @@ -3590,7 +3548,7 @@ packages: - supports-color dev: true - /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.7.5)(eslint-plugin-import@2.28.1)(eslint@8.51.0): + /eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.8.0)(eslint-plugin-import@2.28.1)(eslint@8.51.0): resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: @@ -3600,8 +3558,8 @@ packages: debug: 4.3.4(supports-color@8.1.1) enhanced-resolve: 5.15.0 eslint: 8.51.0 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.7.5)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.51.0) - eslint-plugin-import: 2.28.1(@typescript-eslint/parser@6.7.5)(eslint-import-resolver-typescript@3.6.1)(eslint@8.51.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.8.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.51.0) + eslint-plugin-import: 2.28.1(@typescript-eslint/parser@6.8.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.51.0) fast-glob: 3.3.1 get-tsconfig: 4.7.0 is-core-module: 2.13.0 @@ -3613,7 +3571,7 @@ packages: - supports-color dev: true - /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.7.5)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.51.0): + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.8.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.51.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -3634,11 +3592,11 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 6.7.5(eslint@8.51.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.8.0(eslint@8.51.0)(typescript@5.2.2) debug: 3.2.7(supports-color@8.1.1) eslint: 8.51.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.7.5)(eslint-plugin-import@2.28.1)(eslint@8.51.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.8.0)(eslint-plugin-import@2.28.1)(eslint@8.51.0) transitivePeerDependencies: - supports-color dev: true @@ -3652,7 +3610,7 @@ packages: globals: 13.21.0 dev: true - /eslint-plugin-import@2.28.1(@typescript-eslint/parser@6.7.5)(eslint-import-resolver-typescript@3.6.1)(eslint@8.51.0): + /eslint-plugin-import@2.28.1(@typescript-eslint/parser@6.8.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.51.0): resolution: {integrity: sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==} engines: {node: '>=4'} peerDependencies: @@ -3662,7 +3620,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 6.7.5(eslint@8.51.0)(typescript@5.2.2) + '@typescript-eslint/parser': 6.8.0(eslint@8.51.0)(typescript@5.2.2) array-includes: 3.1.6 array.prototype.findlastindex: 1.2.2 array.prototype.flat: 1.3.1 @@ -3671,7 +3629,7 @@ packages: doctrine: 2.1.0 eslint: 8.51.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.7.5)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.51.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.8.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.51.0) has: 1.0.3 is-core-module: 2.13.0 is-glob: 4.0.3 From ef3474a5c18294619c6e1aa88579a23e34285d66 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 10:41:30 +0000 Subject: [PATCH 21/27] Bump @types/chai from 4.3.7 to 4.3.8 in /js (#23955) Bumps [@types/chai](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/chai) from 4.3.7 to 4.3.8. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/chai) --- updated-dependencies: - dependency-name: "@types/chai" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- js/libs/keycloak-admin-client/package.json | 2 +- js/pnpm-lock.yaml | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/js/libs/keycloak-admin-client/package.json b/js/libs/keycloak-admin-client/package.json index 7696e03495c4..92dcf3464927 100644 --- a/js/libs/keycloak-admin-client/package.json +++ b/js/libs/keycloak-admin-client/package.json @@ -44,7 +44,7 @@ }, "devDependencies": { "@faker-js/faker": "^8.1.0", - "@types/chai": "^4.3.7", + "@types/chai": "^4.3.8", "@types/lodash-es": "^4.17.9", "@types/mocha": "^10.0.2", "@types/node": "^20.8.6", diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index 2111e9024cd8..18afda9dc8f8 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -330,8 +330,8 @@ importers: specifier: ^8.1.0 version: 8.1.0 '@types/chai': - specifier: ^4.3.7 - version: 4.3.7 + specifier: ^4.3.8 + version: 4.3.8 '@types/lodash-es': specifier: ^4.17.9 version: 4.17.9 @@ -1741,17 +1741,17 @@ packages: /@types/chai-subset@1.3.3: resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} dependencies: - '@types/chai': 4.3.7 - dev: true - - /@types/chai@4.3.6: - resolution: {integrity: sha512-VOVRLM1mBxIRxydiViqPcKn6MIxZytrbMpd6RJLIWKxUNr3zux8no0Oc7kJx0WAPIitgZ0gkrDS+btlqQpubpw==} + '@types/chai': 4.3.8 dev: true /@types/chai@4.3.7: resolution: {integrity: sha512-/k+vesl92vMvMygmQrFe9Aimxi6oQXFUX9mA5HanTrKUSAMoLauSi6PNFOdRw0oeqilaW600GNx2vSaT2f8aIQ==} dev: true + /@types/chai@4.3.8: + resolution: {integrity: sha512-yW/qTM4mRBBcsA9Xw9FbcImYtFPY7sgr+G/O5RDYVmxiy9a+pE5FyoFUi8JYCZY5nicj8atrr1pcfPiYpeNGOA==} + dev: true + /@types/d3-array@3.0.7: resolution: {integrity: sha512-4/Q0FckQ8TBjsB0VdGFemJOG8BLXUB2KKlL0VmZ+eOYeOnTb/wDRQqYWpBmQ6IlvWkXwkYiot+n9Px2aTJ7zGQ==} dev: false @@ -7152,7 +7152,7 @@ packages: webdriverio: optional: true dependencies: - '@types/chai': 4.3.7 + '@types/chai': 4.3.8 '@types/chai-subset': 1.3.3 '@types/node': 20.8.6 '@vitest/expect': 0.34.6 @@ -7217,7 +7217,7 @@ packages: webdriverio: optional: true dependencies: - '@types/chai': 4.3.6 + '@types/chai': 4.3.7 '@types/chai-subset': 1.3.3 '@types/node': 20.8.5 '@vitest/expect': 0.34.6 From 6f53b92b03f5ff3ba7d9691e827f46bc10794158 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 12:41:41 +0200 Subject: [PATCH 22/27] Bump react-i18next from 13.2.2 to 13.3.0 in /js (#23997) Bumps [react-i18next](https://github.com/i18next/react-i18next) from 13.2.2 to 13.3.0. - [Changelog](https://github.com/i18next/react-i18next/blob/master/CHANGELOG.md) - [Commits](https://github.com/i18next/react-i18next/compare/v13.2.2...v13.3.0) --- updated-dependencies: - dependency-name: react-i18next dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- js/apps/account-ui/package.json | 2 +- js/apps/admin-ui/package.json | 2 +- js/pnpm-lock.yaml | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/js/apps/account-ui/package.json b/js/apps/account-ui/package.json index d2f4c2c56e05..95906bd0d937 100644 --- a/js/apps/account-ui/package.json +++ b/js/apps/account-ui/package.json @@ -21,7 +21,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-hook-form": "^7.47.0", - "react-i18next": "^13.2.2", + "react-i18next": "^13.3.0", "react-router-dom": "^6.15.0", "ui-shared": "workspace:*" }, diff --git a/js/apps/admin-ui/package.json b/js/apps/admin-ui/package.json index 3f7232121283..d4f17493da5b 100644 --- a/js/apps/admin-ui/package.json +++ b/js/apps/admin-ui/package.json @@ -82,7 +82,7 @@ "react-dropzone": "^14.2.3", "react-error-boundary": "^3.1.4", "react-hook-form": "^7.47.0", - "react-i18next": "^13.2.2", + "react-i18next": "^13.3.0", "react-router-dom": "^6.15.0", "reactflow": "^11.9.4", "ui-shared": "workspace:*", diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index 18afda9dc8f8..035fe1cc11b1 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -105,8 +105,8 @@ importers: specifier: ^7.47.0 version: 7.47.0(react@18.2.0) react-i18next: - specifier: ^13.2.2 - version: 13.2.2(i18next@23.5.1)(react-dom@18.2.0)(react@18.2.0) + specifier: ^13.3.0 + version: 13.3.0(i18next@23.5.1)(react-dom@18.2.0)(react@18.2.0) react-router-dom: specifier: ^6.15.0 version: 6.15.0(react-dom@18.2.0)(react@18.2.0) @@ -211,8 +211,8 @@ importers: specifier: ^7.47.0 version: 7.47.0(react@18.2.0) react-i18next: - specifier: ^13.2.2 - version: 13.2.2(i18next@23.5.1)(react-dom@18.2.0)(react@18.2.0) + specifier: ^13.3.0 + version: 13.3.0(i18next@23.5.1)(react-dom@18.2.0)(react@18.2.0) react-router-dom: specifier: ^6.15.0 version: 6.15.0(react-dom@18.2.0)(react@18.2.0) @@ -5901,8 +5901,8 @@ packages: react: 18.2.0 dev: false - /react-i18next@13.2.2(i18next@23.5.1)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-+nFUkbRByFwnrfDcYqvzBuaeZb+nACHx+fAWN/pZMddWOCJH5hoc21+Sa/N/Lqi6ne6/9wC/qRGOoQhJa6IkEQ==} + /react-i18next@13.3.0(i18next@23.5.1)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-FlR9xjYHSPIJfQspEmkN0yOlxgRyNuiJKJ8gCaZH08UJ7SZHG+VrptEPcpEMEchjNoCOZdKcvJ3PnmHEZhkeXg==} peerDependencies: i18next: '>= 23.2.3' react: '>= 16.8.0' @@ -7625,7 +7625,7 @@ packages: react-dropzone: 14.2.3(react@18.2.0) react-error-boundary: 3.1.4(react@18.2.0) react-hook-form: 7.47.0(react@18.2.0) - react-i18next: 13.2.2(i18next@23.5.1)(react-dom@18.2.0)(react@18.2.0) + react-i18next: 13.3.0(i18next@23.5.1)(react-dom@18.2.0)(react@18.2.0) react-router-dom: 6.15.0(react-dom@18.2.0)(react@18.2.0) reactflow: 11.9.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0) ui-shared: link:libs/ui-shared From a54070470ad3bdf8994da8690f8354344b73957e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 12:41:57 +0200 Subject: [PATCH 23/27] Bump lint-staged from 14.0.1 to 15.0.1 in /js (#23996) Bumps [lint-staged](https://github.com/okonet/lint-staged) from 14.0.1 to 15.0.1. - [Release notes](https://github.com/okonet/lint-staged/releases) - [Changelog](https://github.com/lint-staged/lint-staged/blob/master/CHANGELOG.md) - [Commits](https://github.com/okonet/lint-staged/compare/v14.0.1...v15.0.1) --- updated-dependencies: - dependency-name: lint-staged dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- js/package.json | 2 +- js/pnpm-lock.yaml | 66 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 46 insertions(+), 22 deletions(-) diff --git a/js/package.json b/js/package.json index 17124c09b265..2116d8304bf1 100644 --- a/js/package.json +++ b/js/package.json @@ -18,7 +18,7 @@ "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "husky": "^8.0.3", - "lint-staged": "^14.0.1", + "lint-staged": "^15.0.1", "prettier": "^3.0.3", "tslib": "^2.6.2", "typescript": "^5.2.2", diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index 035fe1cc11b1..dbfb2b2c25ac 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -51,8 +51,8 @@ importers: specifier: ^8.0.3 version: 8.0.3 lint-staged: - specifier: ^14.0.1 - version: 14.0.1 + specifier: ^15.0.1 + version: 15.0.1 prettier: specifier: ^3.0.3 version: 3.0.3 @@ -2907,8 +2907,8 @@ packages: delayed-stream: 1.0.0 dev: true - /commander@11.0.0: - resolution: {integrity: sha512-9HMlXtt/BNoYr8ooyjjNRdIilOTkVJXB+GhxMTtOKwk0R4j4lS4NpjuqmRxroBfnfTSHQIHQB7wryHhXarNjmQ==} + /commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} dev: true @@ -3885,6 +3885,21 @@ packages: strip-final-newline: 3.0.0 dev: true + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.1.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: true + /executable@4.1.1: resolution: {integrity: sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==} engines: {node: '>=4'} @@ -4164,6 +4179,11 @@ packages: engines: {node: '>=10'} dev: true + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: true + /get-symbol-description@1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} @@ -4409,6 +4429,11 @@ packages: engines: {node: '>=14.18.0'} dev: true + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: true + /husky@8.0.3: resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} engines: {node: '>=14'} @@ -5083,23 +5108,22 @@ packages: engines: {node: '>=10'} dev: true - /lint-staged@14.0.1: - resolution: {integrity: sha512-Mw0cL6HXnHN1ag0mN/Dg4g6sr8uf8sn98w2Oc1ECtFto9tvRF7nkXGJRbx8gPlHyoR0pLyBr2lQHbWwmUHe1Sw==} - engines: {node: ^16.14.0 || >=18.0.0} + /lint-staged@15.0.1: + resolution: {integrity: sha512-2IU5OWmCaxch0X0+IBF4/v7sutpB+F3qoXbro43pYjQTOo5wumckjxoxn47pQBqqBsCWrD5HnI2uG/zJA7isew==} + engines: {node: '>=18.12.0'} hasBin: true dependencies: chalk: 5.3.0 - commander: 11.0.0 + commander: 11.1.0 debug: 4.3.4(supports-color@8.1.1) - execa: 7.2.0 + execa: 8.0.1 lilconfig: 2.1.0 - listr2: 6.6.1 + listr2: 7.0.1 micromatch: 4.0.5 pidtree: 0.6.0 string-argv: 0.3.2 - yaml: 2.3.1 + yaml: 2.3.2 transitivePeerDependencies: - - enquirer - supports-color dev: true @@ -5123,14 +5147,9 @@ packages: wrap-ansi: 7.0.0 dev: true - /listr2@6.6.1: - resolution: {integrity: sha512-+rAXGHh0fkEWdXBmX+L6mmfmXmXvDGEKzkjxO+8mP3+nI/r/CWznVBvsibXdxda9Zz0OW2e2ikphN3OwCT/jSg==} + /listr2@7.0.1: + resolution: {integrity: sha512-nz+7hwgbDp8eWNoDgzdl4hA/xDSLrNRzPu1TLgOYs6l5Y+Ma6zVWWy9Oyt9TQFONwKoSPoka3H50D3vD5EuNwg==} engines: {node: '>=16.0.0'} - peerDependencies: - enquirer: '>= 2.3.0 < 3' - peerDependenciesMeta: - enquirer: - optional: true dependencies: cli-truncate: 3.1.0 colorette: 2.0.20 @@ -6284,6 +6303,11 @@ packages: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: true + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true + /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -7512,8 +7536,8 @@ packages: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true - /yaml@2.3.1: - resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==} + /yaml@2.3.2: + resolution: {integrity: sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==} engines: {node: '>= 14'} dev: true From c51060ae34e661dc032adab7e659e3e3618d7f55 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 12:49:52 +0200 Subject: [PATCH 24/27] Bump cypress from 13.3.0 to 13.3.1 in /js (#23926) Bumps [cypress](https://github.com/cypress-io/cypress) from 13.3.0 to 13.3.1. - [Release notes](https://github.com/cypress-io/cypress/releases) - [Changelog](https://github.com/cypress-io/cypress/blob/develop/CHANGELOG.md) - [Commits](https://github.com/cypress-io/cypress/compare/v13.3.0...v13.3.1) --- updated-dependencies: - dependency-name: cypress dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- js/apps/admin-ui/package.json | 2 +- js/pnpm-lock.yaml | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/js/apps/admin-ui/package.json b/js/apps/admin-ui/package.json index d4f17493da5b..96b520bf4d73 100644 --- a/js/apps/admin-ui/package.json +++ b/js/apps/admin-ui/package.json @@ -100,7 +100,7 @@ "@types/react-dom": "^18.2.13", "@types/uuid": "^9.0.5", "@vitejs/plugin-react-swc": "^3.4.0", - "cypress": "^13.3.0", + "cypress": "^13.3.1", "cypress-axe": "^1.5.0", "jsdom": "^22.1.0", "ldap-server-mock": "^6.0.1", diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index dbfb2b2c25ac..db8fb2e96c00 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -228,10 +228,10 @@ importers: devDependencies: '@4tw/cypress-drag-drop': specifier: ^2.2.5 - version: 2.2.5(cypress@13.3.0) + version: 2.2.5(cypress@13.3.1) '@testing-library/cypress': specifier: ^10.0.1 - version: 10.0.1(cypress@13.3.0) + version: 10.0.1(cypress@13.3.1) '@testing-library/jest-dom': specifier: ^6.1.4 version: 6.1.4(vitest@0.34.6) @@ -260,11 +260,11 @@ importers: specifier: ^3.4.0 version: 3.4.0(vite@4.4.10) cypress: - specifier: ^13.3.0 - version: 13.3.0 + specifier: ^13.3.1 + version: 13.3.1 cypress-axe: specifier: ^1.5.0 - version: 1.5.0(axe-core@4.7.2)(cypress@13.3.0) + version: 1.5.0(axe-core@4.7.2)(cypress@13.3.1) jsdom: specifier: ^22.1.0 version: 22.1.0 @@ -470,12 +470,12 @@ importers: packages: - /@4tw/cypress-drag-drop@2.2.5(cypress@13.3.0): + /@4tw/cypress-drag-drop@2.2.5(cypress@13.3.1): resolution: {integrity: sha512-3ghTmzhOmUqeN6U3QmUnKRUxI7OMLbJA4hHUY/eS/FhWJgxbiGgcaELbolWnBAOpajPXcsNQGYEj9brd59WH6A==} peerDependencies: cypress: 2 - 13 dependencies: - cypress: 13.3.0 + cypress: 13.3.1 dev: true /@aashutoshrathi/word-wrap@1.2.6: @@ -1641,7 +1641,7 @@ packages: resolution: {integrity: sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==} dev: true - /@testing-library/cypress@10.0.1(cypress@13.3.0): + /@testing-library/cypress@10.0.1(cypress@13.3.1): resolution: {integrity: sha512-e8uswjTZIBhaIXjzEcrQQ8nHRWHgZH7XBxKuIWxZ/T7FxfWhCR48nFhUX5nfPizjVOKSThEfOSv67jquc1ASkw==} engines: {node: '>=12', npm: '>=6'} peerDependencies: @@ -1649,7 +1649,7 @@ packages: dependencies: '@babel/runtime': 7.22.11 '@testing-library/dom': 9.3.1 - cypress: 13.3.0 + cypress: 13.3.1 dev: true /@testing-library/dom@9.3.1: @@ -2995,7 +2995,7 @@ packages: /csstype@3.1.2: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} - /cypress-axe@1.5.0(axe-core@4.7.2)(cypress@13.3.0): + /cypress-axe@1.5.0(axe-core@4.7.2)(cypress@13.3.1): resolution: {integrity: sha512-Hy/owCjfj+25KMsecvDgo4fC/781ccL+e8p+UUYoadGVM2ogZF9XIKbiM6KI8Y3cEaSreymdD6ZzccbI2bY0lQ==} engines: {node: '>=10'} peerDependencies: @@ -3003,11 +3003,11 @@ packages: cypress: ^10 || ^11 || ^12 || ^13 dependencies: axe-core: 4.7.2 - cypress: 13.3.0 + cypress: 13.3.1 dev: true - /cypress@13.3.0: - resolution: {integrity: sha512-mpI8qcTwLGiA4zEQvTC/U1xGUezVV4V8HQCOYjlEOrVmU1etVvxOjkCXHGwrlYdZU/EPmUiWfsO3yt1o+Q2bgw==} + /cypress@13.3.1: + resolution: {integrity: sha512-g4mJLZxYN+UAF2LMy3Znd4LBnUmS59Vynd81VES59RdW48Yt+QtR2cush3melOoVNz0PPbADpWr8DcUx6mif8Q==} engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} hasBin: true requiresBuild: true From 6112b25648b294ba77d8f476735dc580b67639c9 Mon Sep 17 00:00:00 2001 From: shigeyuki kabano Date: Tue, 1 Aug 2023 18:52:03 +0900 Subject: [PATCH 25/27] Enhancing Light Weight Token(#22148) Closes #21183 --- .../representations/JsonWebToken.java | 9 +- .../public/locales/en/translation.json | 4 + .../infinispan/UserSessionAdapter.java | 1 + .../session/PersistentUserSessionAdapter.java | 5 + .../userSession/MapUserSessionAdapter.java | 6 +- .../org/keycloak/models/UserSessionModel.java | 4 +- .../AccessTokenIntrospectionProvider.java | 60 +++ .../oidc/OIDCLoginProtocolFactory.java | 32 +- .../keycloak/protocol/oidc/TokenManager.java | 12 + .../oidc/endpoints/UserInfoEndpoint.java | 83 +-- .../mappers/AbstractOIDCProtocolMapper.java | 11 + .../mappers/AbstractPairwiseSubMapper.java | 9 +- .../AbstractUserRoleMappingMapper.java | 2 +- .../oidc/mappers/AcrProtocolMapper.java | 5 +- .../protocol/oidc/mappers/AddressMapper.java | 7 +- .../AllowedWebOriginsProtocolMapper.java | 69 ++- .../oidc/mappers/AudienceProtocolMapper.java | 5 +- .../AudienceResolveProtocolMapper.java | 67 ++- .../mappers/ClaimsParameterTokenMapper.java | 8 +- ...ClaimsParameterWithValueIdTokenMapper.java | 2 +- .../protocol/oidc/mappers/FullNameMapper.java | 5 +- .../oidc/mappers/GroupMembershipMapper.java | 11 +- .../protocol/oidc/mappers/HardcodedClaim.java | 11 +- .../protocol/oidc/mappers/HardcodedRole.java | 10 +- .../mappers/OIDCAttributeMapperHelper.java | 51 +- .../protocol/oidc/mappers/RoleNameMapper.java | 10 +- .../ScriptBasedOIDCProtocolMapper.java | 8 +- .../TokenIntrospectionTokenMapper.java | 12 + .../oidc/mappers/UserAttributeMapper.java | 14 +- .../mappers/UserClientRoleMappingMapper.java | 8 +- .../oidc/mappers/UserPropertyMapper.java | 6 +- .../mappers/UserRealmRoleMappingMapper.java | 12 +- .../oidc/mappers/UserSessionNoteMapper.java | 13 +- .../services/managers/ClientManager.java | 6 +- .../services/util/UserSessionUtil.java | 97 ++++ .../rest/TestingResourceProvider.java | 2 +- ...KcOidcBrokerSubMatchIntrospectionTest.java | 14 +- .../testsuite/broker/KcOidcBrokerTest.java | 29 +- .../broker/KcOidcBrokerTokenExchangeTest.java | 6 +- .../AbstractKerberosSingleRealmTest.java | 3 +- .../ldap/LDAPMultipleAttributesTest.java | 5 +- .../testsuite/oauth/AccessTokenTest.java | 2 +- .../oauth/ClientTokenExchangeTest.java | 22 +- .../testsuite/oauth/OAuthGrantTest.java | 2 +- .../oauth/OIDCProtocolMappersTest.java | 106 ++-- .../keycloak/testsuite/oidc/AudienceTest.java | 10 +- .../oidc/LightWeightAccessTokenTest.java | 472 ++++++++++++++++++ .../script/DeployedScriptMapperTest.java | 2 +- ...ndeployedScriptMapperNotAvailableTest.java | 2 +- .../testsuite/util/ProtocolMapperUtil.java | 43 +- 50 files changed, 1091 insertions(+), 304 deletions(-) create mode 100644 services/src/main/java/org/keycloak/protocol/oidc/mappers/TokenIntrospectionTokenMapper.java create mode 100644 services/src/main/java/org/keycloak/services/util/UserSessionUtil.java create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/LightWeightAccessTokenTest.java diff --git a/core/src/main/java/org/keycloak/representations/JsonWebToken.java b/core/src/main/java/org/keycloak/representations/JsonWebToken.java index f2d1a9765a92..0ed565171fdf 100755 --- a/core/src/main/java/org/keycloak/representations/JsonWebToken.java +++ b/core/src/main/java/org/keycloak/representations/JsonWebToken.java @@ -40,6 +40,9 @@ * @version $Revision: 1 $ */ public class JsonWebToken implements Serializable, Token { + public static final String AZP = "azp"; + public static final String SUBJECT = "sub"; + @JsonProperty("jti") protected String id; @@ -53,11 +56,11 @@ public class JsonWebToken implements Serializable, Token { @JsonSerialize(using = StringOrArraySerializer.class) @JsonDeserialize(using = StringOrArrayDeserializer.class) protected String[] audience; - @JsonProperty("sub") + @JsonProperty(SUBJECT) protected String subject; @JsonProperty("typ") protected String type; - @JsonProperty("azp") + @JsonProperty(AZP) public String issuedFor; protected Map otherClaims = new HashMap<>(); @@ -184,7 +187,7 @@ public JsonWebToken iat(Long iat) { this.iat = iat; return this; } - + /** * @deprecated int will overflow with values after 2038. Use {@link #iat(Long)} ()} instead. */ diff --git a/js/apps/admin-ui/public/locales/en/translation.json b/js/apps/admin-ui/public/locales/en/translation.json index e67335ae0e91..e8438a545c99 100644 --- a/js/apps/admin-ui/public/locales/en/translation.json +++ b/js/apps/admin-ui/public/locales/en/translation.json @@ -3096,6 +3096,10 @@ "label": "Add to userinfo", "tooltip": "Should the claim be added to the userinfo?" }, + "includeInIntrospection": { + "label": "Add to token introspection", + "tooltip": "Should the claim be added to the token introspection?" + }, "sectorIdentifierUri": { "label": "Sector Identifier URI", "tooltip": "Providers that use pairwise sub values and support Dynamic Client Registration SHOULD use the sector_identifier_uri parameter. It provides a way for a group of websites under common administrative control to have consistent pairwise sub values independent of the individual domain names. It also provides a way for Clients to change redirect_uri domains without having to reregister all their users." diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/UserSessionAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/UserSessionAdapter.java index ae314e1d7ce9..e06408b91fe1 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/UserSessionAdapter.java +++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/UserSessionAdapter.java @@ -315,6 +315,7 @@ public void runUpdate(UserSessionEntity entity) { update(task); } + @Override public SessionPersistenceState getPersistenceState() { return persistenceState; } diff --git a/model/legacy-private/src/main/java/org/keycloak/models/session/PersistentUserSessionAdapter.java b/model/legacy-private/src/main/java/org/keycloak/models/session/PersistentUserSessionAdapter.java index da5cb96bd64f..2b782c60b378 100644 --- a/model/legacy-private/src/main/java/org/keycloak/models/session/PersistentUserSessionAdapter.java +++ b/model/legacy-private/src/main/java/org/keycloak/models/session/PersistentUserSessionAdapter.java @@ -232,6 +232,11 @@ public State getState() { return State.valueOf(state); } + @Override + public SessionPersistenceState getPersistenceState() { + return SessionPersistenceState.PERSISTENT; + } + @Override public void setState(State state) { String stateStr = state==null ? null : state.toString(); diff --git a/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionAdapter.java b/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionAdapter.java index a7595e32b6c8..5087347208b2 100644 --- a/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionAdapter.java +++ b/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionAdapter.java @@ -23,7 +23,6 @@ import org.keycloak.models.ModelIllegalStateException; import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; - import org.keycloak.models.UserSessionModel; import org.keycloak.models.map.common.TimeAdapter; @@ -289,4 +288,9 @@ public boolean equals(Object o) { public int hashCode() { return getId().hashCode(); } + + @Override + public SessionPersistenceState getPersistenceState() { + return entity.getPersistenceState(); + } } diff --git a/server-spi/src/main/java/org/keycloak/models/UserSessionModel.java b/server-spi/src/main/java/org/keycloak/models/UserSessionModel.java index 121b10e078fd..aba486ec3b14 100755 --- a/server-spi/src/main/java/org/keycloak/models/UserSessionModel.java +++ b/server-spi/src/main/java/org/keycloak/models/UserSessionModel.java @@ -83,7 +83,7 @@ class SearchableFields { /** * Returns map where key is ID of the client (its UUID) and value is ID respective {@link AuthenticatedClientSessionModel} object. - * @return + * @return */ Map getAuthenticatedClientSessions(); /** @@ -135,6 +135,8 @@ public static State valueOfInteger(Integer id) { } } + SessionPersistenceState getPersistenceState(); + /** * Flag used when creating user session */ diff --git a/services/src/main/java/org/keycloak/protocol/oidc/AccessTokenIntrospectionProvider.java b/services/src/main/java/org/keycloak/protocol/oidc/AccessTokenIntrospectionProvider.java index 20d52050697b..7b2c5d44f68a 100644 --- a/services/src/main/java/org/keycloak/protocol/oidc/AccessTokenIntrospectionProvider.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/AccessTokenIntrospectionProvider.java @@ -24,6 +24,12 @@ import org.keycloak.common.VerificationException; import org.keycloak.crypto.SignatureProvider; import org.keycloak.crypto.SignatureVerifierContext; +import org.keycloak.events.Details; +import org.keycloak.events.EventBuilder; +import org.keycloak.events.EventType; +import org.keycloak.models.AuthenticatedClientSessionModel; +import org.keycloak.models.ClientModel; +import org.keycloak.models.ClientSessionContext; import org.keycloak.models.ImpersonationSessionNote; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; @@ -31,6 +37,8 @@ import org.keycloak.models.UserSessionModel; import org.keycloak.representations.AccessToken; import org.keycloak.services.Urls; +import org.keycloak.services.util.DefaultClientSessionContext; +import org.keycloak.services.util.UserSessionUtil; import org.keycloak.util.JsonSerialization; import jakarta.ws.rs.core.MediaType; @@ -55,6 +63,7 @@ public AccessTokenIntrospectionProvider(KeycloakSession session) { public Response introspect(String token) { try { AccessToken accessToken = verifyAccessToken(token); + accessToken = transformAccessToken(accessToken); ObjectNode tokenMetadata; if (accessToken != null) { @@ -106,6 +115,57 @@ public Response introspect(String token) { } } + private AccessToken transformAccessToken(AccessToken token) { + if (token == null) { + return null; + } + + ClientModel client = realm.getClientByClientId(token.getIssuedFor()); + EventBuilder event = new EventBuilder(realm, session, session.getContext().getConnection()) + .event(EventType.INTROSPECT_TOKEN) + .detail(Details.AUTH_METHOD, Details.VALIDATE_ACCESS_TOKEN); + UserSessionModel userSession; + try { + userSession = UserSessionUtil.findValidSession(session, realm, token, event, client); + } catch (Exception e) { + logger.debugf("Can not get user session: %s", e.getMessage()); + // Backwards compatibility + return token; + } + if (userSession.getUser() == null) { + logger.debugf("User not found"); + // Backwards compatibility + return token; + } + AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(client.getId()); + ClientSessionContext clientSessionCtx = DefaultClientSessionContext.fromClientSessionScopeParameter(clientSession, session); + AccessToken smallToken = getAccessTokenFromStoredData(token, userSession); + return tokenManager.transformIntrospectionAccessToken(session, smallToken, userSession, clientSessionCtx); + } + + private AccessToken getAccessTokenFromStoredData(AccessToken token, UserSessionModel userSession) { + // Copy just "basic" claims from the initial token. The same like filled in TokenManager.initToken. The rest should be possibly added by protocol mappers (only if configured for introspection response) + AccessToken newToken = new AccessToken(); + newToken.id(token.getId()); + newToken.type(token.getType()); + newToken.subject(token.getSubject() != null ? token.getSubject() : userSession.getUser().getId()); + newToken.iat(token.getIat()); + newToken.exp(token.getExp()); + newToken.issuedFor(token.getIssuedFor()); + newToken.issuer(token.getIssuer()); + newToken.setNonce(token.getNonce()); + newToken.setScope(token.getScope()); + newToken.setAuth_time(token.getAuth_time()); + newToken.setSessionState(token.getSessionState()); + + // In the case of a refresh token, aud is a basic claim. + newToken.audience(token.getAudience()); + + // The cnf is not a claim controlled by the protocol mapper. + newToken.setConfirmation(token.getConfirmation()); + return newToken; + } + protected AccessToken verifyAccessToken(String token) { AccessToken accessToken; diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java index c9bf0c46afad..3a5f57221330 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java @@ -133,29 +133,29 @@ public Map getBuiltinMappers() { private Map builtins = new HashMap<>(); void initBuiltIns() { - ProtocolMapperModel model; + ProtocolMapperModel model; model = UserAttributeMapper.createClaimMapper(USERNAME, "username", "preferred_username", String.class.getSimpleName(), - true, true); + true, true, true); builtins.put(USERNAME, model); model = UserAttributeMapper.createClaimMapper(EMAIL, "email", "email", "String", - true, true); + true, true, true); builtins.put(EMAIL, model); model = UserAttributeMapper.createClaimMapper(GIVEN_NAME, "firstName", "given_name", "String", - true, true); + true, true, true); builtins.put(GIVEN_NAME, model); model = UserAttributeMapper.createClaimMapper(FAMILY_NAME, "lastName", "family_name", "String", - true, true); + true, true, true); builtins.put(FAMILY_NAME, model); createUserAttributeMapper(MIDDLE_NAME, "middleName", IDToken.MIDDLE_NAME, "String"); @@ -175,10 +175,10 @@ void initBuiltIns() { model = UserPropertyMapper.createClaimMapper(EMAIL_VERIFIED, "emailVerified", "email_verified", "boolean", - true, true); + true, true, true); builtins.put(EMAIL_VERIFIED, model); - ProtocolMapperModel fullName = FullNameMapper.create(FULL_NAME, true, true, true); + ProtocolMapperModel fullName = FullNameMapper.create(FULL_NAME, true, true, true, true); builtins.put(FULL_NAME, fullName); ProtocolMapperModel address = AddressMapper.createAddressMapper(); @@ -187,19 +187,19 @@ void initBuiltIns() { model = UserSessionNoteMapper.createClaimMapper(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME, KerberosConstants.GSS_DELEGATION_CREDENTIAL, KerberosConstants.GSS_DELEGATION_CREDENTIAL, "String", - true, false); + true, false, true); builtins.put(KerberosConstants.GSS_DELEGATION_CREDENTIAL, model); - model = UserRealmRoleMappingMapper.create(null, REALM_ROLES, "realm_access.roles", true, false, true); + model = UserRealmRoleMappingMapper.create(null, REALM_ROLES, "realm_access.roles", true, false, true, true); builtins.put(REALM_ROLES, model); - model = UserClientRoleMappingMapper.create(null, null, CLIENT_ROLES, "resource_access.${client_id}.roles", true, false, true); + model = UserClientRoleMappingMapper.create(null, null, CLIENT_ROLES, "resource_access.${client_id}.roles", true, false, true, true); builtins.put(CLIENT_ROLES, model); - model = AudienceResolveProtocolMapper.createClaimMapper(AUDIENCE_RESOLVE); + model = AudienceResolveProtocolMapper.createClaimMapper(AUDIENCE_RESOLVE, true, true); builtins.put(AUDIENCE_RESOLVE, model); - model = AllowedWebOriginsProtocolMapper.createClaimMapper(ALLOWED_WEB_ORIGINS); + model = AllowedWebOriginsProtocolMapper.createClaimMapper(ALLOWED_WEB_ORIGINS, true, true); builtins.put(ALLOWED_WEB_ORIGINS, model); builtins.put(IMPERSONATOR_ID.getDisplayName(), UserSessionNoteMapper.createUserSessionNoteMapper(IMPERSONATOR_ID)); @@ -207,14 +207,14 @@ void initBuiltIns() { model = UserAttributeMapper.createClaimMapper(UPN, "username", "upn", "String", - true, true); + true, true, true); builtins.put(UPN, model); - model = UserRealmRoleMappingMapper.create(null, GROUPS, GROUPS, true, true, true); + model = UserRealmRoleMappingMapper.create(null, GROUPS, GROUPS, true, true, true, true); builtins.put(GROUPS, model); if (Profile.isFeatureEnabled(Profile.Feature.STEP_UP_AUTHENTICATION)) { - model = AcrProtocolMapper.create(ACR, true, true); + model = AcrProtocolMapper.create(ACR, true, true, true); builtins.put(ACR, model); } } @@ -223,7 +223,7 @@ private void createUserAttributeMapper(String name, String attrName, String clai ProtocolMapperModel model = UserAttributeMapper.createClaimMapper(name, attrName, claimName, type, - true, true, false); + true, true, true, false); builtins.put(name, model); } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java index 460624ad5076..203c888b3f0c 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java @@ -61,6 +61,7 @@ import org.keycloak.models.utils.RoleUtils; import org.keycloak.protocol.ProtocolMapper; import org.keycloak.protocol.ProtocolMapperUtils; +import org.keycloak.protocol.oidc.mappers.TokenIntrospectionTokenMapper; import org.keycloak.protocol.oidc.mappers.OIDCAccessTokenMapper; import org.keycloak.protocol.oidc.mappers.OIDCAccessTokenResponseMapper; import org.keycloak.protocol.oidc.mappers.OIDCIDTokenMapper; @@ -785,6 +786,17 @@ protected AccessToken applyMapper(AccessToken token, Map.Entry mapper.getValue() instanceof TokenIntrospectionTokenMapper) + .collect(new TokenCollector(token) { + @Override + protected AccessToken applyMapper(AccessToken token, Map.Entry mapper) { + return ((TokenIntrospectionTokenMapper) mapper.getValue()).transformIntrospectionToken(token, mapper.getKey(), session, userSession, clientSessionCtx); + } + }); + } + public Map generateUserInfoClaims(AccessToken userInfo, UserModel userModel) { Map claims = new HashMap<>(); claims.put("sub", userInfo.getSubject() == null? userModel.getId() : userInfo.getSubject()); diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java index 48ee7493f168..3762e1e16ee0 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/UserInfoEndpoint.java @@ -24,7 +24,6 @@ import org.keycloak.common.ClientConnection; import org.keycloak.common.Profile; import org.keycloak.common.VerificationException; -import org.keycloak.common.constants.ServiceAccountConstants; import org.keycloak.crypto.ContentEncryptionProvider; import org.keycloak.crypto.CekManagementProvider; import org.keycloak.crypto.KeyWrapper; @@ -48,7 +47,6 @@ import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserSessionModel; -import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.protocol.oidc.TokenManager; @@ -59,15 +57,11 @@ import org.keycloak.services.clientpolicy.ClientPolicyException; import org.keycloak.services.clientpolicy.context.UserInfoRequestContext; import org.keycloak.services.managers.AppAuthManager; -import org.keycloak.services.managers.AuthenticationManager; -import org.keycloak.services.managers.UserSessionCrossDCManager; -import org.keycloak.services.managers.UserSessionManager; import org.keycloak.services.resources.Cors; import org.keycloak.services.util.DPoPUtil; import org.keycloak.services.util.DefaultClientSessionContext; import org.keycloak.services.util.MtlsHoKTokenUtil; -import org.keycloak.sessions.AuthenticationSessionModel; -import org.keycloak.sessions.RootAuthenticationSessionModel; +import org.keycloak.services.util.UserSessionUtil; import org.keycloak.util.JsonSerialization; import org.keycloak.util.TokenUtil; import org.keycloak.utils.MediaType; @@ -145,15 +139,15 @@ public Response issueUserInfoPost() { authorization(accessToken); try { - + String contentType = headers.getHeaderString(HttpHeaders.CONTENT_TYPE); jakarta.ws.rs.core.MediaType mediaType = jakarta.ws.rs.core.MediaType.valueOf(contentType); - + if (jakarta.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED_TYPE.isCompatible(mediaType)) { MultivaluedMap formParams = request.getDecodedFormParameters(); checkAccessTokenDuplicated(formParams); accessToken = formParams.getFirst(OAuth2Constants.ACCESS_TOKEN); - authorization(accessToken); + authorization(accessToken); } } catch (IllegalArgumentException e) { // not application/x-www-form-urlencoded, ignore @@ -229,7 +223,7 @@ private Response issueUserInfo() { throw error.invalidToken("Client disabled"); } - UserSessionModel userSession = findValidSession(token, event, clientModel); + UserSessionModel userSession = UserSessionUtil.findValidSession(session, realm, token, event, clientModel); UserModel userModel = userSession.getUser(); if (userModel == null) { @@ -350,73 +344,6 @@ private String jweFromContent(String content, String jweContentType) { return encryptedToken; } - private UserSessionModel createTransientSessionForClient(AccessToken token, ClientModel client) { - // create a transient session - UserModel user = TokenManager.lookupUserFromStatelessToken(session, realm, token); - if (user == null) { - throw error.invalidToken("User not found"); - } - UserSessionModel userSession = new UserSessionManager(session).createUserSession(KeycloakModelUtils.generateId(), realm, user, user.getUsername(), clientConnection.getRemoteAddr(), - ServiceAccountConstants.CLIENT_AUTH, false, null, null, UserSessionModel.SessionPersistenceState.TRANSIENT); - // attach an auth session for the client - RootAuthenticationSessionModel rootAuthSession = session.authenticationSessions().createRootAuthenticationSession(realm); - AuthenticationSessionModel authSession = rootAuthSession.createAuthenticationSession(client); - authSession.setAuthenticatedUser(userSession.getUser()); - authSession.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL); - authSession.setClientNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(session.getContext().getUri().getBaseUri(), realm.getName())); - AuthenticationManager.setClientScopesInSession(authSession); - TokenManager.attachAuthenticationSession(session, userSession, authSession); - return userSession; - } - - private UserSessionModel findValidSession(AccessToken token, EventBuilder event, ClientModel client) { - if (token.getSessionState() == null) { - return createTransientSessionForClient(token, client); - } - - UserSessionModel userSession = new UserSessionCrossDCManager(session).getUserSessionWithClient(realm, token.getSessionState(), false, client.getId()); - UserSessionModel offlineUserSession = null; - if (AuthenticationManager.isSessionValid(realm, userSession)) { - checkTokenIssuedAt(token, userSession, event, client); - event.session(userSession); - return userSession; - } else { - offlineUserSession = new UserSessionCrossDCManager(session).getUserSessionWithClient(realm, token.getSessionState(), true, client.getId()); - if (AuthenticationManager.isOfflineSessionValid(realm, offlineUserSession)) { - checkTokenIssuedAt(token, offlineUserSession, event, client); - event.session(offlineUserSession); - return offlineUserSession; - } - } - - if (userSession == null && offlineUserSession == null) { - event.error(Errors.USER_SESSION_NOT_FOUND); - throw error.invalidToken("User session not found or doesn't have client attached on it"); - } - - if (userSession != null) { - event.session(userSession); - } else { - event.session(offlineUserSession); - } - - event.error(Errors.SESSION_EXPIRED); - throw error.invalidToken("Session expired"); - } - - private void checkTokenIssuedAt(AccessToken token, UserSessionModel userSession, EventBuilder event, ClientModel client) { - if (token.isIssuedBeforeSessionStart(userSession.getStarted())) { - event.error(Errors.INVALID_TOKEN); - throw error.invalidToken("Stale token"); - } - - AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(client.getId()); - if (token.isIssuedBeforeSessionStart(clientSession.getStarted())) { - event.error(Errors.INVALID_TOKEN); - throw error.invalidToken("Stale token"); - } - } - private void checkAccessTokenDuplicated(MultivaluedMap formParams) { // If access_token is not provided, error is thrown in issueUserInfo(). // Only checks duplication of access token parameter in this function. diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AbstractOIDCProtocolMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AbstractOIDCProtocolMapper.java index 0ca3af4f2f1a..42f4e32f7f2a 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AbstractOIDCProtocolMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AbstractOIDCProtocolMapper.java @@ -106,6 +106,17 @@ public AccessTokenResponse transformAccessTokenResponse(AccessTokenResponse acce return accessTokenResponse; } + public AccessToken transformIntrospectionToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session, + UserSessionModel userSession, ClientSessionContext clientSessionCtx) { + + if (!OIDCAttributeMapperHelper.includeInIntrospection(mappingModel)){ + return token; + } + + setClaim(token, mappingModel, userSession, session, clientSessionCtx); + return token; + } + /** * Intended to be overridden in {@link ProtocolMapper} implementations to add claims to an token. * @param token diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AbstractPairwiseSubMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AbstractPairwiseSubMapper.java index ef3b9bdcf1e8..fd9389644b55 100644 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AbstractPairwiseSubMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AbstractPairwiseSubMapper.java @@ -14,6 +14,7 @@ import org.keycloak.representations.AccessToken; import org.keycloak.representations.IDToken; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -22,7 +23,7 @@ * * @author Martin Hardselius */ -public abstract class AbstractPairwiseSubMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper { +public abstract class AbstractPairwiseSubMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper, TokenIntrospectionTokenMapper { public static final String PROVIDER_ID_SUFFIX = "-pairwise-sub-mapper"; public abstract String getIdPrefix(); @@ -75,6 +76,12 @@ public AccessToken transformAccessToken(AccessToken token, ProtocolMapperModel m return token; } + @Override + public AccessToken transformIntrospectionToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session, UserSessionModel userSession, ClientSessionContext clientSessionCtx) { + setAccessTokenSubject(token, generateSub(mappingModel, getSectorIdentifier(clientSessionCtx.getClientSession().getClient(), mappingModel), userSession.getUser().getId())); + return token; + } + @Override public AccessToken transformUserInfoToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session, UserSessionModel userSession, ClientSessionContext clientSessionCtx) { setUserInfoTokenSubject(token, generateSub(mappingModel, getSectorIdentifier(clientSessionCtx.getClientSession().getClient(), mappingModel), userSession.getUser().getId())); diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AbstractUserRoleMappingMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AbstractUserRoleMappingMapper.java index 831804baa627..2f371513917e 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AbstractUserRoleMappingMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AbstractUserRoleMappingMapper.java @@ -38,7 +38,7 @@ * * @author Thomas Darimont */ -abstract class AbstractUserRoleMappingMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper { +abstract class AbstractUserRoleMappingMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper, TokenIntrospectionTokenMapper { @Override public int getPriority() { diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AcrProtocolMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AcrProtocolMapper.java index 3da2a5823d88..1b02130546cc 100644 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AcrProtocolMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AcrProtocolMapper.java @@ -42,7 +42,7 @@ /** * @author Marek Posolda */ -public class AcrProtocolMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, EnvironmentDependentProviderFactory { +public class AcrProtocolMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, TokenIntrospectionTokenMapper, EnvironmentDependentProviderFactory { private static final Logger logger = Logger.getLogger(AcrProtocolMapper.class); @@ -87,7 +87,7 @@ protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSes token.setAcr(acr); } - public static ProtocolMapperModel create(String name, boolean accessToken, boolean idToken) { + public static ProtocolMapperModel create(String name, boolean accessToken, boolean idToken, boolean introspectionEndpoint) { ProtocolMapperModel mapper = new ProtocolMapperModel(); mapper.setName(name); mapper.setProtocolMapper(PROVIDER_ID); @@ -95,6 +95,7 @@ public static ProtocolMapperModel create(String name, boolean accessToken, boole Map config = new HashMap<>(); if (accessToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true"); if (idToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true"); + if (introspectionEndpoint) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_INTROSPECTION, "true"); mapper.setConfig(config); return mapper; } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AddressMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AddressMapper.java index 9d61b81ff348..a35a9360cfc7 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AddressMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AddressMapper.java @@ -35,7 +35,7 @@ * @author Bill Burke * @version $Revision: 1 $ */ -public class AddressMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper { +public class AddressMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper, TokenIntrospectionTokenMapper { private static final List configProperties = new ArrayList(); @@ -69,10 +69,10 @@ public static String getModelPropertyName(String claimName) { public static final String PROVIDER_ID = "oidc-address-mapper"; public static ProtocolMapperModel createAddressMapper() { - return createAddressMapper(true, true, true); + return createAddressMapper(true, true, true, true); } - public static ProtocolMapperModel createAddressMapper(boolean idToken, boolean accessToken, boolean userInfo) { + public static ProtocolMapperModel createAddressMapper(boolean idToken, boolean accessToken, boolean userInfo, boolean introspectionEndpoint) { Map config; ProtocolMapperModel address = new ProtocolMapperModel(); address.setName("address"); @@ -82,6 +82,7 @@ public static ProtocolMapperModel createAddressMapper(boolean idToken, boolean a config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, Boolean.toString(accessToken)); config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, Boolean.toString(idToken)); config.put(OIDCAttributeMapperHelper.INCLUDE_IN_USERINFO, Boolean.toString(userInfo)); + config.put(OIDCAttributeMapperHelper.INCLUDE_IN_INTROSPECTION, Boolean.toString(introspectionEndpoint)); config.put(getModelPropertyName(STREET), STREET); config.put(getModelPropertyName(AddressClaimSet.LOCALITY), AddressClaimSet.LOCALITY); diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AllowedWebOriginsProtocolMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AllowedWebOriginsProtocolMapper.java index 2ffe70cc6d59..5d8a7d40b481 100644 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AllowedWebOriginsProtocolMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AllowedWebOriginsProtocolMapper.java @@ -19,7 +19,9 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; import org.keycloak.models.ClientModel; @@ -32,18 +34,24 @@ import org.keycloak.provider.ProviderConfigProperty; import org.keycloak.representations.AccessToken; +import static org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN; +import static org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper.INCLUDE_IN_INTROSPECTION; + /** * Protocol mapper to add allowed web origins to the access token to the 'allowed-origins' claim * * @author Marek Posolda */ -public class AllowedWebOriginsProtocolMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper { +public class AllowedWebOriginsProtocolMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, TokenIntrospectionTokenMapper { private static final List configProperties = new ArrayList(); public static final String PROVIDER_ID = "oidc-allowed-origins-mapper"; + static { + OIDCAttributeMapperHelper.addIncludeInTokensConfig(configProperties, AllowedWebOriginsProtocolMapper.class); + } public List getConfigProperties() { return configProperties; @@ -72,23 +80,72 @@ public String getHelpText() { @Override public AccessToken transformAccessToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session, UserSessionModel userSession, ClientSessionContext clientSessionCtx) { + + if (!includeInAccessToken(mappingModel)){ + return token; + } + setWebOrigin(token, session, clientSessionCtx); + return token; + } + + private boolean includeInAccessToken(ProtocolMapperModel mappingModel) { + String includeInAccessToken = mappingModel.getConfig().get(INCLUDE_IN_ACCESS_TOKEN); + + // Backwards compatibility + if (includeInAccessToken == null) { + return true; + } + + return "true".equals(includeInAccessToken); + } + + @Override + public AccessToken transformIntrospectionToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session, + UserSessionModel userSession, ClientSessionContext clientSessionCtx) { + if (!includeInIntrospection(mappingModel)) { + return token; + } + setWebOrigin(token, session, clientSessionCtx); + return token; + } + + private boolean includeInIntrospection(ProtocolMapperModel mappingModel) { + String includeInIntrospection = mappingModel.getConfig().get(INCLUDE_IN_INTROSPECTION); + + // Backwards compatibility + if (includeInIntrospection == null) { + return true; + } + + return "true".equals(includeInIntrospection); + } + + private void setWebOrigin(AccessToken token, KeycloakSession session, ClientSessionContext clientSessionCtx) { ClientModel client = clientSessionCtx.getClientSession().getClient(); Set allowedOrigins = client.getWebOrigins(); if (allowedOrigins != null && !allowedOrigins.isEmpty()) { token.setAllowedOrigins(WebOriginsUtils.resolveValidWebOrigins(session, client)); } - - return token; } - - public static ProtocolMapperModel createClaimMapper(String name) { + public static ProtocolMapperModel createClaimMapper(String name, boolean accessToken, boolean introspectionEndpoint) { ProtocolMapperModel mapper = new ProtocolMapperModel(); mapper.setName(name); mapper.setProtocolMapper(PROVIDER_ID); mapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL); - mapper.setConfig(Collections.emptyMap()); + Map config = new HashMap<>(); + if (accessToken) { + config.put(INCLUDE_IN_ACCESS_TOKEN, "true"); + } else { + config.put(INCLUDE_IN_ACCESS_TOKEN, "false"); + } + if (introspectionEndpoint) { + config.put(INCLUDE_IN_INTROSPECTION, "true"); + } else { + config.put(INCLUDE_IN_INTROSPECTION, "false"); + } + mapper.setConfig(config); return mapper; } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AudienceProtocolMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AudienceProtocolMapper.java index 80914bcecfeb..c65e321cf381 100644 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AudienceProtocolMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AudienceProtocolMapper.java @@ -33,7 +33,7 @@ /** * @author Marek Posolda */ -public class AudienceProtocolMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper { +public class AudienceProtocolMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, TokenIntrospectionTokenMapper { private static final List configProperties = new ArrayList<>(); @@ -115,7 +115,7 @@ protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSes public static ProtocolMapperModel createClaimMapper(String name, String includedClientAudience, String includedCustomAudience, - boolean accessToken, boolean idToken) { + boolean accessToken, boolean idToken, boolean introspectionEndpoint) { ProtocolMapperModel mapper = new ProtocolMapperModel(); mapper.setName(name); mapper.setProtocolMapper(PROVIDER_ID); @@ -131,6 +131,7 @@ public static ProtocolMapperModel createClaimMapper(String name, if (accessToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true"); if (idToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true"); + if (introspectionEndpoint) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_INTROSPECTION, "true"); mapper.setConfig(config); return mapper; } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AudienceResolveProtocolMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AudienceResolveProtocolMapper.java index b1e1b861bc9f..f7cd53051cb8 100644 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/AudienceResolveProtocolMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/AudienceResolveProtocolMapper.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -32,16 +33,21 @@ import org.keycloak.representations.AccessToken; import org.keycloak.utils.RoleResolveUtil; +import static org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN; +import static org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper.INCLUDE_IN_INTROSPECTION; + /** * Protocol mapper, which adds all client_ids of "allowed" clients to the audience field of the token. Allowed client means the client * for which user has at least one client role * * @author Marek Posolda */ -public class AudienceResolveProtocolMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper { +public class AudienceResolveProtocolMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, TokenIntrospectionTokenMapper { private static final List configProperties = new ArrayList(); - + static { + OIDCAttributeMapperHelper.addIncludeInTokensConfig(configProperties, AudienceResolveProtocolMapper.class); + } public static final String PROVIDER_ID = "oidc-audience-resolve-mapper"; @@ -79,6 +85,46 @@ public int getPriority() { @Override public AccessToken transformAccessToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session, UserSessionModel userSession, ClientSessionContext clientSessionCtx) { + if (!includeInAccessToken(mappingModel)){ + return token; + } + setAudience(token, clientSessionCtx, session); + return token; + } + + private boolean includeInAccessToken(ProtocolMapperModel mappingModel) { + String includeInAccessToken = mappingModel.getConfig().get(INCLUDE_IN_ACCESS_TOKEN); + + // Backwards compatibility + if (includeInAccessToken == null) { + return true; + } + + return "true".equals(includeInAccessToken); + } + + @Override + public AccessToken transformIntrospectionToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session, + UserSessionModel userSession, ClientSessionContext clientSessionCtx) { + if (!includeInIntrospection(mappingModel)) { + return token; + } + setAudience(token, clientSessionCtx, session); + return token; + } + + private boolean includeInIntrospection(ProtocolMapperModel mappingModel) { + String includeInIntrospection = mappingModel.getConfig().get(INCLUDE_IN_INTROSPECTION); + + // Backwards compatibility + if (includeInIntrospection == null) { + return true; + } + + return "true".equals(includeInIntrospection); + } + + private void setAudience(AccessToken token, ClientSessionContext clientSessionCtx, KeycloakSession session) { String clientId = clientSessionCtx.getClientSession().getClient().getClientId(); for (Map.Entry entry : RoleResolveUtil.getAllResolvedClientRoles(session, clientSessionCtx).entrySet()) { @@ -92,16 +138,25 @@ public AccessToken transformAccessToken(AccessToken token, ProtocolMapperModel m token.addAudience(entry.getKey()); } } - - return token; } - public static ProtocolMapperModel createClaimMapper(String name) { + public static ProtocolMapperModel createClaimMapper(String name, boolean accessToken, boolean introspectionEndpoint) { ProtocolMapperModel mapper = new ProtocolMapperModel(); mapper.setName(name); mapper.setProtocolMapper(PROVIDER_ID); mapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL); - mapper.setConfig(Collections.emptyMap()); + Map config = new HashMap<>(); + if (accessToken) { + config.put(INCLUDE_IN_ACCESS_TOKEN, "true"); + } else { + config.put(INCLUDE_IN_ACCESS_TOKEN, "false"); + } + if (introspectionEndpoint) { + config.put(INCLUDE_IN_INTROSPECTION, "true"); + } else { + config.put(INCLUDE_IN_INTROSPECTION, "false"); + } + mapper.setConfig(config); return mapper; } } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/ClaimsParameterTokenMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/ClaimsParameterTokenMapper.java index a65ca1ff2857..45a557b5951d 100644 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/ClaimsParameterTokenMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/ClaimsParameterTokenMapper.java @@ -110,16 +110,16 @@ private void putClaims(String tokenType, String claims, IDToken token, ProtocolM fullNameMapper.setClaim(token, mappingModel, userSession); } else if (i.equals(IDToken.GIVEN_NAME)) { UserAttributeMapper userPropertyMapper = new UserAttributeMapper(); - userPropertyMapper.setClaim(token, UserAttributeMapper.createClaimMapper("requested firstName", "firstName", IDToken.GIVEN_NAME, "String", false, true), userSession); + userPropertyMapper.setClaim(token, UserAttributeMapper.createClaimMapper("requested firstName", "firstName", IDToken.GIVEN_NAME, "String", false, true, false), userSession); } else if (i.equals(IDToken.FAMILY_NAME)) { UserAttributeMapper userPropertyMapper = new UserAttributeMapper(); - userPropertyMapper.setClaim(token, UserAttributeMapper.createClaimMapper("requested lastName", "lastName", IDToken.FAMILY_NAME, "String", false, true), userSession); + userPropertyMapper.setClaim(token, UserAttributeMapper.createClaimMapper("requested lastName", "lastName", IDToken.FAMILY_NAME, "String", false, true, false), userSession); } else if (i.equals(IDToken.PREFERRED_USERNAME)) { UserAttributeMapper userPropertyMapper = new UserAttributeMapper(); - userPropertyMapper.setClaim(token, UserAttributeMapper.createClaimMapper("requested username", "username", IDToken.PREFERRED_USERNAME, "String", false, true), userSession); + userPropertyMapper.setClaim(token, UserAttributeMapper.createClaimMapper("requested username", "username", IDToken.PREFERRED_USERNAME, "String", false, true, false), userSession); } else if (i.equals(IDToken.EMAIL)) { UserAttributeMapper userPropertyMapper = new UserAttributeMapper(); - userPropertyMapper.setClaim(token, UserAttributeMapper.createClaimMapper("requested email", "email", IDToken.EMAIL, "String", false, true), userSession); + userPropertyMapper.setClaim(token, UserAttributeMapper.createClaimMapper("requested email", "email", IDToken.EMAIL, "String", false, true, false), userSession); } }); } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/ClaimsParameterWithValueIdTokenMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/ClaimsParameterWithValueIdTokenMapper.java index fa07c5ab6e01..92f6d3c9af0b 100644 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/ClaimsParameterWithValueIdTokenMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/ClaimsParameterWithValueIdTokenMapper.java @@ -123,7 +123,7 @@ private void putClaims(ClaimsRepresentation.ClaimContext tokenType, String claim } HardcodedClaim hardcodedClaimMapper = new HardcodedClaim(); - hardcodedClaimMapper.setClaim(token, HardcodedClaim.create("hard", claimName, claim, "String", false, true), userSession); + hardcodedClaimMapper.setClaim(token, HardcodedClaim.create("hard", claimName, claim, "String", false, true, false), userSession); } public static ProtocolMapperModel createMapper(String name, String attributeValue, boolean idToken) { diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/FullNameMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/FullNameMapper.java index 13dccc5114f1..3f3e73c83ef3 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/FullNameMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/FullNameMapper.java @@ -37,7 +37,7 @@ * @author Bill Burke * @version $Revision: 1 $ */ -public class FullNameMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper { +public class FullNameMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper, TokenIntrospectionTokenMapper { private static final List configProperties = new ArrayList<>(); @@ -83,7 +83,7 @@ protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSes } } - public static ProtocolMapperModel create(String name, boolean accessToken, boolean idToken, boolean userInfo) { + public static ProtocolMapperModel create(String name, boolean accessToken, boolean idToken, boolean userInfo, boolean introspectionEndpoint) { ProtocolMapperModel mapper = new ProtocolMapperModel(); mapper.setName(name); mapper.setProtocolMapper(PROVIDER_ID); @@ -92,6 +92,7 @@ public static ProtocolMapperModel create(String name, boolean accessToken, boole if (accessToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true"); if (idToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true"); if (userInfo) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_USERINFO, "true"); + if (introspectionEndpoint) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_INTROSPECTION, "true"); mapper.setConfig(config); return mapper; } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/GroupMembershipMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/GroupMembershipMapper.java index 685aed7ca331..27b718617111 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/GroupMembershipMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/GroupMembershipMapper.java @@ -39,7 +39,7 @@ * @author Bill Burke * @version $Revision: 1 $ */ -public class GroupMembershipMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper { +public class GroupMembershipMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper, TokenIntrospectionTokenMapper { private static final List configProperties = new ArrayList(); @@ -105,9 +105,9 @@ protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSes } public static ProtocolMapperModel create(String name, - String tokenClaimName, - boolean consentRequired, String consentText, - boolean accessToken, boolean idToken) { + String tokenClaimName, + boolean consentRequired, String consentText, + boolean accessToken, boolean idToken, boolean introspectionEndpoint) { ProtocolMapperModel mapper = new ProtocolMapperModel(); mapper.setName(name); mapper.setProtocolMapper(PROVIDER_ID); @@ -116,8 +116,9 @@ public static ProtocolMapperModel create(String name, config.put(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME, tokenClaimName); if (accessToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true"); if (idToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true"); + if (introspectionEndpoint) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_INTROSPECTION, "true"); mapper.setConfig(config); - + return mapper; } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/HardcodedClaim.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/HardcodedClaim.java index 707dc1f78e59..e36a4f2be1c6 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/HardcodedClaim.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/HardcodedClaim.java @@ -38,7 +38,7 @@ * @version $Revision: 1 $ */ public class HardcodedClaim extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper, - OIDCAccessTokenResponseMapper { + OIDCAccessTokenResponseMapper, TokenIntrospectionTokenMapper { private static final List configProperties = new ArrayList(); @@ -94,7 +94,7 @@ protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSes @Override protected void setClaim(AccessTokenResponse accessTokenResponse, ProtocolMapperModel mappingModel, UserSessionModel userSession, - KeycloakSession keycloakSession, ClientSessionContext clientSessionCtx) { + KeycloakSession keycloakSession, ClientSessionContext clientSessionCtx) { String attributeValue = mappingModel.getConfig().get(CLAIM_VALUE); if (attributeValue == null) return; @@ -102,9 +102,9 @@ protected void setClaim(AccessTokenResponse accessTokenResponse, ProtocolMapperM } public static ProtocolMapperModel create(String name, - String hardcodedName, - String hardcodedValue, String claimType, - boolean accessToken, boolean idToken) { + String hardcodedName, + String hardcodedValue, String claimType, + boolean accessToken, boolean idToken, boolean introspectionEndpoint) { ProtocolMapperModel mapper = new ProtocolMapperModel(); mapper.setName(name); mapper.setProtocolMapper(PROVIDER_ID); @@ -115,6 +115,7 @@ public static ProtocolMapperModel create(String name, config.put(OIDCAttributeMapperHelper.JSON_TYPE, claimType); if (accessToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true"); if (idToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true"); + if (introspectionEndpoint) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_INTROSPECTION, "true"); mapper.setConfig(config); return mapper; } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/HardcodedRole.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/HardcodedRole.java index 10762d497d32..7f1583900cb1 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/HardcodedRole.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/HardcodedRole.java @@ -40,7 +40,7 @@ * @author Bill Burke * @version $Revision: 1 $ */ -public class HardcodedRole extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, UserInfoTokenMapper { +public class HardcodedRole extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, UserInfoTokenMapper, TokenIntrospectionTokenMapper { private static final List configProperties = new ArrayList<>(); @@ -104,6 +104,14 @@ public AccessToken transformAccessToken(AccessToken token, ProtocolMapperModel m return token; } + @Override + public AccessToken transformIntrospectionToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session, + UserSessionModel userSession, ClientSessionContext clientSessionCtx) { + // the mapper is always executed and then other role mappers decide if the claims are really set to the token + setClaim(token, mappingModel, userSession, session, clientSessionCtx); + return token; + } + @Override protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession, KeycloakSession session, ClientSessionContext clientSessionCtx) { diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAttributeMapperHelper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAttributeMapperHelper.java index 2375e5e6edcf..c15037cc825c 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAttributeMapperHelper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/OIDCAttributeMapperHelper.java @@ -31,10 +31,17 @@ import org.keycloak.services.ServicesLogger; import org.keycloak.util.JsonSerialization; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; + /** * @author Bill Burke * @version $Revision: 1 $ @@ -60,6 +67,10 @@ public class OIDCAttributeMapperHelper { public static final String INCLUDE_IN_USERINFO_LABEL = "includeInUserInfo.label"; public static final String INCLUDE_IN_USERINFO_HELP_TEXT = "includeInUserInfo.tooltip"; + public static final String INCLUDE_IN_INTROSPECTION = "introspection.token.claim"; + public static final String INCLUDE_IN_INTROSPECTION_LABEL = "includeInIntrospection.label"; + public static final String INCLUDE_IN_INTROSPECTION_HELP_TEXT = "includeInIntrospection.tooltip"; + private static final Logger logger = Logger.getLogger(OIDCAttributeMapperHelper.class); /** @@ -230,7 +241,7 @@ private static Boolean getBoolean(Object attributeValue) { if (attributeValue instanceof String) return Boolean.valueOf((String) attributeValue); return null; } - + private static JsonNode getJsonNode(Object attributeValue) { if (attributeValue instanceof JsonNode){ return (JsonNode) attributeValue; @@ -259,7 +270,7 @@ public static void mapClaim(AccessTokenResponse token, ProtocolMapperModel mappi } private static void mapClaim(T token, ProtocolMapperModel mappingModel, Object attributeValue, - Map> setters, Map jsonObject) { + Map> setters, Map jsonObject) { attributeValue = mapAttributeValue(mappingModel, attributeValue); if (attributeValue == null) { return; @@ -317,16 +328,16 @@ private static void mapClaim(List split, Object attributeValue, Map configProperties, Class protocolMapperClass) { addTokenClaimNameConfig(configProperties); addJsonTypeConfig(configProperties); @@ -441,5 +464,15 @@ public static void addIncludeInTokensConfig(List configP property.setHelpText(INCLUDE_IN_ACCESS_TOKEN_RESPONSE_HELP_TEXT); configProperties.add(property); } + + if (TokenIntrospectionTokenMapper.class.isAssignableFrom(protocolMapperClass)) { + ProviderConfigProperty property = new ProviderConfigProperty(); + property.setName(INCLUDE_IN_INTROSPECTION); + property.setLabel(INCLUDE_IN_INTROSPECTION_LABEL); + property.setType(ProviderConfigProperty.BOOLEAN_TYPE); + property.setDefaultValue("true"); + property.setHelpText(INCLUDE_IN_INTROSPECTION_HELP_TEXT); + configProperties.add(property); + } } } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/RoleNameMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/RoleNameMapper.java index 4316d0ae322b..7cb40f888a0f 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/RoleNameMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/RoleNameMapper.java @@ -40,7 +40,7 @@ * @author Bill Burke * @version $Revision: 1 $ */ -public class RoleNameMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, UserInfoTokenMapper { +public class RoleNameMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, UserInfoTokenMapper, TokenIntrospectionTokenMapper { private static final List configProperties = new ArrayList<>(); @@ -111,6 +111,14 @@ public AccessToken transformAccessToken(AccessToken token, ProtocolMapperModel m return token; } + @Override + public AccessToken transformIntrospectionToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session, + UserSessionModel userSession, ClientSessionContext clientSessionCtx) { + // the mapper is always executed and then other role mappers decide if the claims are really set to the token + setClaim(token, mappingModel, userSession, session, clientSessionCtx); + return token; + } + @Override protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSessionModel userSession, KeycloakSession session, ClientSessionContext clientSessionCtx) { diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/ScriptBasedOIDCProtocolMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/ScriptBasedOIDCProtocolMapper.java index 47889a40867c..4ca24948641c 100644 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/ScriptBasedOIDCProtocolMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/ScriptBasedOIDCProtocolMapper.java @@ -46,7 +46,7 @@ * @author Thomas Darimont */ public class ScriptBasedOIDCProtocolMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper, - OIDCAccessTokenResponseMapper, EnvironmentDependentProviderFactory { + OIDCAccessTokenResponseMapper, TokenIntrospectionTokenMapper, EnvironmentDependentProviderFactory { public static final String PROVIDER_ID = "oidc-script-based-protocol-mapper"; @@ -197,14 +197,14 @@ protected String getScriptCode(ProtocolMapperModel mapperModel) { public static ProtocolMapperModel create(String name, String userAttribute, String tokenClaimName, String claimType, - boolean accessToken, boolean idToken, String script, boolean multiValued) { + boolean accessToken, boolean idToken, boolean introspectionEndpoint, String script, boolean multiValued) { ProtocolMapperModel mapper = OIDCAttributeMapperHelper.createClaimMapper(name, userAttribute, tokenClaimName, claimType, - accessToken, idToken, + accessToken, idToken, introspectionEndpoint, script); mapper.getConfig().put(ProtocolMapperUtils.MULTIVALUED, String.valueOf(multiValued)); - return mapper; + return mapper; } } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/TokenIntrospectionTokenMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/TokenIntrospectionTokenMapper.java new file mode 100644 index 000000000000..50a10064e9c5 --- /dev/null +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/TokenIntrospectionTokenMapper.java @@ -0,0 +1,12 @@ +package org.keycloak.protocol.oidc.mappers; + +import org.keycloak.models.ClientSessionContext; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.ProtocolMapperModel; +import org.keycloak.models.UserSessionModel; +import org.keycloak.representations.AccessToken; + +public interface TokenIntrospectionTokenMapper { + AccessToken transformIntrospectionToken(AccessToken token, ProtocolMapperModel mappingModel, KeycloakSession session, + UserSessionModel userSession, ClientSessionContext clientSessionCtx); +} diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserAttributeMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserAttributeMapper.java index 764b8e51de9f..c99f4da142dd 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserAttributeMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserAttributeMapper.java @@ -37,7 +37,7 @@ * @author Bill Burke * @version $Revision: 1 $ */ -public class UserAttributeMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper { +public class UserAttributeMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper, TokenIntrospectionTokenMapper { private static final List configProperties = new ArrayList(); @@ -106,19 +106,19 @@ protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSes public static ProtocolMapperModel createClaimMapper(String name, String userAttribute, String tokenClaimName, String claimType, - boolean accessToken, boolean idToken, boolean multivalued) { + boolean accessToken, boolean idToken, boolean introspectionEndpoint, boolean multivalued) { return createClaimMapper(name, userAttribute, tokenClaimName, claimType, - accessToken, idToken, multivalued, false); + accessToken, idToken, introspectionEndpoint, multivalued, false); } public static ProtocolMapperModel createClaimMapper(String name, String userAttribute, String tokenClaimName, String claimType, - boolean accessToken, boolean idToken, + boolean accessToken, boolean idToken, boolean introspectionEndpoint, boolean multivalued, boolean aggregateAttrs) { ProtocolMapperModel mapper = OIDCAttributeMapperHelper.createClaimMapper(name, userAttribute, tokenClaimName, claimType, - accessToken, idToken, + accessToken, idToken, introspectionEndpoint, PROVIDER_ID); if (multivalued) { @@ -134,8 +134,8 @@ public static ProtocolMapperModel createClaimMapper(String name, public static ProtocolMapperModel createClaimMapper(String name, String userAttribute, String tokenClaimName, String claimType, - boolean accessToken, boolean idToken) { + boolean accessToken, boolean idToken, boolean introspectionEndpoint) { return createClaimMapper(name, userAttribute, tokenClaimName, claimType, - accessToken, idToken, false, false); + accessToken, idToken, introspectionEndpoint, false, false); } } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserClientRoleMappingMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserClientRoleMappingMapper.java index ca57bd6e8626..77c9532f20b1 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserClientRoleMappingMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserClientRoleMappingMapper.java @@ -135,18 +135,18 @@ protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSes public static ProtocolMapperModel create(String clientId, String clientRolePrefix, String name, String tokenClaimName, - boolean accessToken, boolean idToken) { - return create(clientId, clientRolePrefix, name, tokenClaimName, accessToken, idToken, false); + boolean accessToken, boolean idToken, boolean introspectionEndpoint) { + return create(clientId, clientRolePrefix, name, tokenClaimName, accessToken, idToken, introspectionEndpoint, false); } public static ProtocolMapperModel create(String clientId, String clientRolePrefix, String name, String tokenClaimName, - boolean accessToken, boolean idToken, boolean multiValued) { + boolean accessToken, boolean idToken, boolean introspectionEndpoint, boolean multiValued) { ProtocolMapperModel mapper = OIDCAttributeMapperHelper.createClaimMapper(name, "foo", tokenClaimName, "String", - accessToken, idToken, false, + accessToken, idToken, false, introspectionEndpoint, PROVIDER_ID); mapper.getConfig().put(ProtocolMapperUtils.MULTIVALUED, String.valueOf(multiValued)); diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserPropertyMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserPropertyMapper.java index 863b9835a7e6..94b0bc37c956 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserPropertyMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserPropertyMapper.java @@ -35,7 +35,7 @@ * @author Bill Burke * @version $Revision: 1 $ */ -public class UserPropertyMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper { +public class UserPropertyMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, UserInfoTokenMapper, TokenIntrospectionTokenMapper { private static final List configProperties = new ArrayList(); static { @@ -89,10 +89,10 @@ protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSes public static ProtocolMapperModel createClaimMapper(String name, String userAttribute, String tokenClaimName, String claimType, - boolean accessToken, boolean idToken) { + boolean accessToken, boolean idToken, boolean introspectionEndpoint) { return OIDCAttributeMapperHelper.createClaimMapper(name, userAttribute, tokenClaimName, claimType, - accessToken, idToken, + accessToken, idToken, introspectionEndpoint, PROVIDER_ID); } } diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserRealmRoleMappingMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserRealmRoleMappingMapper.java index 1f817d612428..089426023ed3 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserRealmRoleMappingMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserRealmRoleMappingMapper.java @@ -100,18 +100,18 @@ protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSes public static ProtocolMapperModel create(String realmRolePrefix, String name, - String tokenClaimName, boolean accessToken, boolean idToken) { + String tokenClaimName, boolean accessToken, boolean idToken, boolean introspectionEndpoint) { - return create(realmRolePrefix, name, tokenClaimName, accessToken, idToken, false); + return create(realmRolePrefix, name, tokenClaimName, accessToken, idToken, introspectionEndpoint, false); } public static ProtocolMapperModel create(String realmRolePrefix, String name, - String tokenClaimName, boolean accessToken, boolean idToken, boolean multiValued) { + String tokenClaimName, boolean accessToken, boolean idToken, boolean introspectionEndpoint, boolean multiValued) { ProtocolMapperModel mapper = OIDCAttributeMapperHelper.createClaimMapper(name, "foo", - tokenClaimName, "String", - accessToken, idToken, false, - PROVIDER_ID); + tokenClaimName, "String", + accessToken, idToken, false, introspectionEndpoint, + PROVIDER_ID); mapper.getConfig().put(ProtocolMapperUtils.MULTIVALUED, String.valueOf(multiValued)); mapper.getConfig().put(ProtocolMapperUtils.USER_MODEL_REALM_ROLE_MAPPING_ROLE_PREFIX, realmRolePrefix); diff --git a/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserSessionNoteMapper.java b/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserSessionNoteMapper.java index b7be2cb2913e..cdc4a0f9af3b 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserSessionNoteMapper.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/mappers/UserSessionNoteMapper.java @@ -38,7 +38,7 @@ * * @author Marek Posolda */ -public class UserSessionNoteMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, OIDCAccessTokenResponseMapper, UserInfoTokenMapper { +public class UserSessionNoteMapper extends AbstractOIDCProtocolMapper implements OIDCAccessTokenMapper, OIDCIDTokenMapper, OIDCAccessTokenResponseMapper, UserInfoTokenMapper, TokenIntrospectionTokenMapper { private static final List configProperties = new ArrayList<>(); @@ -90,7 +90,7 @@ protected void setClaim(IDToken token, ProtocolMapperModel mappingModel, UserSes @Override protected void setClaim(AccessTokenResponse accessTokenResponse, ProtocolMapperModel mappingModel, UserSessionModel userSession, - KeycloakSession keycloakSession, ClientSessionContext clientSessionCtx) { + KeycloakSession keycloakSession, ClientSessionContext clientSessionCtx) { String noteName = mappingModel.getConfig().get(ProtocolMapperUtils.USER_SESSION_NOTE); String noteValue = userSession.getNote(noteName); @@ -101,14 +101,14 @@ protected void setClaim(AccessTokenResponse accessTokenResponse, ProtocolMapperM public static ProtocolMapperModel createClaimMapper(String name, String userSessionNote, String tokenClaimName, String jsonType, - boolean accessToken, boolean idToken) { - return createClaimMapper(name, userSessionNote, tokenClaimName, jsonType, accessToken, idToken, false); + boolean accessToken, boolean idToken, boolean introspectionEndpoint) { + return createClaimMapper(name, userSessionNote, tokenClaimName, jsonType, accessToken, idToken, false, introspectionEndpoint); } public static ProtocolMapperModel createClaimMapper(String name, String userSessionNote, String tokenClaimName, String jsonType, - boolean accessToken, boolean idToken, boolean userInfo) { + boolean accessToken, boolean idToken, boolean userInfo, boolean introspectionEndpoint) { ProtocolMapperModel mapper = new ProtocolMapperModel(); mapper.setName(name); mapper.setProtocolMapper(PROVIDER_ID); @@ -120,6 +120,7 @@ public static ProtocolMapperModel createClaimMapper(String name, if (accessToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true"); if (idToken) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true"); if (userInfo) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_USERINFO, "true"); + if (introspectionEndpoint) config.put(OIDCAttributeMapperHelper.INCLUDE_IN_INTROSPECTION, "true"); mapper.setConfig(config); return mapper; } @@ -135,7 +136,7 @@ public static ProtocolMapperModel createUserSessionNoteMapper(UserSessionNoteDes userSessionNoteDescriptor.toString(), userSessionNoteDescriptor.getTokenClaim(), "String", - true, true + true, true, true ); } diff --git a/services/src/main/java/org/keycloak/services/managers/ClientManager.java b/services/src/main/java/org/keycloak/services/managers/ClientManager.java index 8df85b93ec12..d4e4520a0077 100644 --- a/services/src/main/java/org/keycloak/services/managers/ClientManager.java +++ b/services/src/main/java/org/keycloak/services/managers/ClientManager.java @@ -170,7 +170,7 @@ public void enableServiceAccount(ClientModel client) { ProtocolMapperModel protocolMapper = UserSessionNoteMapper.createClaimMapper(ServiceAccountConstants.CLIENT_ID_PROTOCOL_MAPPER, ServiceAccountConstants.CLIENT_ID, ServiceAccountConstants.CLIENT_ID, "String", - true, true); + true, true, true); client.addProtocolMapper(protocolMapper); } @@ -180,7 +180,7 @@ public void enableServiceAccount(ClientModel client) { ProtocolMapperModel protocolMapper = UserSessionNoteMapper.createClaimMapper(ServiceAccountConstants.CLIENT_HOST_PROTOCOL_MAPPER, ServiceAccountConstants.CLIENT_HOST, ServiceAccountConstants.CLIENT_HOST, "String", - true, true); + true, true, true); client.addProtocolMapper(protocolMapper); } @@ -189,7 +189,7 @@ public void enableServiceAccount(ClientModel client) { ProtocolMapperModel protocolMapper = UserSessionNoteMapper.createClaimMapper(ServiceAccountConstants.CLIENT_ADDRESS_PROTOCOL_MAPPER, ServiceAccountConstants.CLIENT_ADDRESS, ServiceAccountConstants.CLIENT_ADDRESS, "String", - true, true); + true, true, true); client.addProtocolMapper(protocolMapper); } } diff --git a/services/src/main/java/org/keycloak/services/util/UserSessionUtil.java b/services/src/main/java/org/keycloak/services/util/UserSessionUtil.java new file mode 100644 index 000000000000..234bc1f6a865 --- /dev/null +++ b/services/src/main/java/org/keycloak/services/util/UserSessionUtil.java @@ -0,0 +1,97 @@ +package org.keycloak.services.util; + +import org.keycloak.common.ClientConnection; +import org.keycloak.common.constants.ServiceAccountConstants; +import org.keycloak.events.Errors; +import org.keycloak.events.EventBuilder; +import org.keycloak.models.AuthenticatedClientSessionModel; +import org.keycloak.models.ClientModel; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; +import org.keycloak.models.UserModel; +import org.keycloak.models.UserSessionModel; +import org.keycloak.models.utils.KeycloakModelUtils; +import org.keycloak.protocol.oidc.OIDCLoginProtocol; +import org.keycloak.protocol.oidc.TokenManager; +import org.keycloak.representations.AccessToken; +import org.keycloak.services.Urls; +import org.keycloak.services.managers.AuthenticationManager; +import org.keycloak.services.managers.UserSessionCrossDCManager; +import org.keycloak.services.managers.UserSessionManager; +import org.keycloak.sessions.AuthenticationSessionModel; +import org.keycloak.sessions.RootAuthenticationSessionModel; +import org.keycloak.utils.OAuth2Error; + +public class UserSessionUtil { + + public static UserSessionModel findValidSession(KeycloakSession session, RealmModel realm, AccessToken token, EventBuilder event, ClientModel client) { + OAuth2Error error = new OAuth2Error().json(false).realm(realm); + if (token.getSessionState() == null) { + return createTransientSessionForClient(session, realm, token, client); + } + + UserSessionModel userSession = new UserSessionCrossDCManager(session).getUserSessionWithClient(realm, token.getSessionState(), false, client.getId()); + UserSessionModel offlineUserSession = null; + if (AuthenticationManager.isSessionValid(realm, userSession)) { + checkTokenIssuedAt(realm, token, userSession, event, client); + event.session(userSession); + return userSession; + } else { + offlineUserSession = new UserSessionCrossDCManager(session).getUserSessionWithClient(realm, token.getSessionState(), true, client.getId()); + if (AuthenticationManager.isOfflineSessionValid(realm, offlineUserSession)) { + checkTokenIssuedAt(realm, token, offlineUserSession, event, client); + event.session(offlineUserSession); + return offlineUserSession; + } + } + + if (userSession == null && offlineUserSession == null) { + event.error(Errors.USER_SESSION_NOT_FOUND); + throw error.invalidToken("User session not found or doesn't have client attached on it"); + } + + if (userSession != null) { + event.session(userSession); + } else { + event.session(offlineUserSession); + } + + event.error(Errors.SESSION_EXPIRED); + throw error.invalidToken("Session expired"); + } + + private static UserSessionModel createTransientSessionForClient(KeycloakSession session, RealmModel realm, AccessToken token, ClientModel client) { + OAuth2Error error = new OAuth2Error().json(false).realm(realm); + // create a transient session + UserModel user = TokenManager.lookupUserFromStatelessToken(session, realm, token); + if (user == null) { + throw error.invalidToken("User not found"); + } + ClientConnection clientConnection = session.getContext().getConnection(); + UserSessionModel userSession = new UserSessionManager(session).createUserSession(KeycloakModelUtils.generateId(), realm, user, user.getUsername(), clientConnection.getRemoteAddr(), + ServiceAccountConstants.CLIENT_AUTH, false, null, null, UserSessionModel.SessionPersistenceState.TRANSIENT); + // attach an auth session for the client + RootAuthenticationSessionModel rootAuthSession = session.authenticationSessions().createRootAuthenticationSession(realm); + AuthenticationSessionModel authSession = rootAuthSession.createAuthenticationSession(client); + authSession.setAuthenticatedUser(userSession.getUser()); + authSession.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL); + authSession.setClientNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(session.getContext().getUri().getBaseUri(), realm.getName())); + AuthenticationManager.setClientScopesInSession(authSession); + TokenManager.attachAuthenticationSession(session, userSession, authSession); + return userSession; + } + + private static void checkTokenIssuedAt(RealmModel realm, AccessToken token, UserSessionModel userSession, EventBuilder event, ClientModel client) { + OAuth2Error error = new OAuth2Error().json(false).realm(realm); + if (token.isIssuedBeforeSessionStart(userSession.getStarted())) { + event.error(Errors.INVALID_TOKEN); + throw error.invalidToken("Stale token"); + } + + AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(client.getId()); + if (token.isIssuedBeforeSessionStart(clientSession.getStarted())) { + event.error(Errors.INVALID_TOKEN); + throw error.invalidToken("Stale token"); + } + } +} diff --git a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java index 8c1fb0a72559..114198fbea3f 100644 --- a/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java +++ b/testsuite/integration-arquillian/servers/auth-server/services/testsuite-providers/src/main/java/org/keycloak/testsuite/rest/TestingResourceProvider.java @@ -817,7 +817,7 @@ public String generateAudienceClientScope(@QueryParam("realm") final String real clientScopeModel.setIncludeInTokenScope(true); // Add audience protocol mapper - ProtocolMapperModel audienceMapper = AudienceProtocolMapper.createClaimMapper("Audience for " + clientId, clientId, null,true, false); + ProtocolMapperModel audienceMapper = AudienceProtocolMapper.createClaimMapper("Audience for " + clientId, clientId, null,true, false, true ); clientScopeModel.addProtocolMapper(audienceMapper); return clientScopeModel.getId(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerSubMatchIntrospectionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerSubMatchIntrospectionTest.java index 2a3603f69dec..163c13f797a8 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerSubMatchIntrospectionTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerSubMatchIntrospectionTest.java @@ -21,12 +21,12 @@ protected BrokerConfiguration getBrokerConfiguration() { @Override public List createConsumerClients() { List clients = new ArrayList<>(super.createConsumerClients()); - + clients.add(ClientBuilder.create().clientId("consumer-client") .publicClient() .redirectUris(getConsumerRoot() + "/auth/realms/master/app/auth/*") .publicClient().build()); - + return clients; } @@ -36,14 +36,14 @@ public List createProviderClients() { List mappers = new ArrayList<>(); ProtocolMapperRepresentation hardcodedClaim = createHardcodedClaim("sub-override", "sub", "overriden", - "String", false, false); - + "String", false, false, false); + hardcodedClaim.getConfig().put(OIDCAttributeMapperHelper.INCLUDE_IN_USERINFO, Boolean.TRUE.toString()); - + mappers.add(hardcodedClaim); - + clients.get(0).setProtocolMappers(mappers); - + return clients; } }; diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerTest.java index b1a4fe79c06d..7cf72ac02dfa 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerTest.java @@ -100,7 +100,7 @@ protected Iterable createIdentityProviderM IdentityProviderMapperRepresentation attrMapper2 = new IdentityProviderMapperRepresentation(); attrMapper2.setName("user-role-mapper"); attrMapper2.setIdentityProviderMapper(ExternalKeycloakRoleToRoleMapper.PROVIDER_ID); - attrMapper2.setConfig(ImmutableMap.builder() + attrMapper2.setConfig(ImmutableMap.builder() .put(IdentityProviderMapperModel.SYNC_MODE, syncMode.toString()) .put("external.role", ROLE_USER) .put("role", ROLE_USER) @@ -114,7 +114,7 @@ protected void createAdditionalMapperWithCustomSyncMode(IdentityProviderMapperSy IdentityProviderMapperRepresentation friendlyManagerMapper = new IdentityProviderMapperRepresentation(); friendlyManagerMapper.setName("friendly-manager-role-mapper"); friendlyManagerMapper.setIdentityProviderMapper(ExternalKeycloakRoleToRoleMapper.PROVIDER_ID); - friendlyManagerMapper.setConfig(ImmutableMap.builder() + friendlyManagerMapper.setConfig(ImmutableMap.builder() .put(IdentityProviderMapperModel.SYNC_MODE, syncMode.toString()) .put("external.role", ROLE_FRIENDLY_MANAGER) .put("role", ROLE_FRIENDLY_MANAGER) @@ -197,7 +197,7 @@ private void loginFetchingUserFromUserEndpoint(boolean loginIsDenied) { logInWithBroker(bc); - waitForPage(driver, loginIsDenied? "We are sorry..." : "update account information", false); + waitForPage(driver, loginIsDenied ? "We are sorry..." : "update account information", false); if (loginIsDenied) { return; } @@ -243,7 +243,7 @@ public void loginFetchingUserFromUserEndpointWithClaimMapper() { ClientRepresentation brokerApp = clients.findByClientId("brokerapp").get(0); IdentityProviderResource identityProviderResource = getIdentityProviderResource(); - clients.get(brokerApp.getId()).getProtocolMappers().createMapper(createHardcodedClaim("hard-coded", "hard-coded", "hard-coded", "String", true, true)).close(); + clients.get(brokerApp.getId()).getProtocolMappers().createMapper(createHardcodedClaim("hard-coded", "hard-coded", "hard-coded", "String", true, true, true)).close(); IdentityProviderMapperRepresentation hardCodedSessionNoteMapper = new IdentityProviderMapperRepresentation(); @@ -445,7 +445,7 @@ public void testInvalidIssuedFor() { RealmResource realm = adminClient.realm(bc.providerRealmName()); ClientRepresentation rep = realm.clients().findByClientId(BrokerTestConstants.CLIENT_ID).get(0); ClientResource clientResource = realm.clients().get(rep.getId()); - ProtocolMapperRepresentation hardCodedAzp = createHardcodedClaim("hard", "azp", "invalid-azp", ProviderConfigProperty.STRING_TYPE, true, true); + ProtocolMapperRepresentation hardCodedAzp = createHardcodedClaim("hard", "azp", "invalid-azp", ProviderConfigProperty.STRING_TYPE, true, true, true); clientResource.getProtocolMappers().createMapper(hardCodedAzp); log.debug("Logging in"); @@ -469,7 +469,7 @@ public void testInvalidAudience() { RealmResource realm = adminClient.realm(bc.providerRealmName()); ClientRepresentation rep = realm.clients().findByClientId(BrokerTestConstants.CLIENT_ID).get(0); ClientResource clientResource = realm.clients().get(rep.getId()); - ProtocolMapperRepresentation hardCodedAzp = createHardcodedClaim("hard", "aud", "invalid-aud", ProviderConfigProperty.LIST_TYPE, true, true); + ProtocolMapperRepresentation hardCodedAzp = createHardcodedClaim("hard", "aud", "invalid-aud", ProviderConfigProperty.LIST_TYPE, true, true, true); clientResource.getProtocolMappers().createMapper(hardCodedAzp); log.debug("Logging in"); @@ -564,7 +564,7 @@ public void denyLoginWithClaimFilter() { loginFetchingUserFromUserEndpoint(true); Assert.assertEquals("The ID token issued by the identity provider does not match the configured essential claim. Please contact your administrator.", - loginPage.getInstruction()); + loginPage.getInstruction()); List users = realmsResouce().realm(bc.consumerRealmName()).users().search(bc.getUserLogin()); @@ -572,8 +572,8 @@ public void denyLoginWithClaimFilter() { } protected void postInitializeUser(UserRepresentation user) { - user.setAttributes(ImmutableMap.> builder() - .put(USER_ATTRIBUTE_NAME, ImmutableList. builder().add(USER_ATTRIBUTE_VALUE).build()) + user.setAttributes(ImmutableMap.>builder() + .put(USER_ATTRIBUTE_NAME, ImmutableList.builder().add(USER_ATTRIBUTE_VALUE).build()) .build()); } @@ -585,8 +585,8 @@ private void updateIdPClaimFilter(IdentityProviderRepresentation idProvider, Ide assertThat(claimFilterValue, Matchers.notNullValue()); if (idProvider.getConfig().getOrDefault(IdentityProviderModel.FILTERED_BY_CLAIMS, "false").equals(Boolean.toString(filteredByClaim)) && - idProvider.getConfig().getOrDefault(IdentityProviderModel.CLAIM_FILTER_NAME, "").equals(claimFilterName) && - idProvider.getConfig().getOrDefault(IdentityProviderModel.CLAIM_FILTER_VALUE, "").equals(claimFilterValue) + idProvider.getConfig().getOrDefault(IdentityProviderModel.CLAIM_FILTER_NAME, "").equals(claimFilterName) && + idProvider.getConfig().getOrDefault(IdentityProviderModel.CLAIM_FILTER_VALUE, "").equals(claimFilterValue) ) { return; } @@ -722,7 +722,7 @@ private void checkFederatedIdentityLink(UserResource userResource, String userID } private void updateIdPSyncMode(IdentityProviderRepresentation idProvider, IdentityProviderResource idProviderResource, - IdentityProviderSyncMode syncMode, boolean trustEmail) { + IdentityProviderSyncMode syncMode, boolean trustEmail) { assertThat(idProvider, Matchers.notNullValue()); assertThat(idProviderResource, Matchers.notNullValue()); assertThat(syncMode, Matchers.notNullValue()); @@ -755,6 +755,7 @@ private IdentityProviderResource getIdentityProviderResource() { } private static final CustomKcOidcBrokerConfiguration BROKER_CONFIG_INSTANCE = new CustomKcOidcBrokerConfiguration(); + static class CustomKcOidcBrokerConfiguration extends KcOidcBrokerConfiguration { @Override @@ -766,7 +767,7 @@ public List createProviderClients() { userAttrMapper.setName(USER_ATTRIBUTE_NAME); userAttrMapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL); userAttrMapper.setProtocolMapper(UserAttributeMapper.PROVIDER_ID); - + Map userAttrMapperConfig = userAttrMapper.getConfig(); userAttrMapperConfig.put(ProtocolMapperUtils.USER_ATTRIBUTE, USER_ATTRIBUTE_NAME); userAttrMapperConfig.put(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME, USER_ATTRIBUTE_NAME); @@ -781,6 +782,6 @@ public List createProviderClients() { client.setProtocolMappers(mappers); return clients; - } + } } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerTokenExchangeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerTokenExchangeTest.java index 52a99fedb7d8..6899c587ce95 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerTokenExchangeTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerTokenExchangeTest.java @@ -50,18 +50,16 @@ import org.keycloak.representations.idm.IdentityProviderMapperRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation; -import org.keycloak.representations.idm.authorization.DecisionStrategy; import org.keycloak.services.resources.admin.permissions.AdminPermissionManagement; import org.keycloak.services.resources.admin.permissions.AdminPermissions; import org.keycloak.testsuite.arquillian.annotation.EnableFeature; import org.keycloak.testsuite.arquillian.annotation.EnableFeatures; import org.keycloak.testsuite.util.AdminClientUtil; -import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.util.BasicAuthHelper; import com.google.common.collect.ImmutableMap; -@EnableFeatures({ @EnableFeature(Profile.Feature.TOKEN_EXCHANGE), @EnableFeature(Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ) }) +@EnableFeatures({@EnableFeature(Profile.Feature.TOKEN_EXCHANGE), @EnableFeature(Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ)}) public final class KcOidcBrokerTokenExchangeTest extends AbstractInitializedBaseBrokerTest { @Override @@ -77,7 +75,7 @@ public void testExternalInternalTokenExchange() throws Exception { brokerApp.setDirectAccessGrantsEnabled(true); ClientResource brokerAppResource = providerRealm.clients().get(brokerApp.getId()); brokerAppResource.update(brokerApp); - brokerAppResource.getProtocolMappers().createMapper(createHardcodedClaim("hard-coded", "hard-coded", "hard-coded", "String", true, true)).close(); + brokerAppResource.getProtocolMappers().createMapper(createHardcodedClaim("hard-coded", "hard-coded", "hard-coded", "String", true, true, true)).close(); IdentityProviderMapperRepresentation hardCodedSessionNoteMapper = new IdentityProviderMapperRepresentation(); hardCodedSessionNoteMapper.setName("hard-coded"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/AbstractKerberosSingleRealmTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/AbstractKerberosSingleRealmTest.java index 141c8ca23e89..80d61f4a00ab 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/AbstractKerberosSingleRealmTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/AbstractKerberosSingleRealmTest.java @@ -47,6 +47,7 @@ import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.TestAppHelper; + import static org.keycloak.testsuite.admin.ApiUtil.findClientByClientId; /** @@ -180,7 +181,7 @@ public void credentialDelegationTest() throws Exception { ProtocolMapperModel protocolMapper = UserSessionNoteMapper.createClaimMapper(KerberosConstants.GSS_DELEGATION_CREDENTIAL_DISPLAY_NAME, KerberosConstants.GSS_DELEGATION_CREDENTIAL, KerberosConstants.GSS_DELEGATION_CREDENTIAL, "String", - true, false, true); + true, false, true, true); ProtocolMapperRepresentation protocolMapperRep = ModelToRepresentation.toRepresentation(protocolMapper); ClientResource clientResource = findClientByClientId(testRealmResource(), "kerberos-app"); Response response = clientResource.getProtocolMappers().createMapper(protocolMapperRep); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPMultipleAttributesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPMultipleAttributesTest.java index 254800628632..9c6f1d8395a1 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPMultipleAttributesTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPMultipleAttributesTest.java @@ -105,8 +105,8 @@ protected void afterImportTestRealm() { ldapClient.addRedirectUri("/ldap-portal"); ldapClient.addRedirectUri("/ldap-portal/*"); ldapClient.setManagementUrl("/ldap-portal"); - ldapClient.addProtocolMapper(UserAttributeMapper.createClaimMapper("postalCode", "postal_code", "postal_code", "String", true, true, true)); - ldapClient.addProtocolMapper(UserAttributeMapper.createClaimMapper("street", "street", "street", "String", true, true, false)); + ldapClient.addProtocolMapper(UserAttributeMapper.createClaimMapper("postalCode", "postal_code", "postal_code", "String", true, true, true, true)); + ldapClient.addProtocolMapper(UserAttributeMapper.createClaimMapper("street", "street", "street", "String", true, true, true, false)); ldapClient.addScopeMapping(appRealm.getRole("user")); ldapClient.setSecret("password"); }); @@ -237,7 +237,6 @@ public void ldapPortalEndToEndTest() { } - } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java index adc2d18af70f..641e991f3b42 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java @@ -819,7 +819,7 @@ public void testClientScope() throws Exception { String clientScopeId = ApiUtil.getCreatedId(response); response.close(); ClientScopeResource clientScopeResource = adminClient.proxy(ClientScopeResource.class, scopeUri); - ProtocolMapperModel hard = HardcodedClaim.create("hard", "hard", "coded", "String", true, true); + ProtocolMapperModel hard = HardcodedClaim.create("hard", "hard", "coded", "String", true, true, true); ProtocolMapperRepresentation mapper = ModelToRepresentation.toRepresentation(hard); response = clientScopeResource.getProtocolMappers().createMapper(mapper); assertEquals(201, response.getStatus()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientTokenExchangeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientTokenExchangeTest.java index ab6a51d51cbc..b8ac280f851c 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientTokenExchangeTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientTokenExchangeTest.java @@ -175,7 +175,7 @@ public static void setupRealm(KeycloakSession session) { directPublic.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL); directPublic.setFullScopeAllowed(false); directPublic.addRedirectUri("*"); - directPublic.addProtocolMapper(AudienceProtocolMapper.createClaimMapper("client-exchanger-audience", clientExchanger.getClientId(), null, true, false)); + directPublic.addProtocolMapper(AudienceProtocolMapper.createClaimMapper("client-exchanger-audience", clientExchanger.getClientId(), null, true, false, true)); ClientModel directUntrustedPublic = realm.addClient("direct-public-untrusted"); directUntrustedPublic.setClientId("direct-public-untrusted"); @@ -186,7 +186,7 @@ public static void setupRealm(KeycloakSession session) { directUntrustedPublic.setFullScopeAllowed(false); directUntrustedPublic.addRedirectUri("*"); directUntrustedPublic.setAttribute(OIDCConfigAttributes.POST_LOGOUT_REDIRECT_URIS, "+"); - directUntrustedPublic.addProtocolMapper(AudienceProtocolMapper.createClaimMapper("client-exchanger-audience", clientExchanger.getClientId(), null, true, false)); + directUntrustedPublic.addProtocolMapper(AudienceProtocolMapper.createClaimMapper("client-exchanger-audience", clientExchanger.getClientId(), null, true, false, true)); ClientModel directNoSecret = realm.addClient("direct-no-secret"); directNoSecret.setClientId("direct-no-secret"); @@ -538,16 +538,16 @@ public void testIntrospectTokenAfterImpersonation() throws Exception { } try (Response response = exchangeUrl.request() - .header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader("client-exchanger", "secret")) - .post(Entity.form( - new Form() - .param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE) - .param(OAuth2Constants.SUBJECT_TOKEN, accessToken) - .param(OAuth2Constants.SUBJECT_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE) - .param(OAuth2Constants.REQUESTED_SUBJECT, "impersonated-user") - .param(OAuth2Constants.AUDIENCE, "target") + .header(HttpHeaders.AUTHORIZATION, BasicAuthHelper.createHeader("client-exchanger", "secret")) + .post(Entity.form( + new Form() + .param(OAuth2Constants.GRANT_TYPE, OAuth2Constants.TOKEN_EXCHANGE_GRANT_TYPE) + .param(OAuth2Constants.SUBJECT_TOKEN, accessToken) + .param(OAuth2Constants.SUBJECT_TOKEN_TYPE, OAuth2Constants.ACCESS_TOKEN_TYPE) + .param(OAuth2Constants.REQUESTED_SUBJECT, "impersonated-user") + .param(OAuth2Constants.AUDIENCE, "target") - ))) { + ))) { org.junit.Assert.assertEquals(200, response.getStatus()); AccessTokenResponse accessTokenResponse = response.readEntity(AccessTokenResponse.class); String exchangedTokenString = accessTokenResponse.getToken(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java index 2519d7d3d3b4..894e068be726 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java @@ -401,7 +401,7 @@ public void oauthGrantClientScopeMappers() throws Exception { String fooScopeId = ApiUtil.getCreatedId(response); response.close(); - ProtocolMapperRepresentation protocolMapper = ProtocolMapperUtil.createAddressMapper(true, true, true); + ProtocolMapperRepresentation protocolMapper = ProtocolMapperUtil.createAddressMapper(true, true, true, true); response = appRealm.clientScopes().get(fooScopeId).getProtocolMappers().createMapper(protocolMapper); response.close(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OIDCProtocolMappersTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OIDCProtocolMappersTest.java index fa7a86599b9d..fdaedfd1989b 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OIDCProtocolMappersTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OIDCProtocolMappersTest.java @@ -153,11 +153,11 @@ public void testTokenScriptMapping() throws Exception { reconnectAdminClient(); ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app"); - app.getProtocolMappers().createMapper(createScriptMapper("test-script-mapper1","computed-via-script", "computed-via-script", "String", true, true, "script-scripts/test-script-mapper1.js", false)).close(); - app.getProtocolMappers().createMapper(createScriptMapper("test-script-mapper2","multiValued-via-script", "multiValued-via-script", "String", true, true, "script-scripts/test-script-mapper2.js", true)).close(); - app.getProtocolMappers().createMapper(createScriptMapper("test-script-mapper3","computed-json-via-script", "computed-json-via-script", "JSON", true, true, "script-scripts/test-script-mapper3.js", false)).close(); + app.getProtocolMappers().createMapper(createScriptMapper("test-script-mapper1","computed-via-script", "computed-via-script", "String", true, true, true,"script-scripts/test-script-mapper1.js", false)).close(); + app.getProtocolMappers().createMapper(createScriptMapper("test-script-mapper2","multiValued-via-script", "multiValued-via-script", "String", true, true, true, "script-scripts/test-script-mapper2.js", true)).close(); + app.getProtocolMappers().createMapper(createScriptMapper("test-script-mapper3","computed-json-via-script", "computed-json-via-script", "JSON", true, true, true, "script-scripts/test-script-mapper3.js", false)).close(); - Response response = app.getProtocolMappers().createMapper(createScriptMapper("test-script-mapper3", "syntax-error-script", "syntax-error-script", "String", true, true, "script-scripts/test-bad-script-mapper3.js", false)); + Response response = app.getProtocolMappers().createMapper(createScriptMapper("test-script-mapper3", "syntax-error-script", "syntax-error-script", "String", true, true, true, "script-scripts/test-bad-script-mapper3.js", false)); assertThat(response.getStatusInfo().getFamily(), is(Response.Status.Family.CLIENT_ERROR)); response.close(); } @@ -199,31 +199,31 @@ public void testTokenMapping() throws Exception { ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app"); - ProtocolMapperRepresentation mapper = createAddressMapper(true, true, true); + ProtocolMapperRepresentation mapper = createAddressMapper(true, true, true, true); mapper.getConfig().put(AddressMapper.getModelPropertyName(AddressClaimSet.REGION), "region_some"); mapper.getConfig().put(AddressMapper.getModelPropertyName(AddressClaimSet.COUNTRY), "country_some"); mapper.getConfig().remove(AddressMapper.getModelPropertyName(AddressClaimSet.POSTAL_CODE)); // Even if we remove protocolMapper config property, it should still default to postal_code app.getProtocolMappers().createMapper(mapper).close(); - ProtocolMapperRepresentation hard = createHardcodedClaim("hard", "hard", "coded", "String", true, true); + ProtocolMapperRepresentation hard = createHardcodedClaim("hard", "hard", "coded", "String", true, true, true); app.getProtocolMappers().createMapper(hard).close(); - app.getProtocolMappers().createMapper(createHardcodedClaim("hard-nested", "nested.hard", "coded-nested", "String", true, true)).close(); - app.getProtocolMappers().createMapper(createClaimMapper("custom phone", "phone", "home_phone", "String", true, true, true)).close(); - app.getProtocolMappers().createMapper(createClaimMapper("nested phone", "phone", "home.phone", "String", true, true, true)).close(); - app.getProtocolMappers().createMapper(createClaimMapper("dotted phone", "phone", "home\\.phone", "String", true, true, true)).close(); - app.getProtocolMappers().createMapper(createClaimMapper("departments", "departments", "department", "String", true, true, true)).close(); - app.getProtocolMappers().createMapper(createClaimMapper("firstDepartment", "departments", "firstDepartment", "String", true, true, false)).close(); + app.getProtocolMappers().createMapper(createHardcodedClaim("hard-nested", "nested.hard", "coded-nested", "String", true, true, true)).close(); + app.getProtocolMappers().createMapper(createClaimMapper("custom phone", "phone", "home_phone", "String", true, true, true, true)).close(); + app.getProtocolMappers().createMapper(createClaimMapper("nested phone", "phone", "home.phone", "String", true, true, true, true)).close(); + app.getProtocolMappers().createMapper(createClaimMapper("dotted phone", "phone", "home\\.phone", "String", true, true, true, true)).close(); + app.getProtocolMappers().createMapper(createClaimMapper("departments", "departments", "department", "String", true, true, true, true)).close(); + app.getProtocolMappers().createMapper(createClaimMapper("firstDepartment", "departments", "firstDepartment", "String", true, true, true,false)).close(); app.getProtocolMappers().createMapper(createHardcodedRole("hard-realm", "hardcoded")).close(); app.getProtocolMappers().createMapper(createHardcodedRole("hard-app", "app.hardcoded")).close(); app.getProtocolMappers().createMapper(createRoleNameMapper("rename-app-role", "test-app.customer-user", "realm-user")).close(); - app.getProtocolMappers().createMapper(createScriptMapper("test-script-mapper1","computed-via-script", "computed-via-script", "String", true, true, "'hello_' + user.username", false)).close(); - app.getProtocolMappers().createMapper(createScriptMapper("test-script-mapper2","multiValued-via-script", "multiValued-via-script", "String", true, true, "new java.util.ArrayList(['A','B'])", true)).close(); + app.getProtocolMappers().createMapper(createScriptMapper("test-script-mapper1","computed-via-script", "computed-via-script", "String", true, true, true, "'hello_' + user.username", false)).close(); + app.getProtocolMappers().createMapper(createScriptMapper("test-script-mapper2","multiValued-via-script", "multiValued-via-script", "String", true, true, true, "new java.util.ArrayList(['A','B'])", true)).close(); app.getProtocolMappers().createMapper(createClaimMapper("json-attribute-mapper", "json-attribute", "claim-from-json-attribute", - "JSON", true, true, false)).close(); + "JSON", true, true, true, false)).close(); app.getProtocolMappers().createMapper(createClaimMapper("json-attribute-mapper-multi", "json-attribute-multi", "claim-from-json-attribute-multi", - "JSON", true, true, true)).close(); + "JSON", true, true, true, true)).close(); - Response response = app.getProtocolMappers().createMapper(createScriptMapper("test-script-mapper3", "syntax-error-script", "syntax-error-script", "String", true, true, "func_tion foo(){ return 'fail';} foo()", false)); + Response response = app.getProtocolMappers().createMapper(createScriptMapper("test-script-mapper3", "syntax-error-script", "syntax-error-script", "String", true, true, true, "func_tion foo(){ return 'fail';} foo()", false)); assertThat(response.getStatusInfo().getFamily(), is(Response.Status.Family.CLIENT_ERROR)); response.close(); } @@ -360,10 +360,10 @@ public void testTokenPropertiesMapping() throws Exception { // create a user attr mapping for some claims that exist as properties in the tokens ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app"); - app.getProtocolMappers().createMapper(createClaimMapper("userid-as-sub", "userid", "sub", "String", true, true, false)).close(); - app.getProtocolMappers().createMapper(createClaimMapper("useraud", "useraud", "aud", "String", true, true, true)).close(); - app.getProtocolMappers().createMapper(createHardcodedClaim("website-hardcoded", "website", "http://localhost", "String", true, true)).close(); - app.getProtocolMappers().createMapper(createHardcodedClaim("iat-hardcoded", "iat", "123", "long", true, false)).close(); + app.getProtocolMappers().createMapper(createClaimMapper("userid-as-sub", "userid", "sub", "String", true, true, true,false)).close(); + app.getProtocolMappers().createMapper(createClaimMapper("useraud", "useraud", "aud", "String", true, true, true, true)).close(); + app.getProtocolMappers().createMapper(createHardcodedClaim("website-hardcoded", "website", "http://localhost", "String", true, true, true)).close(); + app.getProtocolMappers().createMapper(createHardcodedClaim("iat-hardcoded", "iat", "123", "long", true, false, true)).close(); // login OAuthClient.AccessTokenResponse response = browserLogin("password", "test-user@localhost", "password"); @@ -432,6 +432,7 @@ public void testClaimFromUserPropertyMapperWithOptionalProfileScope() { "claim-name", String.class.getSimpleName(), true, + true, true )))) { mapperId = getCreatedId(response); @@ -481,6 +482,7 @@ public void testClaimFromUserPropertyMapperWithDefaultProfileScope() { "claim-name", String.class.getSimpleName(), true, + true, true )))) { mapperId = getCreatedId(response); @@ -519,8 +521,8 @@ public void testNullOrEmptyTokenMapping() throws Exception { userResource.update(user); ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app"); - app.getProtocolMappers().createMapper(createClaimMapper("empty", "empty", "empty", "String", true, true, false)).close(); - app.getProtocolMappers().createMapper(createClaimMapper("null", "null", "null", "String", true, true, false)).close(); + app.getProtocolMappers().createMapper(createClaimMapper("empty", "empty", "empty", "String", true, true, true,false)).close(); + app.getProtocolMappers().createMapper(createClaimMapper("null", "null", "null", "String", true, true, true,false)).close(); } { @@ -569,8 +571,8 @@ public void testNullOrEmptyTokenMapping() throws Exception { public void testUserRoleToAttributeMappers() throws Exception { // Add mapper for realm roles - ProtocolMapperRepresentation realmMapper = ProtocolMapperUtil.createUserRealmRoleMappingMapper("pref.", "Realm roles mapper", "roles-custom.realm", true, true); - ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper("test-app", null, "Client roles mapper", "roles-custom.test-app", true, true); + ProtocolMapperRepresentation realmMapper = ProtocolMapperUtil.createUserRealmRoleMappingMapper("pref.", "Realm roles mapper", "roles-custom.realm", true, true, true); + ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper("test-app", null, "Client roles mapper", "roles-custom.test-app", true, true, true); ProtocolMappersResource protocolMappers = ApiUtil.findClientResourceByClientId(adminClient.realm("test"), "test-app").getProtocolMappers(); protocolMappers.createMapper(Arrays.asList(realmMapper, clientMapper)); @@ -792,7 +794,7 @@ public void testUserRoleToAttributeMappersWithFullScopeDisabled() throws Excepti public void testRoleMapperWithRoleInheritedFromMoreGroups() throws Exception { // Create client-mapper String clientId = "test-app"; - ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper(clientId, null, "Client roles mapper", "roles-custom.test-app", true, true); + ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper(clientId, null, "Client roles mapper", "roles-custom.test-app", true, true, true); ProtocolMappersResource protocolMappers = ApiUtil.findClientResourceByClientId(adminClient.realm("test"), clientId).getProtocolMappers(); protocolMappers.createMapper(Arrays.asList(clientMapper)); @@ -825,8 +827,8 @@ public void testRoleMapperWithRoleInheritedFromMoreGroups() throws Exception { public void testUserGroupRoleToAttributeMappers() throws Exception { // Add mapper for realm roles String clientId = "test-app"; - ProtocolMapperRepresentation realmMapper = ProtocolMapperUtil.createUserRealmRoleMappingMapper("pref.", "Realm roles mapper", "roles-custom.realm", true, true); - ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper(clientId, "ta.", "Client roles mapper", "roles-custom.test-app", true, true); + ProtocolMapperRepresentation realmMapper = ProtocolMapperUtil.createUserRealmRoleMappingMapper("pref.", "Realm roles mapper", "roles-custom.realm", true, true, true); + ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper(clientId, "ta.", "Client roles mapper", "roles-custom.test-app", true, true, true); ProtocolMappersResource protocolMappers = ApiUtil.findClientResourceByClientId(adminClient.realm("test"), clientId).getProtocolMappers(); protocolMappers.createMapper(Arrays.asList(realmMapper, clientMapper)); @@ -861,8 +863,8 @@ public void testUserGroupRoleToAttributeMappers() throws Exception { @Test public void testUserGroupRoleToAttributeMappersNotScopedOtherApp() throws Exception { String clientId = "test-app-authz"; - ProtocolMapperRepresentation realmMapper = ProtocolMapperUtil.createUserRealmRoleMappingMapper("pref.", "Realm roles mapper", "roles-custom.realm", true, true); - ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper(clientId, null, "Client roles mapper", "roles-custom." + clientId, true, true); + ProtocolMapperRepresentation realmMapper = ProtocolMapperUtil.createUserRealmRoleMappingMapper("pref.", "Realm roles mapper", "roles-custom.realm", true, true, true); + ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper(clientId, null, "Client roles mapper", "roles-custom." + clientId, true, true, true); ProtocolMappersResource protocolMappers = ApiUtil.findClientResourceByClientId(adminClient.realm("test"), clientId).getProtocolMappers(); protocolMappers.createMapper(Arrays.asList(realmMapper, clientMapper)); @@ -901,8 +903,8 @@ public void testUserGroupRoleToAttributeMappersNotScopedOtherApp() throws Except @Test public void testUserGroupRoleToAttributeMappersScoped() throws Exception { String clientId = "test-app-scope"; - ProtocolMapperRepresentation realmMapper = ProtocolMapperUtil.createUserRealmRoleMappingMapper("pref.", "Realm roles mapper", "roles-custom.realm", true, true); - ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper(clientId, null, "Client roles mapper", "roles-custom.test-app-scope", true, true); + ProtocolMapperRepresentation realmMapper = ProtocolMapperUtil.createUserRealmRoleMappingMapper("pref.", "Realm roles mapper", "roles-custom.realm", true, true, true); + ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper(clientId, null, "Client roles mapper", "roles-custom.test-app-scope", true, true, true); ProtocolMappersResource protocolMappers = ApiUtil.findClientResourceByClientId(adminClient.realm("test"), clientId).getProtocolMappers(); protocolMappers.createMapper(Arrays.asList(realmMapper, clientMapper)); @@ -935,8 +937,8 @@ public void testUserGroupRoleToAttributeMappersScoped() throws Exception { @Test public void testUserGroupRoleToAttributeMappersScopedClientNotSet() throws Exception { String clientId = "test-app-scope"; - ProtocolMapperRepresentation realmMapper = ProtocolMapperUtil.createUserRealmRoleMappingMapper("pref.", "Realm roles mapper", "roles-custom.realm", true, true); - ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper(null, null, "Client roles mapper", "roles-custom.test-app-scope", true, true); + ProtocolMapperRepresentation realmMapper = ProtocolMapperUtil.createUserRealmRoleMappingMapper("pref.", "Realm roles mapper", "roles-custom.realm", true, true, true); + ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper(null, null, "Client roles mapper", "roles-custom.test-app-scope", true, true, true); ProtocolMappersResource protocolMappers = ApiUtil.findClientResourceByClientId(adminClient.realm("test"), clientId).getProtocolMappers(); protocolMappers.createMapper(Arrays.asList(realmMapper, clientMapper)); @@ -971,8 +973,8 @@ public void testUserGroupRoleToAttributeMappersScopedClientNotSet() throws Excep @Test public void testSingleValuedRoleMapping() throws Exception { String clientId = "test-app-scope"; - ProtocolMapperRepresentation realmMapper = ProtocolMapperUtil.createUserRealmRoleMappingMapper("pref.", "Realm roles mapper", "roles-custom.realm", true, true, false); - ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper(null, null, "Client roles mapper", "roles-custom.test-app-scope", true, true, false); + ProtocolMapperRepresentation realmMapper = ProtocolMapperUtil.createUserRealmRoleMappingMapper("pref.", "Realm roles mapper", "roles-custom.realm", true, true, true,false); + ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper(null, null, "Client roles mapper", "roles-custom.test-app-scope", true, true, true, false); ProtocolMappersResource protocolMappers = ApiUtil.findClientResourceByClientId(adminClient.realm("test"), clientId).getProtocolMappers(); protocolMappers.createMapper(Arrays.asList(realmMapper, clientMapper)); @@ -1008,8 +1010,8 @@ public void testUserGroupRoleToAttributeMappersScopedWithDifferentClient() throw final String diffClient = "test-app"; final String realmName = "test"; - final ProtocolMapperRepresentation realmMapper = ProtocolMapperUtil.createUserRealmRoleMappingMapper("pref.", "Realm roles mapper", "roles-custom.realm", true, true); - final ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper(diffClient, null, "Client roles mapper", "roles-custom.test-app", true, true); + final ProtocolMapperRepresentation realmMapper = ProtocolMapperUtil.createUserRealmRoleMappingMapper("pref.", "Realm roles mapper", "roles-custom.realm", true, true, true); + final ProtocolMapperRepresentation clientMapper = ProtocolMapperUtil.createUserClientRoleMappingMapper(diffClient, null, "Client roles mapper", "roles-custom.test-app", true, true, true); try (ClientAttributeUpdater cau = ClientAttributeUpdater.forClient(adminClient, realmName, clientId).setDirectAccessGrantsEnabled(true); ProtocolMappersUpdater protocolMappers = new ProtocolMappersUpdater(cau.getResource().getProtocolMappers())) { @@ -1057,7 +1059,7 @@ public void testGroupAttributeUserOneGroupNoMultivalueNoAggregate() throws Excep userResource.joinGroup(group1.getId()); // create the attribute mapper ProtocolMappersResource protocolMappers = findClientResourceByClientId(adminClient.realm("test"), "test-app").getProtocolMappers(); - protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, false, false)).close(); + protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true,false, false)).close(); try { // test it @@ -1097,7 +1099,7 @@ public void testGroupAttributeUserOneGroupMultivalueNoAggregate() throws Excepti userResource.joinGroup(group1.getId()); // create the attribute mapper ProtocolMappersResource protocolMappers = findClientResourceByClientId(adminClient.realm("test"), "test-app").getProtocolMappers(); - protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, false)).close(); + protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, true, false)).close(); try { // test it @@ -1138,7 +1140,7 @@ public void testGroupAttributeUserOneGroupMultivalueAggregate() throws Exception userResource.joinGroup(group1.getId()); // create the attribute mapper ProtocolMappersResource protocolMappers = findClientResourceByClientId(adminClient.realm("test"), "test-app").getProtocolMappers(); - protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, true)).close(); + protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, true, true)).close(); try { // test it @@ -1177,7 +1179,7 @@ public void testGroupAttributeOneGroupNoMultivalueNoAggregate() throws Exception userResource.joinGroup(group1.getId()); // create the attribute mapper ProtocolMappersResource protocolMappers = findClientResourceByClientId(adminClient.realm("test"), "test-app").getProtocolMappers(); - protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, false, false)).close(); + protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, false, false)).close(); try { // test it @@ -1212,7 +1214,7 @@ public void testGroupAttributeOneGroupMultiValueNoAggregate() throws Exception { // create the attribute mapper ProtocolMappersResource protocolMappers = findClientResourceByClientId(adminClient.realm("test"), "test-app").getProtocolMappers(); - protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, false)).close(); + protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, true, false)).close(); try { // test it @@ -1248,7 +1250,7 @@ public void testGroupAttributeOneGroupMultiValueAggregate() throws Exception { // create the attribute mapper ProtocolMappersResource protocolMappers = findClientResourceByClientId(adminClient.realm("test"), "test-app").getProtocolMappers(); - protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, true)).close(); + protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, true, true)).close(); try { // test it @@ -1291,7 +1293,7 @@ public void testGroupAttributeTwoGroupNoMultivalueNoAggregate() throws Exception // create the attribute mapper ProtocolMappersResource protocolMappers = findClientResourceByClientId(adminClient.realm("test"), "test-app").getProtocolMappers(); - protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, false, false)).close(); + protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, false, false)).close(); try { // test it @@ -1336,7 +1338,7 @@ public void testGroupAttributeTwoGroupMultiValueNoAggregate() throws Exception { // create the attribute mapper ProtocolMappersResource protocolMappers = findClientResourceByClientId(adminClient.realm("test"), "test-app").getProtocolMappers(); - protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, false)).close(); + protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, true, false)).close(); try { // test it @@ -1383,7 +1385,7 @@ public void testGroupAttributeTwoGroupMultiValueAggregate() throws Exception { // create the attribute mapper ProtocolMappersResource protocolMappers = findClientResourceByClientId(adminClient.realm("test"), "test-app").getProtocolMappers(); - protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, true)).close(); + protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, true, true)).close(); try { // test it @@ -1434,7 +1436,7 @@ public void testGroupAttributeTwoGroupHierarchyNoMultivalueNoAggregateFromParent // create the attribute mapper ProtocolMappersResource protocolMappers = findClientResourceByClientId(adminClient.realm("test"), "test-app").getProtocolMappers(); - protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, false, false)).close(); + protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, false, false)).close(); try { // test it @@ -1483,7 +1485,7 @@ public void testGroupAttributeTwoGroupHierarchyNoMultivalueNoAggregateFromChild( // create the attribute mapper ProtocolMappersResource protocolMappers = findClientResourceByClientId(adminClient.realm("test"), "test-app").getProtocolMappers(); - protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, false, false)).close(); + protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, false, false)).close(); try { // test it @@ -1532,7 +1534,7 @@ public void testGroupAttributeTwoGroupHierarchyMultiValueNoAggregate() throws Ex // create the attribute mapper ProtocolMappersResource protocolMappers = findClientResourceByClientId(adminClient.realm("test"), "test-app").getProtocolMappers(); - protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, false)).close(); + protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, true, false)).close(); try { // test it @@ -1586,7 +1588,7 @@ public void testGroupAttributeTwoGroupHierarchyMultiValueAggregate() throws Exce // create the attribute mapper ProtocolMappersResource protocolMappers = findClientResourceByClientId(adminClient.realm("test"), "test-app").getProtocolMappers(); - protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true, true)).close(); + protocolMappers.createMapper(createClaimMapper("group-value", "group-value", "group-value", "String", true, true, true,true, true)).close(); try { // test it @@ -1776,7 +1778,7 @@ public void executeTokenMappersOnDynamicScopes() { put(ClientScopeModel.DYNAMIC_SCOPE_REGEXP, "dyn-scope-with-mapper:*"); }}); // create the attribute mapper - ProtocolMapperRepresentation protocolMapperRepresentation = createHardcodedClaim("dynamic-scope-hardcoded-mapper", "hardcoded-foo", "hardcoded-bar", "String", true, true); + ProtocolMapperRepresentation protocolMapperRepresentation = createHardcodedClaim("dynamic-scope-hardcoded-mapper", "hardcoded-foo", "hardcoded-bar", "String", true, true, true); scopeRep.setProtocolMappers(Collections.singletonList(protocolMapperRepresentation)); try (Response resp = adminClient.realm("test").clientScopes().create(scopeRep)) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AudienceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AudienceTest.java index 7f349dcd6b0c..605660132b32 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AudienceTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AudienceTest.java @@ -119,7 +119,7 @@ public void beforeTest() { public void testAudienceProtocolMapperWithClientAudience() throws Exception { // Add audience protocol mapper to the clientScope "audience-scope" ProtocolMapperRepresentation audienceMapper = ProtocolMapperUtil.createAudienceMapper("audience mapper", "service-client", - null, true, false); + null, true, false, true); ClientScopeResource clientScope = ApiUtil.findClientScopeByName(testRealm(), "audience-scope"); Response resp = clientScope.getProtocolMappers().createMapper(audienceMapper); String mapperId = ApiUtil.getCreatedId(resp); @@ -131,7 +131,7 @@ public void testAudienceProtocolMapperWithClientAudience() throws Exception { EventRepresentation loginEvent = events.expectLogin() .user(userId) .assertEvent(); - Tokens tokens = sendTokenRequest(loginEvent, userId,"openid profile email audience-scope", "test-app"); + Tokens tokens = sendTokenRequest(loginEvent, userId, "openid profile email audience-scope", "test-app"); assertAudiences(tokens.accessToken, "service-client"); assertAudiences(tokens.idToken, "test-app"); @@ -145,14 +145,14 @@ public void testAudienceProtocolMapperWithClientAudience() throws Exception { public void testAudienceProtocolMapperWithCustomAudience() throws Exception { // Add audience protocol mapper to the clientScope "audience-scope" ProtocolMapperRepresentation audienceMapper = ProtocolMapperUtil.createAudienceMapper("audience mapper 1", null, - "http://host/service/ctx1", true, false); + "http://host/service/ctx1", true, false, true); ClientScopeResource clientScope = ApiUtil.findClientScopeByName(testRealm(), "audience-scope"); Response resp = clientScope.getProtocolMappers().createMapper(audienceMapper); String mapper1Id = ApiUtil.getCreatedId(resp); resp.close(); audienceMapper = ProtocolMapperUtil.createAudienceMapper("audience mapper 2", null, - "http://host/service/ctx2", true, true); + "http://host/service/ctx2", true, true, true); resp = clientScope.getProtocolMappers().createMapper(audienceMapper); String mapper2Id = ApiUtil.getCreatedId(resp); resp.close(); @@ -163,7 +163,7 @@ public void testAudienceProtocolMapperWithCustomAudience() throws Exception { EventRepresentation loginEvent = events.expectLogin() .user(userId) .assertEvent(); - Tokens tokens = sendTokenRequest(loginEvent, userId,"openid profile email audience-scope", "test-app"); + Tokens tokens = sendTokenRequest(loginEvent, userId, "openid profile email audience-scope", "test-app"); assertAudiences(tokens.accessToken, "http://host/service/ctx1", "http://host/service/ctx2"); assertAudiences(tokens.idToken, "test-app", "http://host/service/ctx2"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/LightWeightAccessTokenTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/LightWeightAccessTokenTest.java new file mode 100644 index 000000000000..63762cbd795d --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/LightWeightAccessTokenTest.java @@ -0,0 +1,472 @@ +package org.keycloak.testsuite.oidc; + +import jakarta.ws.rs.NotFoundException; +import org.junit.Before; +import org.junit.Test; +import org.keycloak.admin.client.resource.ClientScopeResource; +import org.keycloak.admin.client.resource.ProtocolMappersResource; +import org.keycloak.admin.client.resource.RealmResource; +import org.keycloak.common.Profile; +import org.keycloak.models.ProtocolMapperModel; +import org.keycloak.models.utils.ModelToRepresentation; +import org.keycloak.protocol.oidc.OIDCLoginProtocol; +import org.keycloak.protocol.oidc.mappers.AudienceProtocolMapper; +import org.keycloak.protocol.oidc.mappers.GroupMembershipMapper; +import org.keycloak.protocol.oidc.mappers.HardcodedClaim; +import org.keycloak.protocol.oidc.mappers.HardcodedRole; +import org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper; +import org.keycloak.protocol.oidc.mappers.RoleNameMapper; +import org.keycloak.protocol.oidc.mappers.SHA256PairwiseSubMapper; +import org.keycloak.protocol.oidc.mappers.UserSessionNoteMapper; +import org.keycloak.representations.AccessToken; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.ProtocolMapperRepresentation; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testsuite.AbstractKeycloakTest; +import org.keycloak.testsuite.admin.ApiUtil; +import org.keycloak.testsuite.arquillian.annotation.EnableFeature; +import org.keycloak.testsuite.util.ClientManager; +import org.keycloak.testsuite.util.KeycloakModelUtils; +import org.keycloak.testsuite.util.OAuthClient; +import org.keycloak.testsuite.util.ProtocolMapperUtil; +import org.keycloak.util.JsonSerialization; +import org.wildfly.common.Assert; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.keycloak.protocol.ProtocolMapperUtils.USER_SESSION_NOTE; +import static org.keycloak.protocol.oidc.OIDCLoginProtocolFactory.ACR; +import static org.keycloak.protocol.oidc.OIDCLoginProtocolFactory.ACR_SCOPE; +import static org.keycloak.protocol.oidc.OIDCLoginProtocolFactory.ADDRESS; +import static org.keycloak.protocol.oidc.OIDCLoginProtocolFactory.ALLOWED_WEB_ORIGINS; +import static org.keycloak.protocol.oidc.OIDCLoginProtocolFactory.AUDIENCE_RESOLVE; +import static org.keycloak.protocol.oidc.OIDCLoginProtocolFactory.CLIENT_ROLES; +import static org.keycloak.protocol.oidc.OIDCLoginProtocolFactory.EMAIL; +import static org.keycloak.protocol.oidc.OIDCLoginProtocolFactory.EMAIL_VERIFIED; +import static org.keycloak.protocol.oidc.OIDCLoginProtocolFactory.FAMILY_NAME; +import static org.keycloak.protocol.oidc.OIDCLoginProtocolFactory.FULL_NAME; +import static org.keycloak.protocol.oidc.OIDCLoginProtocolFactory.GIVEN_NAME; +import static org.keycloak.protocol.oidc.OIDCLoginProtocolFactory.PROFILE_CLAIM; +import static org.keycloak.protocol.oidc.OIDCLoginProtocolFactory.REALM_ROLES; +import static org.keycloak.protocol.oidc.OIDCLoginProtocolFactory.ROLES_SCOPE; +import static org.keycloak.protocol.oidc.OIDCLoginProtocolFactory.USERNAME; +import static org.keycloak.protocol.oidc.OIDCLoginProtocolFactory.WEB_ORIGINS_SCOPE; +import static org.keycloak.protocol.oidc.mappers.AbstractPairwiseSubMapper.PROVIDER_ID_SUFFIX; +import static org.keycloak.protocol.oidc.mappers.AudienceProtocolMapper.INCLUDED_CLIENT_AUDIENCE; +import static org.keycloak.protocol.oidc.mappers.HardcodedClaim.CLAIM_VALUE; +import static org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN; +import static org.keycloak.protocol.oidc.mappers.OIDCAttributeMapperHelper.INCLUDE_IN_INTROSPECTION; +import static org.keycloak.protocol.oidc.mappers.PairwiseSubMapperHelper.PAIRWISE_SUB_ALGORITHM_SALT; +import static org.keycloak.protocol.oidc.mappers.RoleNameMapper.NEW_ROLE_NAME; +import static org.keycloak.protocol.oidc.mappers.RoleNameMapper.ROLE_CONFIG; +import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson; +import static org.keycloak.testsuite.auth.page.AuthRealm.TEST; + +@EnableFeature(value = Profile.Feature.TOKEN_EXCHANGE, skipRestart = true) +public class LightWeightAccessTokenTest extends AbstractKeycloakTest { + + @Before + public void clientConfiguration() { + ClientManager.realm(adminClient.realm("test")).clientId("test-app").directAccessGrant(true).setServiceAccountsEnabled(true); + ClientManager.realm(adminClient.realm("test")).clientId("resource-server").directAccessGrant(true); + } + + @Override + public void addTestRealms(List testRealms) { + RealmRepresentation realm = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class); + UserRepresentation user = findUser(realm, "test-user@localhost"); + Map> attributes = new HashMap<>(){{ + put("street", Arrays.asList("1 My Street")); + put("locality", Arrays.asList("Cardiff")); + put("region", Arrays.asList("Cardiff")); + put("postal_code", Arrays.asList("CF104RA")); + }}; + user.setAttributes(attributes); + user.setGroups(Arrays.asList("/topGroup/level2group")); + ClientRepresentation confApp = KeycloakModelUtils.createClient(realm, "resource-server"); + confApp.setSecret("password"); + confApp.setServiceAccountsEnabled(Boolean.TRUE); + testRealms.add(realm); + } + + private UserRepresentation findUser(RealmRepresentation testRealm, String userName) { + for (UserRepresentation user : testRealm.getUsers()) { + if (user.getUsername().equals(userName)) return user; + } + + return null; + } + + @Test + public void accessTokenFalseIntrospectionTrueTest() throws IOException { + ProtocolMappersResource protocolMappers = setProtocolMappers(false, true, true); + try { + oauth.nonce("123456"); + oauth.scope("address"); + oauth.clientId("test-app"); + OAuthClient.AccessTokenResponse response = browserLogin("password", "test-user@localhost", "password").tokenResponse; + String accessToken = response.getAccessToken(); + System.out.println("accessToken:" + accessToken); + assertAccessToken(oauth.verifyToken(accessToken), true, false); + + oauth.clientId("resource-server"); + String tokenResponse = oauth.introspectAccessTokenWithClientCredential("resource-server", "password", accessToken); + System.out.println("tokenResponse:" + tokenResponse); + assertTokenIntrospectionResponse(JsonSerialization.readValue(tokenResponse, AccessToken.class), true, true, false); + } finally { + deleteProtocolMappers(protocolMappers); + } + } + + @Test + public void accessTokenTrueIntrospectionFalseTest() throws IOException { + ProtocolMappersResource protocolMappers = setProtocolMappers(true, false, true); + try { + oauth.nonce("123456"); + oauth.scope("address"); + oauth.clientId("test-app"); + OAuthClient.AccessTokenResponse response = browserLogin("password", "test-user@localhost", "password").tokenResponse; + String accessToken = response.getAccessToken(); + System.out.println("accessToken:" + accessToken); + assertAccessToken(oauth.verifyToken(accessToken), true, true); + + oauth.clientId("resource-server"); + String tokenResponse = oauth.introspectAccessTokenWithClientCredential("resource-server", "password", accessToken); + System.out.println("tokenResponse:" + tokenResponse); + // Most of the claims should not be included in introspectionResponse as introspectionMapper was disabled + assertTokenIntrospectionResponse(JsonSerialization.readValue(tokenResponse, AccessToken.class), true, false, false); + } finally { + deleteProtocolMappers(protocolMappers); + } + } + + @Test + public void accessTokenTrueIntrospectionTrueTest() throws IOException { + ProtocolMappersResource protocolMappers = setProtocolMappers(true, true, true); + try { + oauth.nonce("123456"); + oauth.scope("address"); + oauth.clientId("test-app"); + OAuthClient.AccessTokenResponse response = browserLogin("password", "test-user@localhost", "password").tokenResponse; + String accessToken = response.getAccessToken(); + System.out.println("accessToken:" + accessToken); + assertAccessToken(oauth.verifyToken(accessToken), true, true); + + oauth.clientId("resource-server"); + String tokenResponse = oauth.introspectAccessTokenWithClientCredential("resource-server", "password", accessToken); + System.out.println("tokenResponse:" + tokenResponse); + assertTokenIntrospectionResponse(JsonSerialization.readValue(tokenResponse, AccessToken.class), true, true, false); + } finally { + deleteProtocolMappers(protocolMappers); + } + } + + @Test + public void offlineTokenTest() throws IOException { + ProtocolMappersResource protocolMappers = setProtocolMappers(false, true, true); + try { + oauth.nonce("123456"); + oauth.scope("openid address offline_access"); + + oauth.clientId("test-app"); + TokenResponseContext ctx = browserLogin("password", "test-user@localhost", "password"); + OAuthClient.AccessTokenResponse response = ctx.tokenResponse; + String accessToken = response.getAccessToken(); + System.out.println("accessToken:" + accessToken); + System.out.println("idtoken:" + response.getIdToken()); + assertAccessToken(oauth.verifyToken(accessToken), true, false); + + oauth.clientId("resource-server"); + removeSession(ctx.userSessionId); + String tokenResponse = oauth.introspectAccessTokenWithClientCredential("resource-server", "password", accessToken); + System.out.println("tokenResponse:" + tokenResponse); + assertTokenIntrospectionResponse(JsonSerialization.readValue(tokenResponse, AccessToken.class), true, true, false); + } finally { + deleteProtocolMappers(protocolMappers); + } + } + + private void removeSession(final String sessionId) { + testingClient.testing().removeExpired("test"); + try { + testingClient.testing().removeUserSession("test", sessionId); + } catch (NotFoundException nfe) { + // Ignore + } + } + + @Test + public void clientCredentialTest() throws Exception { + ProtocolMappersResource protocolMappers = setProtocolMappers(false, true, false); + try { + oauth.nonce("123456"); + oauth.scope("address"); + + oauth.clientId("test-app"); + OAuthClient.AccessTokenResponse response = oauth.doClientCredentialsGrantAccessTokenRequest("password"); + String accessToken = response.getAccessToken(); + System.out.println("accessToken:" + accessToken); + assertAccessToken(oauth.verifyToken(accessToken), false, false); + + oauth.clientId("resource-server"); + String tokenResponse = oauth.introspectAccessTokenWithClientCredential("resource-server", "password", accessToken); + System.out.println("tokenResponse:" + tokenResponse); + assertTokenIntrospectionResponse(JsonSerialization.readValue(tokenResponse, AccessToken.class), false); + } finally { + deleteProtocolMappers(protocolMappers); + } + } + + @Test + public void exchangeTest() throws Exception { + ProtocolMappersResource protocolMappers = setProtocolMappers(false, true, true); + try { + oauth.nonce("123456"); + oauth.scope("address"); + + oauth.clientId("test-app"); + OAuthClient.AccessTokenResponse response = browserLogin("password", "test-user@localhost", "password").tokenResponse; + String accessToken = response.getAccessToken(); + System.out.println("accessToken:" + accessToken); + assertAccessToken(oauth.verifyToken(accessToken), true, false); + response = oauth.doTokenExchange(TEST, accessToken, null, "test-app", "password"); + String exchangedTokenString = response.getAccessToken(); + System.out.println("exchangedTokenString:" + exchangedTokenString); + + oauth.clientId("resource-server"); + String tokenResponse = oauth.introspectAccessTokenWithClientCredential("resource-server", "password", exchangedTokenString); + System.out.println("tokenResponse:" + tokenResponse); + assertTokenIntrospectionResponse(JsonSerialization.readValue(tokenResponse, AccessToken.class), true, true, true); + } finally { + deleteProtocolMappers(protocolMappers); + } + } + + private void assertMapperClaims(AccessToken token, boolean isAddMapperResponseFlag, boolean isAuthCodeFlow) { + if (isAddMapperResponseFlag) { + if (isAuthCodeFlow) { + Assert.assertNotNull(token.getName()); + Assert.assertNotNull(token.getGivenName()); + Assert.assertNotNull(token.getFamilyName()); + Assert.assertNotNull(token.getAddress()); + Assert.assertNotNull(token.getEmail()); + Assert.assertNotNull(token.getOtherClaims().get("user-session-note")); + Assert.assertNotNull(token.getOtherClaims().get("test-claim")); + Assert.assertNotNull(token.getOtherClaims().get("group-name")); + } + Assert.assertNotNull(token.getAudience()); + Assert.assertNotNull(token.getAcr()); + Assert.assertNotNull(token.getAllowedOrigins()); + Assert.assertNotNull(token.getRealmAccess()); + Assert.assertNotNull(token.getResourceAccess()); + Assert.assertNotNull(token.getEmailVerified()); + Assert.assertNotNull(token.getPreferredUsername()); + } else { + if (isAuthCodeFlow) { + Assert.assertTrue(token.getName() == null); + Assert.assertTrue(token.getGivenName() == null); + Assert.assertTrue(token.getFamilyName() == null); + Assert.assertTrue(token.getAddress() == null); + Assert.assertTrue(token.getEmail() == null); + Assert.assertTrue(token.getOtherClaims().get("user-session-note") == null); + Assert.assertTrue(token.getOtherClaims().get("test-claim") == null); + Assert.assertTrue(token.getOtherClaims().get("group-name") == null); + } + Assert.assertTrue(token.getAcr() == null); + Assert.assertTrue(token.getAllowedOrigins() == null); + Assert.assertTrue(token.getRealmAccess() == null); + Assert.assertTrue(token.getResourceAccess().isEmpty()); + Assert.assertTrue(token.getEmailVerified() == null); + Assert.assertTrue(token.getPreferredUsername() == null); + } + } + + private void assertInitClaims(AccessToken token, boolean isAuthCodeFlow) { + Assert.assertNotNull(token.getExp()); + Assert.assertNotNull(token.getIat()); + Assert.assertNotNull(token.getId()); + Assert.assertNotNull(token.getType()); + if (isAuthCodeFlow) { + Assert.assertNotNull(token.getSessionId()); + Assert.assertNotNull(token.getAuth_time()); + } else { + Assert.assertTrue(token.getSessionId() == null); + Assert.assertTrue(token.getAuth_time() == null); + } + Assert.assertNotNull(token.getIssuedFor()); + Assert.assertNotNull(token.getScope()); + Assert.assertNotNull(token.getIssuer()); + } + + private void assertIntrospectClaims(AccessToken token) { + Assert.assertNotNull(token.getOtherClaims().get("client_id")); + Assert.assertNotNull(token.getOtherClaims().get("active")); + Assert.assertNotNull(token.getOtherClaims().get("token_type")); + } + + private void assertNonce(AccessToken token, boolean isAuthCodeFlow, boolean exchangeToken) { + if (isAuthCodeFlow && !exchangeToken) { + Assert.assertNotNull(token.getNonce()); + } else { + Assert.assertTrue(token.getNonce() == null); + } + } + + private void assertAccessToken(AccessToken token, boolean isAuthCodeFlow, boolean isAddToAccessToken) { + assertNonce(token, isAuthCodeFlow, false); + assertMapperClaims(token, isAddToAccessToken, isAuthCodeFlow); + assertInitClaims(token, isAuthCodeFlow); + } + + private void assertTokenIntrospectionResponse(AccessToken token, boolean isAuthCodeFlow) { + assertTokenIntrospectionResponse(token, isAuthCodeFlow, true, false); + } + + private void assertTokenIntrospectionResponse(AccessToken token, boolean isAuthCodeFlow, boolean isAddToIntrospect, boolean exchangeToken) { + assertNonce(token, isAuthCodeFlow, exchangeToken); + assertMapperClaims(token, isAddToIntrospect, isAuthCodeFlow); + assertInitClaims(token, isAuthCodeFlow); + assertIntrospectClaims(token); + } + + protected RealmResource testRealm() { + return adminClient.realm("test"); + } + + private void setScopeProtocolMappers(boolean isIncludeAccessToken, boolean isIncludeIntrospection) { + setScopeProtocolMapper(ACR_SCOPE, ACR, isIncludeAccessToken, isIncludeIntrospection); + setScopeProtocolMapper(PROFILE_CLAIM, FULL_NAME, isIncludeAccessToken, isIncludeIntrospection); + setScopeProtocolMapper(EMAIL, EMAIL, isIncludeAccessToken, isIncludeIntrospection); + setScopeProtocolMapper(EMAIL, EMAIL_VERIFIED, isIncludeAccessToken, isIncludeIntrospection); + setScopeProtocolMapper(PROFILE_CLAIM, GIVEN_NAME, isIncludeAccessToken, isIncludeIntrospection); + setScopeProtocolMapper(PROFILE_CLAIM, FAMILY_NAME, isIncludeAccessToken, isIncludeIntrospection); + setScopeProtocolMapper(PROFILE_CLAIM, USERNAME, isIncludeAccessToken, isIncludeIntrospection); + setScopeProtocolMapper(WEB_ORIGINS_SCOPE, ALLOWED_WEB_ORIGINS, isIncludeAccessToken, isIncludeIntrospection); + setScopeProtocolMapper(ROLES_SCOPE, REALM_ROLES, isIncludeAccessToken, isIncludeIntrospection); + setScopeProtocolMapper(ROLES_SCOPE, CLIENT_ROLES, isIncludeAccessToken, isIncludeIntrospection); + setScopeProtocolMapper(ROLES_SCOPE, AUDIENCE_RESOLVE, isIncludeAccessToken, isIncludeIntrospection); + setScopeProtocolMapper(ADDRESS, ADDRESS, isIncludeAccessToken, isIncludeIntrospection); + } + + private void setScopeProtocolMapper(String scopeName, String mapperName, boolean isIncludeAccessToken, boolean isIncludeIntrospection) { + ClientScopeResource scope = ApiUtil.findClientScopeByName(testRealm(), scopeName); + ProtocolMapperRepresentation protocolMapper = ApiUtil.findProtocolMapperByName(scope, mapperName); + Map config = protocolMapper.getConfig(); + if (isIncludeAccessToken) { + config.put(INCLUDE_IN_ACCESS_TOKEN, "true"); + } else { + config.put(INCLUDE_IN_ACCESS_TOKEN, "false"); + } + if (isIncludeIntrospection) { + config.put(INCLUDE_IN_INTROSPECTION, "true"); + } else { + config.put(INCLUDE_IN_INTROSPECTION, "false"); + } + scope.getProtocolMappers().update(protocolMapper.getId(), protocolMapper); + } + + private ProtocolMappersResource setProtocolMappers(boolean isIncludeAccessToken, boolean isIncludeIntrospection, boolean setPairWise) { + setScopeProtocolMappers(isIncludeAccessToken, isIncludeIntrospection); + List protocolMapperList = new ArrayList<>(); + setExistingProtocolMappers(protocolMapperList, isIncludeAccessToken, isIncludeIntrospection, setPairWise); + ProtocolMappersResource protocolMappers = ApiUtil.findClientResourceByClientId(adminClient.realm("test"), "test-app").getProtocolMappers(); + protocolMappers.createMapper(protocolMapperList); + return protocolMappers; + } + + private void setExistingProtocolMappers(List protocolMapperList, boolean isIncludeAccessToken, boolean isIncludeIntrospection, boolean setPairWise) { + Map config = new HashMap<>(); + if (isIncludeAccessToken) { + config.put(INCLUDE_IN_ACCESS_TOKEN, "true"); + } else { + config.put(INCLUDE_IN_ACCESS_TOKEN, "false"); + } + + if (isIncludeIntrospection) { + config.put(INCLUDE_IN_INTROSPECTION, "true"); + } else { + config.put(INCLUDE_IN_INTROSPECTION, "false"); + } + + ProtocolMapperRepresentation audienceProtocolMapper = createClaimMapper("audience", AudienceProtocolMapper.PROVIDER_ID, new HashMap<>(config) {{ + put(INCLUDED_CLIENT_AUDIENCE, "account-console"); + }}); + protocolMapperList.add(audienceProtocolMapper); + ProtocolMapperRepresentation roleNameMapper = createClaimMapper("role-name", RoleNameMapper.PROVIDER_ID, new HashMap<>(config) {{ + put(ROLE_CONFIG, "user"); + put(NEW_ROLE_NAME, "new-role"); + }}); + protocolMapperList.add(roleNameMapper); + ProtocolMapperRepresentation groupMembershipMapper = createClaimMapper("group-member", GroupMembershipMapper.PROVIDER_ID, new HashMap<>(config) {{ + put(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME, "group-name"); + }}); + protocolMapperList.add(groupMembershipMapper); + ProtocolMapperRepresentation hardcodedClaim = createClaimMapper("hardcoded-claim", HardcodedClaim.PROVIDER_ID, new HashMap<>(config) {{ + put(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME, "test-claim"); + put(CLAIM_VALUE, "test-value"); + }}); + protocolMapperList.add(hardcodedClaim); + ProtocolMapperRepresentation hardcodedRole = createClaimMapper("hardcoded-role", HardcodedRole.PROVIDER_ID, new HashMap<>(config) {{ + put(ROLE_CONFIG, "hardcoded-role"); + }}); + protocolMapperList.add(hardcodedRole); + ProtocolMapperRepresentation userSessionNoteMapper = createClaimMapper("user-session-note", UserSessionNoteMapper.PROVIDER_ID, new HashMap<>(config) {{ + put(OIDCAttributeMapperHelper.TOKEN_CLAIM_NAME, "user-session-note"); + put(USER_SESSION_NOTE, "AUTH_TIME"); + }}); + protocolMapperList.add(userSessionNoteMapper); + if (setPairWise) { + ProtocolMapperRepresentation pairwiseSubMapper = createClaimMapper("pairwise-sub-mapper", "oidc-" + SHA256PairwiseSubMapper.PROVIDER_ID + PROVIDER_ID_SUFFIX, new HashMap<>(config) {{ + put(PAIRWISE_SUB_ALGORITHM_SALT, "abc"); + }}); + protocolMapperList.add(pairwiseSubMapper); + } + } + + private static ProtocolMapperRepresentation createClaimMapper(String name, String providerId, Map config) { + ProtocolMapperModel mapper = new ProtocolMapperModel(); + mapper.setName(name); + mapper.setProtocolMapper(providerId); + mapper.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL); + mapper.setConfig(config); + return ModelToRepresentation.toRepresentation(mapper); + } + + private void deleteProtocolMappers(ProtocolMappersResource protocolMappers) { + List mapperNames = new ArrayList<>(Arrays.asList("reference", "audience", "role-name", "group-member", "hardcoded-claim", "hardcoded-role", "user-session-note", "pairwise-sub-mapper")); + List mappers = new ArrayList<>(); + for (String mapperName : mapperNames) { + mappers.add(ProtocolMapperUtil.getMapperByNameAndProtocol(protocolMappers, OIDCLoginProtocol.LOGIN_PROTOCOL, mapperName)); + } + + for (ProtocolMapperRepresentation mapper : mappers) { + if (mapper != null) { + protocolMappers.delete(mapper.getId()); + } + } + } + + private TokenResponseContext browserLogin(String clientSecret, String username, String password) { + OAuthClient.AuthorizationEndpointResponse authsEndpointResponse = oauth.doLogin(username, password); + String userSessionId = authsEndpointResponse.getSessionState(); + OAuthClient.AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(authsEndpointResponse.getCode(), clientSecret); + return new TokenResponseContext(userSessionId, tokenResponse); + } + + private class TokenResponseContext { + + private final String userSessionId; + private final OAuthClient.AccessTokenResponse tokenResponse; + + public TokenResponseContext(String userSessionId, OAuthClient.AccessTokenResponse tokenResponse) { + this.userSessionId = userSessionId; + this.tokenResponse = tokenResponse; + } + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/script/DeployedScriptMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/script/DeployedScriptMapperTest.java index 5f357b5ca8a4..af0134fd7ded 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/script/DeployedScriptMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/script/DeployedScriptMapperTest.java @@ -92,7 +92,7 @@ public void testTokenScriptMapping() { ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app"); ProtocolMapperRepresentation mapper = createScriptMapper("test-script-mapper1", "computed-via-script", - "computed-via-script", "String", true, true, "'hello_' + user.username", false); + "computed-via-script", "String", true, true, true, "'hello_' + user.username", false); mapper.setProtocolMapper("script-mapper-a.js"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/script/UndeployedScriptMapperNotAvailableTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/script/UndeployedScriptMapperNotAvailableTest.java index ca7c87726a30..df03132bbc06 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/script/UndeployedScriptMapperNotAvailableTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/script/UndeployedScriptMapperNotAvailableTest.java @@ -95,7 +95,7 @@ public void testMapperNotRecognizedWhenDisabled() throws Exception { ClientResource app = findClientResourceByClientId(adminClient.realm("test"), "test-app"); { ProtocolMapperRepresentation mapper = createScriptMapper("test-script-mapper1", "computed-via-script", - "computed-via-script", "String", true, true, "'hello_' + user.username", false); + "computed-via-script", "String", true, true, true, "'hello_' + user.username", false); mapper.setProtocolMapper("script-mapper-a.js"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ProtocolMapperUtil.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ProtocolMapperUtil.java index e636ad86f216..371758f6434e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ProtocolMapperUtil.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/util/ProtocolMapperUtil.java @@ -47,8 +47,8 @@ public static ProtocolMapperRepresentation createHardcodedRole(String name, * @param accessToken * @return */ - public static ProtocolMapperRepresentation createAddressMapper(boolean idToken, boolean accessToken, boolean userInfo) { - return ModelToRepresentation.toRepresentation(AddressMapper.createAddressMapper(idToken, accessToken, userInfo)); + public static ProtocolMapperRepresentation createAddressMapper(boolean idToken, boolean accessToken, boolean userInfo, boolean introspectionEndpoint) { + return ModelToRepresentation.toRepresentation(AddressMapper.createAddressMapper(idToken, accessToken, userInfo, introspectionEndpoint)); } /** @@ -65,9 +65,9 @@ public static ProtocolMapperRepresentation createAddressMapper(boolean idToken, public static ProtocolMapperRepresentation createHardcodedClaim(String name, String hardcodedName, String hardcodedValue, String claimType, - boolean accessToken, boolean idToken) { + boolean accessToken, boolean idToken, boolean introspectionEndpoint) { return ModelToRepresentation.toRepresentation(HardcodedClaim.create(name, hardcodedName, hardcodedValue, - claimType, accessToken, idToken)); + claimType, accessToken, idToken, introspectionEndpoint)); } /** @@ -85,64 +85,64 @@ public static ProtocolMapperRepresentation createHardcodedClaim(String name, public static ProtocolMapperRepresentation createClaimMapper(String name, String userAttribute, String tokenClaimName, String claimType, - boolean accessToken, boolean idToken, boolean multivalued) { + boolean accessToken, boolean idToken, boolean introspectionEndpoint, boolean multivalued) { return ModelToRepresentation.toRepresentation(UserAttributeMapper.createClaimMapper(name, userAttribute, tokenClaimName, - claimType, accessToken, idToken, multivalued, false)); + claimType, accessToken, idToken, introspectionEndpoint, multivalued, false)); } public static ProtocolMapperRepresentation createClaimMapper(String name, String userAttribute, String tokenClaimName, String claimType, - boolean accessToken, boolean idToken, + boolean accessToken, boolean idToken, boolean introspectionEndpoint, boolean multivalued, boolean aggregateAttrs) { return ModelToRepresentation.toRepresentation(UserAttributeMapper.createClaimMapper(name, userAttribute, tokenClaimName, - claimType, accessToken, idToken, multivalued, aggregateAttrs)); + claimType, accessToken, idToken, introspectionEndpoint, multivalued, aggregateAttrs)); } public static ProtocolMapperRepresentation createClaimMapper(String name, String userSessionNote, String tokenClaimName, String jsonType, - boolean accessToken, boolean idToken) { + boolean accessToken, boolean idToken, boolean introspectionEndpoint) { return ModelToRepresentation.toRepresentation(UserSessionNoteMapper.createClaimMapper(name, userSessionNote, tokenClaimName, jsonType, - accessToken, idToken)); + accessToken, idToken, introspectionEndpoint)); } public static ProtocolMapperRepresentation createUserRealmRoleMappingMapper(String realmRolePrefix, String name, String tokenClaimName, - boolean accessToken, boolean idToken) { + boolean accessToken, boolean idToken, boolean introspectionEndpoint) { - return createUserRealmRoleMappingMapper(realmRolePrefix, name, tokenClaimName, accessToken, idToken, true); + return createUserRealmRoleMappingMapper(realmRolePrefix, name, tokenClaimName, accessToken, idToken, introspectionEndpoint, true); } public static ProtocolMapperRepresentation createUserRealmRoleMappingMapper(String realmRolePrefix, String name, String tokenClaimName, - boolean accessToken, boolean idToken, boolean multiValued) { + boolean accessToken, boolean idToken, boolean introspectionEndpoint, boolean multiValued) { - return ModelToRepresentation.toRepresentation(UserRealmRoleMappingMapper.create(realmRolePrefix, name, tokenClaimName, accessToken, idToken, multiValued)); + return ModelToRepresentation.toRepresentation(UserRealmRoleMappingMapper.create(realmRolePrefix, name, tokenClaimName, accessToken, idToken, introspectionEndpoint, multiValued)); } public static ProtocolMapperRepresentation createUserClientRoleMappingMapper(String clientId, String clientRolePrefix, String name, String tokenClaimName, - boolean accessToken, boolean idToken) { + boolean accessToken, boolean idToken, boolean introspectionEndpoint) { - return createUserClientRoleMappingMapper(clientId, clientRolePrefix, name, tokenClaimName, accessToken, idToken, true); + return createUserClientRoleMappingMapper(clientId, clientRolePrefix, name, tokenClaimName, accessToken, idToken, introspectionEndpoint, true); } public static ProtocolMapperRepresentation createUserClientRoleMappingMapper(String clientId, String clientRolePrefix, String name, String tokenClaimName, - boolean accessToken, boolean idToken, boolean multiValued) { + boolean accessToken, boolean idToken, boolean introspectionEndpoint, boolean multiValued) { - return ModelToRepresentation.toRepresentation(UserClientRoleMappingMapper.create(clientId, clientRolePrefix, name, tokenClaimName, accessToken, idToken, multiValued)); + return ModelToRepresentation.toRepresentation(UserClientRoleMappingMapper.create(clientId, clientRolePrefix, name, tokenClaimName, accessToken, idToken, introspectionEndpoint, multiValued)); } public static ProtocolMapperRepresentation getMapperByNameAndProtocol(ProtocolMappersResource protocolMappers, String protocol, String name) { @@ -160,11 +160,12 @@ public static ProtocolMapperRepresentation createScriptMapper(String name, String claimType, boolean accessToken, boolean idToken, + boolean introspectionEndpoint, String script, boolean multiValued) { return ModelToRepresentation.toRepresentation( - ScriptBasedOIDCProtocolMapper.create(name, userAttribute, tokenClaimName, claimType, accessToken, idToken, script, multiValued) + ScriptBasedOIDCProtocolMapper.create(name, userAttribute, tokenClaimName, claimType, accessToken, idToken, introspectionEndpoint, script, multiValued) ); } @@ -175,10 +176,10 @@ public static ProtocolMapperRepresentation createPairwiseMapper(String sectorIde public static ProtocolMapperRepresentation createAudienceMapper(String name, String includedClientAudience, String includedCustomAudience, - boolean accessToken, boolean idToken) { + boolean accessToken, boolean idToken, boolean introspectionEndpoint) { return ModelToRepresentation.toRepresentation( - AudienceProtocolMapper.createClaimMapper(name, includedClientAudience, includedCustomAudience, accessToken, idToken) + AudienceProtocolMapper.createClaimMapper(name, includedClientAudience, includedCustomAudience, accessToken, idToken, introspectionEndpoint) ); } } From 96674e475f475440fbdd38e33cbad31609926475 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 13:20:59 +0200 Subject: [PATCH 26/27] Bump @faker-js/faker from 8.1.0 to 8.2.0 in /js (#23994) Bumps [@faker-js/faker](https://github.com/faker-js/faker) from 8.1.0 to 8.2.0. - [Release notes](https://github.com/faker-js/faker/releases) - [Changelog](https://github.com/faker-js/faker/blob/next/CHANGELOG.md) - [Commits](https://github.com/faker-js/faker/compare/v8.1.0...v8.2.0) --- updated-dependencies: - dependency-name: "@faker-js/faker" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- js/libs/keycloak-admin-client/package.json | 2 +- js/pnpm-lock.yaml | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/js/libs/keycloak-admin-client/package.json b/js/libs/keycloak-admin-client/package.json index 92dcf3464927..5f1c7d8e1bc8 100644 --- a/js/libs/keycloak-admin-client/package.json +++ b/js/libs/keycloak-admin-client/package.json @@ -43,7 +43,7 @@ "url-template": "^3.1.0" }, "devDependencies": { - "@faker-js/faker": "^8.1.0", + "@faker-js/faker": "^8.2.0", "@types/chai": "^4.3.8", "@types/lodash-es": "^4.17.9", "@types/mocha": "^10.0.2", diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index db8fb2e96c00..111f3a208c86 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -327,8 +327,8 @@ importers: version: 3.1.0 devDependencies: '@faker-js/faker': - specifier: ^8.1.0 - version: 8.1.0 + specifier: ^8.2.0 + version: 8.2.0 '@types/chai': specifier: ^4.3.8 version: 4.3.8 @@ -819,8 +819,8 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@faker-js/faker@8.1.0: - resolution: {integrity: sha512-38DT60rumHfBYynif3lmtxMqMqmsOQIxQgEuPZxCk2yUYN0eqWpTACgxi0VpidvsJB8CRxCpvP7B3anK85FjtQ==} + /@faker-js/faker@8.2.0: + resolution: {integrity: sha512-VacmzZqVxdWdf9y64lDOMZNDMM/FQdtM9IsaOPKOm2suYwEatb8VkdHqOzXcDnZbk7YDE2BmsJmy/2Hmkn563g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0, npm: '>=6.14.13'} dev: true From 0d008df416744d90a550927e74dd325b744ff235 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 17 Oct 2023 13:21:19 +0200 Subject: [PATCH 27/27] Bump @playwright/test from 1.38.1 to 1.39.0 in /js (#23925) Bumps [@playwright/test](https://github.com/microsoft/playwright) from 1.38.1 to 1.39.0. - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.38.1...v1.39.0) --- updated-dependencies: - dependency-name: "@playwright/test" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- js/apps/account-ui/package.json | 2 +- js/pnpm-lock.yaml | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/js/apps/account-ui/package.json b/js/apps/account-ui/package.json index 95906bd0d937..cc2dd73affc0 100644 --- a/js/apps/account-ui/package.json +++ b/js/apps/account-ui/package.json @@ -27,7 +27,7 @@ }, "devDependencies": { "@keycloak/keycloak-admin-client": "workspace:*", - "@playwright/test": "^1.38.1", + "@playwright/test": "^1.39.0", "@types/lodash-es": "^4.17.9", "@types/react": "^18.2.28", "@types/react-dom": "^18.2.13", diff --git a/js/pnpm-lock.yaml b/js/pnpm-lock.yaml index 111f3a208c86..0712e92b9335 100644 --- a/js/pnpm-lock.yaml +++ b/js/pnpm-lock.yaml @@ -118,8 +118,8 @@ importers: specifier: workspace:* version: link:../../libs/keycloak-admin-client '@playwright/test': - specifier: ^1.38.1 - version: 1.38.1 + specifier: ^1.39.0 + version: 1.39.0 '@types/lodash-es': specifier: ^4.17.9 version: 4.17.9 @@ -1162,12 +1162,12 @@ packages: tslib: 2.6.2 dev: true - /@playwright/test@1.38.1: - resolution: {integrity: sha512-NqRp8XMwj3AK+zKLbZShl0r/9wKgzqI/527bkptKXomtuo+dOjU9NdMASQ8DNC9z9zLOMbG53T4eihYr3XR+BQ==} + /@playwright/test@1.39.0: + resolution: {integrity: sha512-3u1iFqgzl7zr004bGPYiN/5EZpRUSFddQBra8Rqll5N0/vfpqlP9I9EXqAoGacuAbX6c9Ulg/Cjqglp5VkK6UQ==} engines: {node: '>=16'} hasBin: true dependencies: - playwright: 1.38.1 + playwright: 1.39.0 dev: true /@reactflow/background@11.3.4(@types/react@18.2.28)(react-dom@18.2.0)(react@18.2.0): @@ -5694,18 +5694,18 @@ packages: pathe: 1.1.1 dev: true - /playwright-core@1.38.1: - resolution: {integrity: sha512-tQqNFUKa3OfMf4b2jQ7aGLB8o9bS3bOY0yMEtldtC2+spf8QXG9zvXLTXUeRsoNuxEYMgLYR+NXfAa1rjKRcrg==} + /playwright-core@1.39.0: + resolution: {integrity: sha512-+k4pdZgs1qiM+OUkSjx96YiKsXsmb59evFoqv8SKO067qBA+Z2s/dCzJij/ZhdQcs2zlTAgRKfeiiLm8PQ2qvw==} engines: {node: '>=16'} hasBin: true dev: true - /playwright@1.38.1: - resolution: {integrity: sha512-oRMSJmZrOu1FP5iu3UrCx8JEFRIMxLDM0c/3o4bpzU5Tz97BypefWf7TuTNPWeCe279TPal5RtPPZ+9lW/Qkow==} + /playwright@1.39.0: + resolution: {integrity: sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==} engines: {node: '>=16'} hasBin: true dependencies: - playwright-core: 1.38.1 + playwright-core: 1.39.0 optionalDependencies: fsevents: 2.3.2 dev: true