diff --git a/packages/auth/README.md b/packages/auth/README.md index cf45241ffd6794c9c133b22e7cc5eb8a57033789..67c756aed377e335a97e756cb407d740b3f8ec0d 100644 --- a/packages/auth/README.md +++ b/packages/auth/README.md @@ -7,7 +7,7 @@ ### Usage ```html -<vpu-auth-keycloak></vpu-auth-keycloak> +<vpu-auth-keycloak url="https://auth.tugraz.at/auth" realm="tugraz" client-id="some-id"></vpu-auth-keycloak> ``` ### Attributes @@ -22,16 +22,14 @@ - `try-login` (optional, default: off): if enabled the a login will happen if the user is already logged in and finishing the login process would not result in a page location change (reload/redirect). - example `<vpu-auth-keycloak try-login></vpu-auth-keycloak>` -- `keycloak-config`: An object which can contain the following keys: url, realm, clientId, silentCheckSsoRedirectUri - - example `<vpu-auth-keycloak keycloak-config='{"url": "https://auth.tugraz.at/auth", "realm": "tugraz", "clientId": "some-id", "silentCheckSsoRedirectUri": "", "scope": ""}'></vpu-auth-keycloak>` -### Keycloak Config +### Keycloak Specific Attributes -- `url`: The base URL of the Keycloak server -- `realm`: The Keycloak realm -- `clientId`: The Keycloak client to use -- `silentCheckSsoRedirectUri`: URI or path to a separate page for checking the login session in an iframe, see https://www.keycloak.org/docs/latest/securing_apps/#_javascript_adapter -- `scope`: Space separated list of scopes to request. These scopes get added in addition to the default ones, assuming the scope is in the optional scopes list of the Keycloak client in use. +- `url` (required): The base URL of the Keycloak server +- `realm` (required): The Keycloak realm +- `client-id` (required): The Keycloak client to use +- `silent-check-sso-redirect-uri` (optional): URI or path to a separate page for checking the login session in an iframe, see https://www.keycloak.org/docs/latest/securing_apps/#_javascript_adapter +- `scope` (optional): Space separated list of scopes to request. These scopes get added in addition to the default ones, assuming the scope is in the optional scopes list of the Keycloak client in use. ### Events to listen to diff --git a/packages/auth/src/auth-keycloak.js b/packages/auth/src/auth-keycloak.js index 526d5125271a51884c4095019e019f041ccae6f2..85749938713caa7dfe562f2bfa2413bc2b013b45 100644 --- a/packages/auth/src/auth-keycloak.js +++ b/packages/auth/src/auth-keycloak.js @@ -34,9 +34,15 @@ export class AuthKeycloak extends LitElement { this.tryLogin = false; this.person = null; this.entryPointUrl = commonUtils.getAPiUrl(); - this.keycloakConfig = null; this._loginStatus = LoginStatus.UNKNOWN; + // Keycloak config + this.keycloakUrl = null; + this.realm = null; + this.clientId = null; + this.silentCheckSsoRedirectUri = null; + this.scope = null; + // Create the events this.initEvent = new CustomEvent("vpu-auth-init", { "detail": "KeyCloak init event", bubbles: true, composed: true }); this.personInitEvent = new CustomEvent("vpu-auth-person-init", { "detail": "KeyCloak person init event", bubbles: true, composed: true }); @@ -157,50 +163,36 @@ export class AuthKeycloak extends LitElement { tryLogin: { type: Boolean, attribute: 'try-login' }, loadPerson: { type: Boolean, attribute: 'load-person' }, entryPointUrl: { type: String, attribute: 'entry-point-url' }, - keycloakConfig: { type: Object, attribute: 'keycloak-config' }, name: { type: String, attribute: false }, token: { type: String, attribute: false }, subject: { type: String, attribute: false }, personId: { type: String, attribute: false }, person: { type: Object, attribute: false }, _loginStatus: { type: String, attribute: false }, + keycloakUrl: { type: String, attribute: 'url' }, + realm: { type: String }, + clientId: { type: String, attribute: 'client-id' }, + silentCheckSsoRedirectUri: { type: String, attribute: 'silent-check-sso-redirect-uri' }, + scope: { type: String }, }; } - _getScope() { - if (this.keycloakConfig !== null) { - return this.keycloakConfig.scope || ""; - } - return ""; - } - connectedCallback() { super.connectedCallback(); - this._bus = new EventBus(); + if (!this.keycloakUrl) + throw Error("url not set"); + if (!this.realm) + throw Error("realm not set"); + if (!this.clientId) + throw Error("client-id not set"); - // Keycloak config - let baseURL = ''; - let realm = ''; - let clientId = ''; - let silentCheckSsoRedirectUri = ''; - if (this.keycloakConfig !== null) { - baseURL = this.keycloakConfig.url || baseURL; - realm = this.keycloakConfig.realm || realm; - clientId = this.keycloakConfig.clientId || clientId; - silentCheckSsoRedirectUri = this.keycloakConfig.silentCheckSsoRedirectUri || silentCheckSsoRedirectUri; - } - if (!baseURL || !realm || !clientId) { - throw Error("Keycloak config not set"); - } - - this._kcwrapper = new KeycloakWrapper(baseURL, realm, clientId, silentCheckSsoRedirectUri); + this._bus = new EventBus(); + this._kcwrapper = new KeycloakWrapper(this.keycloakUrl, this.realm, this.clientId, this.silentCheckSsoRedirectUri); this._kcwrapper.addEventListener('changed', this._onKCChanged); - - this._bus.subscribe('auth-login', () => { - this._kcwrapper.login({lang: this.lang, scope: this._getScope()}); + this._kcwrapper.login({lang: this.lang, scope: this.scope || ''}); }); this._bus.subscribe('auth-logout', () => { @@ -220,7 +212,7 @@ export class AuthKeycloak extends LitElement { const handleLogin = async () => { if (this.forceLogin || this._kcwrapper.isLoggingIn()) { this._setLoginStatus(LoginStatus.LOGGING_IN); - await this._kcwrapper.login({lang: this.lang, scope: this._getScope()}); + await this._kcwrapper.login({lang: this.lang, scope: this.scope || ''}); } else if (this.tryLogin) { this._setLoginStatus(LoginStatus.LOGGING_IN); await this._kcwrapper.tryLogin(); diff --git a/packages/auth/src/vpu-auth-demo.js b/packages/auth/src/vpu-auth-demo.js index 7184a5c2ffdf0b61c65b33c9ad1cdcb2744e3318..a99e918744c5b44e9505728f1ea5fc8037b834a6 100644 --- a/packages/auth/src/vpu-auth-demo.js +++ b/packages/auth/src/vpu-auth-demo.js @@ -90,7 +90,7 @@ class AuthDemo extends ScopedElementsMixin(LitElement) { <h1 class="title">Auth-Demo</h1> </div> <div class="container"> - <vpu-auth-keycloak lang="${this.lang}" keycloak-config='{"url": "https://auth-dev.tugraz.at/auth", "realm": "tugraz", "clientId": "auth-dev-mw-frontend-local", "silentCheckSsoRedirectUri": "${silentCheckSsoUri}", "scope": "optional-test-scope"}' load-person try-login></vpu-auth-keycloak> + <vpu-auth-keycloak lang="${this.lang}" url="https://auth-dev.tugraz.at/auth" realm="tugraz" client-id="auth-dev-mw-frontend-local" silent-check-sso-redirect-uri="${silentCheckSsoUri}" scope="optional-test-scope" load-person try-login></vpu-auth-keycloak> <vpu-login-button lang="${this.lang}" show-image></vpu-login-button> </div> diff --git a/packages/auth/test/unit.js b/packages/auth/test/unit.js index 660662141b749decd57c34b45709030513d4fa6d..1ccba94d51f3336fc95f9c84be74fbaee38effa3 100644 --- a/packages/auth/test/unit.js +++ b/packages/auth/test/unit.js @@ -8,11 +8,9 @@ suite('vpu-auth basics', () => { suiteSetup(async () => { node = document.createElement('vpu-auth-keycloak'); - node.setAttribute('keycloak-config', JSON.stringify({ - url: 'url', - realm: 'realm', - clientId: 'clientId', - })); + node.setAttribute('url', 'someurl'); + node.setAttribute('realm', 'somerealm'); + node.setAttribute('client-id', 'someId'); document.body.appendChild(node); await node.updateComplete; });