keycloak-memoizeit

Details

diff --git a/themes/src/main/resources/theme/keycloak-preview/account/index.ftl b/themes/src/main/resources/theme/keycloak-preview/account/index.ftl
index 4d0f093..5c6a195 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/index.ftl
+++ b/themes/src/main/resources/theme/keycloak-preview/account/index.ftl
@@ -122,7 +122,7 @@
                     if (loadListener) script.addEventListener("load", loadListener);
                     document.head.appendChild(script);
                 };
-            keycloak.init({onLoad: 'check-sso'}).success(function(authenticated) {
+            keycloak.init({onLoad: 'login-required'}).success(function(authenticated) {
                 loadjs("/node_modules/react/umd/react.development.js", function() {
                    loadjs("/node_modules/react-dom/umd/react-dom.development.js", function() {
                         loadjs("/node_modules/systemjs/dist/system.src.js", function() {
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/account-service/account.service.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/account-service/account.service.ts
index 71cb4af..1374d57 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/account-service/account.service.ts
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/account-service/account.service.ts
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017 Red Hat Inc. and/or its affiliates and other contributors
+ * Copyright 2018 Red Hat Inc. and/or its affiliates and other contributors
  * as indicated by the @author tags. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
@@ -15,98 +15,82 @@
  * the License.
  */
  
-/*import {Injectable} from '@angular/core';
-import {Http, Response, RequestOptionsArgs} from '@angular/http';
-
-import {KeycloakNotificationService} from '../notification/keycloak-notification.service';
+//import {KeycloakNotificationService} from '../notification/keycloak-notification.service';
 import {KeycloakService} from '../keycloak-service/keycloak.service';
+import Axios, {AxiosRequestConfig, AxiosResponse, AxiosPromise} from 'axios';
 
-import {NotificationType} from 'patternfly-ng/notification';*/
+//import {NotificationType} from 'patternfly-ng/notification';*/
  
+type AxiosResolve = (AxiosResponse) => void;
+type ConfigResolve = (AxiosRequestConfig) => void;
+type ErrorReject = (Error) => void;
+
  /**
  *
- * @author Stan Silvert ssilvert@redhat.com (C) 2017 Red Hat Inc.
+ * @author Stan Silvert ssilvert@redhat.com (C) 2018 Red Hat Inc.
  */
-//@Injectable()
 export class AccountServiceClient {
-
- /*   private accountUrl: string;
-
-    constructor(protected http: Http,
-                protected kcSvc: KeycloakService,
-                protected kcNotifySvc: KeycloakNotificationService) {
-        this.accountUrl = kcSvc.authServerUrl() + 'realms/' + kcSvc.realm() + '/account';
+    private static instance: AccountServiceClient = new AccountServiceClient();
+    
+    private kcSvc: KeycloakService = KeycloakService.Instance;
+    private accountUrl: string = this.kcSvc.authServerUrl() + 'realms/' + this.kcSvc.realm() + '/account';
+ 
+    private constructor() {}
+    
+    public static get Instance(): AccountServiceClient  {
+        return this.instance;
     }
     
-    public doGetRequest(endpoint: string, 
-                        responseHandler: Function, 
-                        options?: RequestOptionsArgs) {
-        this.http.get(this.accountUrl + endpoint, options)
-            .subscribe((res: Response) => responseHandler(res),
-                       (error: Response) => this.handleServiceError(error));
+    public doGet(endpoint: string, 
+                config?: AxiosRequestConfig): Promise<AxiosResponse> {
+        return this.doRequest(endpoint, {...config, method: 'get'});
     }
     
-    public doPostRequest(endpoint: string,
-                         responseHandler: Function,
-                         options?: RequestOptionsArgs,
-                         successMessage?: string) {
-        this.http.post(this.accountUrl + endpoint, options)
-            .subscribe((res: Response) => this.handleAccountUpdated(responseHandler, res, successMessage),
-                       (error: Response) => this.handleServiceError(error));
+    public doRequest(endpoint: string, 
+                     config?: AxiosRequestConfig): Promise<AxiosResponse> {
+        
+        return new Promise((resolve: AxiosResolve, reject: ErrorReject) => {
+            this.makeConfig(endpoint, config)
+                .then((config: AxiosRequestConfig) => {
+                    console.log({config});
+                    this.axiosRequest(config, resolve, reject);
+                }).catch( (error: Error) => {
+                    this.handleError(error);
+                    reject(error);
+                });
+        });
     }
     
-    private handleAccountUpdated(responseHandler: Function, res: Response, successMessage?: string) {
-        let message: string = "Your account has been updated.";
-        if (successMessage) message = successMessage;
-        this.kcNotifySvc.notify(message, NotificationType.SUCCESS);
-        responseHandler(res);
-    } 
+    private axiosRequest(config: AxiosRequestConfig, 
+                         resolve: AxiosResolve, 
+                         reject: ErrorReject): void {
+        Axios.request(config)
+            .then((response: AxiosResponse) => { 
+                 resolve(response);
+            })
+            .catch((error: Error) => {
+                this.handleError(error);
+                reject(error);
+            });
+    }
     
-    public doDelete(endpoint: string,
-                    responseHandler: Function,
-                    options?: RequestOptionsArgs,
-                    successMessage?: string) {
-        this.http.delete(this.accountUrl + endpoint, options)
-            .subscribe((res: Response) => this.handleAccountUpdated(responseHandler, res, successMessage),
-                       (error: Response) => this.handleServiceError(error));
+    private handleError(error: Error) {
+        console.log(error);
     }
     
-    private handleServiceError(response: Response): void {
-        console.log('**** ERROR!!!! ***');
-        console.log(JSON.stringify(response));
-        console.log("response.status=" + response.status);
-        console.log('***************************************')
-        
-        if ((response.status === undefined) || (response.status === 401)) {
-            this.kcSvc.logout();
-            return;
-        }
-
-        if (response.status === 403) {
-            // TODO: go to a forbidden page?
-        }
-
-        if (response.status === 404) {
-            // TODO: route to PageNotFoundComponent
-        }
-
-        let message: string = response.status + " " + response.statusText;
-
-        const not500Error: boolean = response.status !== 500;
-        console.log('not500Error=' + not500Error);
-        
-        // Unfortunately, errors can be sent back in the response body as
-        // 'errorMessage' or 'error_description'
-        if (not500Error && response.json().hasOwnProperty('errorMessage')) {
-            message = response.json().errorMessage;
-        }
-
-        if (not500Error && response.json().hasOwnProperty('error_description')) {
-            message = response.json().error_description;
-        }
-        
-        this.kcNotifySvc.notify(message, NotificationType.DANGER, response.json().params);
-    } */
+    private makeConfig(endpoint: string, config?: AxiosRequestConfig): Promise<AxiosRequestConfig> {
+        return new Promise( (resolve: ConfigResolve, reject: ErrorReject) => {
+            this.kcSvc.getToken()
+                .then( (token: string) => {
+                    resolve( {
+                        ...config,
+                        baseURL: this.accountUrl,
+                        url: endpoint,
+                        headers: {...config.headers, Authorization: 'Bearer ' + token}
+                    });
+                }).catch((error: Error) => {
+                    reject(error);
+                });       
+        });
+    }
 }
-
-
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/account-page/AccountPage.tsx b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/account-page/AccountPage.tsx
index a17684a..6bfee81 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/account-page/AccountPage.tsx
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/account-page/AccountPage.tsx
@@ -15,20 +15,42 @@
  */
 
 import * as React from 'react';
+import {AxiosResponse} from 'axios';
+import {AccountServiceClient} from '../../account-service/account.service';
  
-export interface AccountPageProps {
+interface AccountPageProps {
 }
- 
-export class AccountPage extends React.Component<AccountPageProps> {
+
+interface AccountPageState {
+    readonly username: string,
+    readonly firstName?: string,
+    readonly lastName?: string,
+    readonly email?: string,
+    readonly emailVerified?: boolean
+}
+
+/**
+ * @author Stan Silvert ssilvert@redhat.com (C) 2018 Red Hat Inc.
+ */
+export class AccountPage extends React.Component<AccountPageProps, AccountPageState> {
+    readonly state: AccountPageState = {
+        username: ''
+    };
     
     constructor(props: AccountPageProps) {
         super(props);
+        AccountServiceClient.Instance.doGet("/")
+            .then((response: AxiosResponse<AccountPageState>) => {
+                this.setState(response.data);
+                console.log({response});
+            });
     }
 
     render() {
+        const {username, firstName} = this.state;
         return (
             <div>
-              <h2>Hello Account Page</h2>
+                <h2>Hello {username} {firstName}</h2>
             </div>
         );
     }
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/package.json b/themes/src/main/resources/theme/keycloak-preview/account/resources/package.json
index 0b9980d..9d79dec 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/package.json
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/package.json
@@ -10,6 +10,7 @@
   "author": "Stan Silvert",
   "license": "Apache 2.0",
   "dependencies": {
+    "axios": "^0.18.0",
     "bootstrap": "^4.1.0",
     "patternfly": "^3.23.2",
     "react": "^16.5.2",
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/package-lock.json b/themes/src/main/resources/theme/keycloak-preview/account/resources/package-lock.json
index 9df53b1..d90b324 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/package-lock.json
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/package-lock.json
@@ -294,6 +294,15 @@
         "@types/react": "*"
       }
     },
+    "axios": {
+      "version": "0.18.0",
+      "resolved": "http://registry.npmjs.org/axios/-/axios-0.18.0.tgz",
+      "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=",
+      "requires": {
+        "follow-redirects": "^1.3.0",
+        "is-buffer": "^1.1.5"
+      }
+    },
     "bootstrap": {
       "version": "4.1.3",
       "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.1.3.tgz",
@@ -411,6 +420,14 @@
         "jquery": ">=1.7"
       }
     },
+    "debug": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+      "requires": {
+        "ms": "2.0.0"
+      }
+    },
     "drmonty-datatables-colvis": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/drmonty-datatables-colvis/-/drmonty-datatables-colvis-1.1.2.tgz",
@@ -440,6 +457,14 @@
         }
       }
     },
+    "follow-redirects": {
+      "version": "1.5.9",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.9.tgz",
+      "integrity": "sha512-Bh65EZI/RU8nx0wbYF9shkFZlqLP+6WT/5FnA3cE/djNSuKNHJEinGGZgu/cQEkeeb2GdFOgenAmn8qaqYke2w==",
+      "requires": {
+        "debug": "=3.1.0"
+      }
+    },
     "font-awesome": {
       "version": "4.7.0",
       "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz",
@@ -492,6 +517,11 @@
         "loose-envify": "^1.0.0"
       }
     },
+    "is-buffer": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+    },
     "isarray": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
@@ -535,6 +565,11 @@
         "moment": ">= 2.6.0"
       }
     },
+    "ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+    },
     "object-assign": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/systemjs.config.js b/themes/src/main/resources/theme/keycloak-preview/account/resources/systemjs.config.js
index c80d779..7f1f5d6 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/systemjs.config.js
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/systemjs.config.js
@@ -18,6 +18,7 @@
       'react-dom': 'npm:react-dom/umd/react-dom.development.js',
       'react-router-dom': 'npm:react-router-dom/umd/react-router-dom.js',
       
+      'axios': 'npm:axios/dist/axios.min.js',
     },
     
     bundles: {