From f7bf48d335e175b060dca8351da5d4b3856a5163 Mon Sep 17 00:00:00 2001
From: Christoph Reiter <reiter.christoph@gmail.com>
Date: Thu, 21 Nov 2019 13:03:19 +0100
Subject: [PATCH] Replace the remember-login attribute with a new try-login one

With the new ability to log in without redirecting to keycloak and reloading the page
we can now try to login on start every time.

Instead of remembering the login state in the session storage we just ask keycloak in an iframe
on start. To better describe this new behaviour rename the attribute from remember-login to try-login.
---
 packages/auth/README.md            |  5 +++--
 packages/auth/src/keycloak.js      | 24 ++++++++++++++++++--
 packages/auth/src/vpu-auth-demo.js |  2 +-
 packages/auth/src/vpu-auth.js      | 36 +++++++++++++-----------------
 4 files changed, 42 insertions(+), 25 deletions(-)

diff --git a/packages/auth/README.md b/packages/auth/README.md
index ade566b6..b0efb910 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 98bc0cf9..fbca5033 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 d6e59e6b..1589094c 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 6479ab57..c5690567 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);
-- 
GitLab