diff --git a/packages/auth/README.md b/packages/auth/README.md index ade566b65dada055aaa4f640e39fbc2e97f5955f..b0efb910ecc0302cdd0a2ae11d713439e4f15a5b 100644 --- a/packages/auth/README.md +++ b/packages/auth/README.md @@ -19,8 +19,9 @@ - example `<vpu-auth client-id="my-client-id" load-person></vpu-auth>` - `force-login` (optional, default: off): if enabled a login will be forced, there never will be a login button - example `<vpu-auth client-id="my-client-id" force-login></vpu-auth>` -- `remember-login` (optional, default: off): if enabled a login will be forced if the user was logged in, in the same session - - example `<vpu-auth client-id="my-client-id" remember-login></vpu-auth>` +- `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 client-id="my-client-id" try-login></vpu-auth>` ## Events to listen to diff --git a/packages/auth/src/keycloak.js b/packages/auth/src/keycloak.js index 98bc0cf999c3436175443b1b39b525115932f94c..fbca5033c32ae0b93db7d03dfb9e02f552f465e0 100644 --- a/packages/auth/src/keycloak.js +++ b/packages/auth/src/keycloak.js @@ -87,13 +87,19 @@ export class KeycloakWrapper extends EventTarget { } /** - * Returns true in case we just got redirected from the login page + * If this returns true you need to call login() at one point to finish the login process. */ isLoggingIn() { const href = window.location.href; return (href.search('[&#]state=') >= 0 && href.search('[&#]session_state=') >= 0); } + /** + * Logs the user in. Might lead to a site refresh or the user needing to authenticate. + * + * @param {object} options + * @param {string} [options.lang] - The locale to use on the keycloak login page + */ async login(options) { await this._ensureInit(); @@ -107,10 +113,24 @@ export class KeycloakWrapper extends EventTarget { } } - async clearToken() { + /** + * Logs the user in if it is possible without leaving the page or the user needing to authenticate again. + */ + async tryLogin() { + await this._ensureInit(); + } + + /** + * Logs the user out locally, but not with keycloak. Login will instantly log the user back in without + * requiring a re-auth. + */ + async localLogout() { this._keycloak.clearToken(); } + /** + * Log the user out from keycloak. + */ async logout() { await this._ensureInit(); this._keycloak.logout(); diff --git a/packages/auth/src/vpu-auth-demo.js b/packages/auth/src/vpu-auth-demo.js index d6e59e6b8ffe4994d1dd35f15efab926120796ae..1589094c976f3f2b61f73422c6b0489c06b0d091 100644 --- a/packages/auth/src/vpu-auth-demo.js +++ b/packages/auth/src/vpu-auth-demo.js @@ -50,7 +50,7 @@ class AuthDemo extends LitElement { <h1 class="title">Auth-Demo</h1> </div> <div class="container"> - <vpu-auth lang="${this.lang}" client-id="${commonUtils.setting('keyCloakClientId')}" silent-check-sso-uri="${silentCheckSsoUri}" load-person remember-login></vpu-auth> + <vpu-auth lang="${this.lang}" client-id="${commonUtils.setting('keyCloakClientId')}" silent-check-sso-uri="${silentCheckSsoUri}" load-person try-login></vpu-auth> </div> </section> `; diff --git a/packages/auth/src/vpu-auth.js b/packages/auth/src/vpu-auth.js index 6479ab574a3458a380729f299c5e7b6ecd2b6b04..c5690567887248cc7a1774f3e5cd2fb83a5d8ef3 100644 --- a/packages/auth/src/vpu-auth.js +++ b/packages/auth/src/vpu-auth.js @@ -41,7 +41,7 @@ class VPUAuth extends VPULitElement { this.subject = ""; this.name = ""; this.personId = ""; - this.rememberLogin = false; + this.tryLogin = false; this.person = null; const _getLoginData = () => { @@ -143,7 +143,7 @@ class VPUAuth extends VPULitElement { return { lang: { type: String }, forceLogin: { type: Boolean, attribute: 'force-login' }, - rememberLogin: { type: Boolean, attribute: 'remember-login' }, + tryLogin: { type: Boolean, attribute: 'try-login' }, loadPerson: { type: Boolean, attribute: 'load-person' }, clientId: { type: String, attribute: 'client-id' }, silentCheckSsoUri: { type: String, attribute: 'silent-check-sso-uri' }, @@ -164,19 +164,21 @@ class VPUAuth extends VPULitElement { this._kcwrapper = new KeycloakWrapper(baseURL, realm, this.clientId, this.silentCheckSsoUri); this._kcwrapper.addEventListener('changed', this._onKCChanged); + const handleLogin = async () => { + if (this.forceLogin || this._kcwrapper.isLoggingIn()) { + this._setLoginStatus(LoginStatus.LOGGING_IN); + await this._kcwrapper.login(); + } else if (this.tryLogin) { + this._setLoginStatus(LoginStatus.LOGGING_IN); + await this._kcwrapper.tryLogin(); + if (this._loginStatus === LoginStatus.LOGGING_IN) + this._setLoginStatus(LoginStatus.LOGGED_OUT); + } else { + this._setLoginStatus(LoginStatus.LOGGED_OUT); + } + }; - let doLogin = false; - if ((this.rememberLogin && sessionStorage.getItem('vpu-logged-in')) || this.forceLogin) { - doLogin = true; - } - - // load Keycloak if we want to force the login or if we were redirected from the Keycloak login page - if (doLogin || this._kcwrapper.isLoggingIn()) { - this._setLoginStatus(LoginStatus.LOGGING_IN); - this._kcwrapper.login() - } else { - this._setLoginStatus(LoginStatus.LOGGED_OUT); - } + handleLogin(); this.updateComplete.then(() => { window.onresize = () => { @@ -221,12 +223,6 @@ class VPUAuth extends VPULitElement { if (propName === "lang") { i18n.changeLanguage(this.lang); } - if (propName == "_loginStatus") { - if (this._loginStatus === LoginStatus.LOGGED_IN) - sessionStorage.setItem('vpu-logged-in', true); - else - sessionStorage.removeItem('vpu-logged-in'); - } }); super.update(changedProperties);