diff --git a/js/libs/keycloak-js/lib/keycloak.d.ts b/js/libs/keycloak-js/lib/keycloak.d.ts index 8597128837..da86a41a96 100644 --- a/js/libs/keycloak-js/lib/keycloak.d.ts +++ b/js/libs/keycloak-js/lib/keycloak.d.ts @@ -28,7 +28,7 @@ export interface KeycloakConfig { /** * URL to the Keycloak server, for example: http://keycloak-server/auth */ - url?: string; + url: string; /** * Name of the realm, for example: 'myrealm' */ @@ -373,7 +373,7 @@ declare class Keycloak { * Creates a new Keycloak client instance. * @param config A configuration object or path to a JSON config file. */ - constructor(config?: KeycloakConfig | string) + constructor(config: KeycloakConfig | string) /** * Is true if the user is authenticated, false otherwise. diff --git a/js/libs/keycloak-js/lib/keycloak.js b/js/libs/keycloak-js/lib/keycloak.js index a465928c71..20fa698f39 100755 --- a/js/libs/keycloak-js/lib/keycloak.js +++ b/js/libs/keycloak-js/lib/keycloak.js @@ -19,6 +19,22 @@ function Keycloak (config) { throw new Error("The 'Keycloak' constructor must be invoked with 'new'.") } + if (typeof config !== 'string' && !isObject(config)) { + throw new Error("The 'Keycloak' constructor must be provided with a configuration object, or a URL to a JSON configuration file."); + } + + if (isObject(config)) { + const requiredProperties = 'oidcProvider' in config + ? ['clientId'] + : ['url', 'realm', 'clientId']; + + for (const property of requiredProperties) { + if (!config[property]) { + throw new Error(`The configuration object is missing the required '${property}' property.`); + } + } + } + var kc = this; var adapter; var refreshQueue = []; @@ -175,7 +191,7 @@ function Keycloak (config) { promise.setError(error); }); - var configPromise = loadConfig(config); + var configPromise = loadConfig(); function onLoad() { var doLogin = function(prompt) { @@ -797,13 +813,11 @@ function Keycloak (config) { } - function loadConfig(url) { + function loadConfig() { var promise = createPromise(); var configUrl; - if (!config) { - configUrl = 'keycloak.json'; - } else if (typeof config === 'string') { + if (typeof config === 'string') { configUrl = config; } @@ -888,27 +902,10 @@ function Keycloak (config) { req.send(); } else { - if (!config.clientId) { - throw 'clientId missing'; - } - kc.clientId = config.clientId; var oidcProvider = config['oidcProvider']; if (!oidcProvider) { - if (!config['url']) { - var scripts = document.getElementsByTagName('script'); - for (var i = 0; i < scripts.length; i++) { - if (scripts[i].src.match(/.*keycloak\.js/)) { - config.url = scripts[i].src.substr(0, scripts[i].src.indexOf('/js/keycloak.js')); - break; - } - } - } - if (!config.realm) { - throw 'realm missing'; - } - kc.authServerUrl = config.url; kc.realm = config.realm; setupOidcEndoints(null); @@ -1815,3 +1812,11 @@ function b64DecodeUnicode(input) { return "%" + code; })); } + +/** + * Check if the input is an object that can be operated on. + * @param {unknown} input + */ +function isObject(input) { + return typeof input === 'object' && input !== null; +} diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/javascript/JavascriptTestExecutor.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/javascript/JavascriptTestExecutor.java index 60bb06f6a1..44c31e6da9 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/javascript/JavascriptTestExecutor.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/util/javascript/JavascriptTestExecutor.java @@ -171,7 +171,7 @@ public class JavascriptTestExecutor { jsExecutor.executeScript("console.warn = event;"); if (argumentsBuilder == null) { - jsExecutor.executeScript("window.keycloak = new Keycloak();"); + jsExecutor.executeScript("window.keycloak = new Keycloak('./keycloak.json');"); } else { String configArguments = argumentsBuilder.build(); jsExecutor.executeScript("window.keycloak = new Keycloak(" + configArguments + ");");