keycloak-uncached

KEYCLOAK-6494: Address load time of new acct mgt console (#5100) *

3/27/2018 1:42:13 PM

Changes

Details

diff --git a/services/src/main/java/org/keycloak/services/resources/account/AccountConsole.java b/services/src/main/java/org/keycloak/services/resources/account/AccountConsole.java
index de29fd7..85cf2a7 100644
--- a/services/src/main/java/org/keycloak/services/resources/account/AccountConsole.java
+++ b/services/src/main/java/org/keycloak/services/resources/account/AccountConsole.java
@@ -40,6 +40,7 @@ import org.keycloak.services.managers.Auth;
 import org.keycloak.services.managers.AuthenticationManager;
 import org.keycloak.services.util.ResolveRelative;
 import org.keycloak.services.validation.Validation;
+import org.keycloak.theme.beans.MessageFormatterMethod;
 
 /**
  * Created by st on 29/03/17.
@@ -101,7 +102,8 @@ public class AccountConsole {
                 if (auth != null) {
                     Locale locale = session.getContext().resolveLocale(auth.getUser());
                     map.put("locale", locale.toLanguageTag());
-                    map.put("msg", messagesToJsonString(theme.getMessages(locale)));
+                    Properties messages = theme.getMessages(locale);
+                    map.put("msg", messagesToJsonString(messages));
                 }
             } catch (Exception e) {
                 logger.warn("Failed to load messages", e);
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 872e42e..3cc9398 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/index.ftl
+++ b/themes/src/main/resources/theme/keycloak-preview/account/index.ftl
@@ -8,7 +8,7 @@
             var baseUrl = '${baseUrl}';
             var realm = '${realm}';
             var resourceUrl = '${resourceUrl}';
-            
+                
             <#if referrer??>
                 var referrer = '${referrer}';
                 var referrer_uri = '${referrer_uri}';
@@ -17,6 +17,9 @@
             <#if msg??>
                 var locale = '${locale}';
                 var l18n_msg = JSON.parse('${msg?no_esc}');
+            <#else>
+                var locale = 'en';
+                var l18n_msg = {};
             </#if>
         </script>
 
@@ -29,16 +32,6 @@
 
         <link rel="icon" href="${resourceUrl}/app/assets/img/favicon.ico" type="image/x-icon"/>
 
-        <#if properties.styles?has_content>
-            <#list properties.styles?split(' ') as style>
-            <link href="${resourceUrl}/${style}" rel="stylesheet"/>
-            </#list>
-        </#if>
-
-        <link rel="stylesheet" href="${resourceUrl}/styles.css">
-
-        <!--<script src="${authUrl}/js/${resourceVersion}/keycloak.js" type="text/javascript"></script>-->
-
         <!-- PatternFly -->
         <!-- iPad retina icon -->
         <link rel="apple-touch-icon-precomposed" sizes="152x152"
@@ -65,56 +58,150 @@
               media="screen, print">
         <link href="${resourceUrl}/node_modules/patternfly/dist/css/patternfly-additions.min.css" rel="stylesheet"
               media="screen, print">
-        <script src="${resourceUrl}/node_modules/jquery/dist/jquery.min.js"></script>
+
         <script src="${resourceUrl}/node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
-        <script src="${resourceUrl}/node_modules/jquery-match-height/dist/jquery.matchHeight-min.js"></script>
         <script src="${resourceUrl}/node_modules/patternfly/dist/js/patternfly.min.js"></script>
+        <script src="${authUrl}/js/keycloak.js"></script>
 
-        <!-- Polyfill(s) for older browsers -->
-        <script src="${resourceUrl}/node_modules/core-js/client/shim.min.js"></script>
-
-        <#if properties.scripts?has_content>
-            <#list properties.scripts?split(' ') as script>
-            <script type="text/javascript" src="${resourceUrl}/${script}"></script>
-            </#list>
-        </#if>
-
-        <script src="${resourceUrl}/node_modules/zone.js/dist/zone.js"></script>
-        <script src="${resourceUrl}/node_modules/systemjs/dist/system.src.js"></script>
-
-        <script src="${resourceUrl}/systemjs.config.js"></script>
         <script>
-            System.import('${resourceUrl}/main.js').catch(function (err) {
-                console.error(err);
+            var keycloak = Keycloak('${authUrl}/realms/${realm}/account/keycloak.json');
+            keycloak.init({onLoad: 'check-sso'}).success(function(authenticated) {
+                var loadjs = function (url,loadListener) {
+                    const script = document.createElement("script");
+                    script.src = resourceUrl + url;
+                    if (loadListener) script.addEventListener("load", loadListener);
+                    document.head.appendChild(script); 
+                };
+                loadjs("/node_modules/core-js/client/shim.min.js", function(){
+                    loadjs("/node_modules/zone.js/dist/zone.min.js");
+                    loadjs("/node_modules/systemjs/dist/system.src.js", function() {
+                        loadjs("/systemjs.config.js");
+                        System.import('${resourceUrl}/main.js').catch(function (err) {
+                            console.error(err);
+                        });
+                        if (!keycloak.authenticated) document.getElementById("signInButton").style.visibility='visible';
+                    });
+                });
+            }).error(function() {
+                alert('failed to initialize keycloak');
             });
         </script>
-    </head>
-
-    <app-root>
-        <style>
-            .kc-background {
-                background: url('${resourceUrl}/img/keycloak-bg.png') top left no-repeat;
-                background-size: cover;
-            }
 
-            .logo-centered {
-                position: fixed;
-                top: 50%;
-                left: 50%;
-                transform: translate(-50%, -50%);
-            }
 
-            .kc-logo-text {
-                background-image: url("${resourceUrl}/img/keycloak-logo-text.png");
-                background-repeat: no-repeat;
-                width: 250px;
-                height: 38px;
-            }
-        </style>
+   <!-- TODO: We should save these css and js into variables and then load in
+        main.ts for better performance.  These might be loaded twice.
+        -->
+        <#if properties.styles?has_content>
+            <#list properties.styles?split(' ') as style>
+        <link href="${resourceUrl}/${style}" rel="stylesheet"/>
+            </#list>
+    <a href="../../../../../../../../keycloak-quickstarts/app-profile-jee-html5/src/main/webapp/index.html"></a>
+        </#if>
 
-        <body class="cards-pf kc-background">
-            <div class='logo-centered kc-logo-text'/>
-        </body>
-    </app-root>
+        <#if properties.scripts?has_content>
+            <#list properties.scripts?split(' ') as script>
+        <script type="text/javascript" src="${resourceUrl}/${script}"></script>
+            </#list>
+        </#if>
+        </head>
+    <body>
 
+        
+        
+<!-- Top Navigation -->
+        <nav class="navbar navbar-pf-alt">
+
+            <div class="navbar-header">
+                <a href="http://www.keycloak.org" class="navbar-brand">
+                    <img class="navbar-brand-icon" type="image/svg+xml" src="${resourceUrl}/app/assets/img/keycloak-logo-min.png" alt="" width="auto" height="30px"/>
+                </a>
+            </div>
+            <nav class="collapse navbar-collapse">
+                <ul class="nav navbar-nav">
+                </ul>
+                
+                <!-- This sign in button is only displayed in the rare case where we go directly to this page and we aren't logged in.
+                     Note javascript code above that changes its visibility for that case.  Also, because we are not logged in
+                     we are unable to localize the button's message.  Not sure what to do about that yet.
+                -->
+                <ul class="nav navbar-nav navbar-right navbar-iconic">
+                    <li><button id="signInButton" style="visibility:hidden" onclick="keycloak.login();" class="btn btn-primary btn-lg" type="button">Sign In</button></li>
+                </ul>
+            </nav>
+        </nav>
+        
+<!--Top Nav -->
+        
+<!-- Home Page --->
+    <div class="cards-pf" id="welcomeScreen">
+        <div><h1 class="text-center">Welcome to Keycloak Account Management</h1></div>
+        <div class="container-fluid container-cards-pf">
+            <div class="row row-cards-pf">
+                <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
+                    <div class="card-pf card-pf-view card-pf-view-select card-pf-view-single-select">
+                        <div class="card-pf-body">
+                            <div class="card-pf-top-element">
+                                <span class="fa pficon-user card-pf-icon-circle"></span>
+                            </div>
+                            <h2 class="card-pf-title text-center">
+                                Personal Info
+                            </h2>
+                            <h3 class="card-pf-info text-center">
+                                <a href="${baseUrl}/#/account">Account</a>
+                            </h3>
+                        </div>
+                    </div>
+                </div>
+                <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
+                    <div class="card-pf card-pf-view card-pf-view-select card-pf-view-single-select">
+                        <div class="card-pf-body">
+                            <div class="card-pf-top-element">
+                                <span class="fa fa-shield card-pf-icon-circle"></span>
+                            </div>
+                            <h2 class="card-pf-title text-center">
+                                Account Security
+                            </h2>
+                            <h3 class="card-pf-info text-center">
+                                More stuff goes here
+                            </h3>
+                        </div>
+                    </div>
+                </div>
+                <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
+                    <div class="card-pf card-pf-view card-pf-view-select card-pf-view-single-select">
+                        <div class="card-pf-body">
+                            <div class="card-pf-top-element">
+                                <span class="fa fa-th card-pf-icon-circle"></span>
+                            </div>
+                            <h2 class="card-pf-title text-center">
+                                Applications
+                            </h2>
+                            <h3 class="card-pf-info text-center">
+                                More stuff goes here
+                            </h3>
+                        </div>
+                    </div>
+                </div>
+                <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
+                    <div class="card-pf card-pf-view card-pf-view-select card-pf-view-single-select">
+                        <div class="card-pf-body">
+                            <div class="card-pf-top-element">
+                                <span class="fa pficon-repository card-pf-icon-circle"></span>
+                            </div>
+                            <h2 class="card-pf-title text-center">
+                                My Resources
+                            </h2>
+                            <h3 class="card-pf-info text-center">
+                                More stuff goes here
+                            </h3>
+                        </div>
+                    </div>
+                </div>
+
+            </div>
+        </div>
+    </div>
+
+        <app-root></app-root>
+    </body>
 </html>
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app.component.html b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app.component.html
index 2a65d8b..cd1e829 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app.component.html
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app.component.html
@@ -1,9 +1,11 @@
-<app-top-nav></app-top-nav>
-<app-side-nav></app-side-nav>
+<div *ngIf="kcService.authenticated()">
+    <app-top-nav [showSideNav]="showSideNav"></app-top-nav>
+</div>
+
+<app-side-nav *ngIf="showSideNav"></app-side-nav>
 
 
 <div class="container-fluid container-pf-alt-nav-pf-vertical-alt {{this.contentWidthClass}}"> <!-- collapsed-nav hidden-nav -->
 
     <router-outlet></router-outlet>
-    
 </div>
\ No newline at end of file
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app.component.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app.component.ts
index 04b2c2e..72a19af 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app.component.ts
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app.component.ts
@@ -15,10 +15,12 @@
  * limitations under the License.
  */
 import {Component, HostListener} from '@angular/core';
-
+import {Router, NavigationEnd} from '@angular/router';
+import 'rxjs/add/observable/of'; // needed for ngx-translate
 import {TranslateService} from '@ngx-translate/core';
 
 import {ResponsivenessService, ContentWidthClass, MenuClickListener} from "./responsiveness-service/responsiveness.service";
+import {KeycloakService} from "./keycloak-service/keycloak.service";
 
 declare const locale: string;
 
@@ -30,8 +32,12 @@ declare const locale: string;
 export class AppComponent implements MenuClickListener {
     
     private contentWidthClass: ContentWidthClass = this.respSvc.calcSideContentWidthClass();
+    private showSideNav: boolean = false;
     
-    constructor(translate: TranslateService, private respSvc: ResponsivenessService) {
+    constructor(translate: TranslateService, 
+                private respSvc: ResponsivenessService,
+                private router: Router,
+                private kcService: KeycloakService) {
         // this language will be used as a fallback when a translation isn't found in the current language
         translate.setDefaultLang('en');
 
@@ -39,6 +45,19 @@ export class AppComponent implements MenuClickListener {
         translate.use(locale);
         
         this.respSvc.addMenuClickListener(this);
+        
+        // show side nav if we are past the welcome screen
+        this.router.events.subscribe(value => {
+            if (value instanceof NavigationEnd) {
+                const navEnd = value as NavigationEnd;
+                console.log(navEnd.url);
+                if (navEnd.url !== '/') {
+                    this.showSideNav = true;
+                    var welcomeScreen = document.getElementById('welcomeScreen')
+                    if (welcomeScreen) welcomeScreen.remove();
+                }
+            }
+        });
     }
     
     public menuClicked() : void {
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app.module.ts
index 6fdd6db..3aec819 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app.module.ts
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app.module.ts
@@ -26,6 +26,7 @@ import { TranslateModule } from '@ngx-translate/core';
 
 import { KeycloakService } from './keycloak-service/keycloak.service';
 import { KEYCLOAK_HTTP_PROVIDER } from './keycloak-service/keycloak.http';
+import {KeycloakGuard} from './keycloak-service/keycloak.guard';
 
 import {ResponsivenessService} from './responsiveness-service/responsiveness.service'
 
@@ -38,55 +39,15 @@ import { TopNavComponent } from './top-nav/top-nav.component';
 import { NotificationComponent } from './top-nav/notification.component';
 import { ToastNotifier } from './top-nav/toast.notifier';
 import { SideNavComponent } from './side-nav/side-nav.component';
-import { AccountPageComponent } from './content/account-page/account-page.component';
-import { PasswordPageComponent } from './content/password-page/password-page.component';
-import { PageNotFoundComponent } from './content/page-not-found/page-not-found.component';
 
-import { AuthenticatorPageComponent } from './content/authenticator-page/authenticator-page.component';
-
-import { SessionsPageComponent } from './content/sessions-page/sessions-page.component';
-import { LargeSessionCardComponent } from './content/sessions-page/large-session-card.component';
-import { SmallSessionCardComponent } from './content/sessions-page/small-session-card.component';
-
-import { ApplicationsPageComponent } from './content/applications-page/applications-page.component';
-import { LargeAppCardComponent } from './content/applications-page/large-app-card.component';
-import { SmallAppCardComponent } from './content/applications-page/small-app-card.component';
-import { RowAppCardComponent } from './content/applications-page/row-app-card.component';
-
-import { ToolbarComponent } from './content/widgets/toolbar.component';
-
-import {OrderbyPipe} from './pipes/orderby.pipe';
-import {FilterbyPipe} from './pipes/filterby.pipe';
-
-const routes: Routes = [
-    { path: 'account', component: AccountPageComponent },
-    { path: 'password', component: PasswordPageComponent },
-    { path: 'authenticator', component: AuthenticatorPageComponent },
-    { path: 'sessions', component: SessionsPageComponent },
-    { path: 'applications', component: ApplicationsPageComponent },
-    { path: '', redirectTo: '/account', pathMatch: 'full' },
-    { path: '**', component: PageNotFoundComponent}
-];
+/* Routing Module */
+import { AppRoutingModule } from './app-routing.module';
 
 const decs = [
     AppComponent,
     TopNavComponent,
     NotificationComponent,
     SideNavComponent,
-    AccountPageComponent,
-    PasswordPageComponent,
-    PageNotFoundComponent,
-    AuthenticatorPageComponent,
-    SessionsPageComponent,
-    LargeSessionCardComponent,
-    SmallSessionCardComponent,
-    ApplicationsPageComponent,
-    LargeAppCardComponent,
-    SmallAppCardComponent,
-    RowAppCardComponent,
-    ToolbarComponent,
-    OrderbyPipe,
-    FilterbyPipe
 ];
 
 export const ORIGINAL_INCOMING_URL: Location = window.location;
@@ -100,10 +61,11 @@ export const ORIGINAL_INCOMING_URL: Location = window.location;
     TranslateModule.forRoot({
         loader: {provide: TranslateLoader, useClass: DeclaredVarTranslateLoader}
     }),
-    RouterModule.forRoot(routes)
+    AppRoutingModule,
   ],
   providers: [
     KeycloakService,
+    KeycloakGuard,
     KEYCLOAK_HTTP_PROVIDER,
     ResponsivenessService,
     AccountServiceClient,
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app-routing.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app-routing.module.ts
new file mode 100644
index 0000000..f11cdaf
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/app-routing.module.ts
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule }             from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import {KeycloakGuard} from './keycloak-service/keycloak.guard';
+
+import { HomePageComponent } from './content/home-page/home-page.component';
+
+declare const resourceUrl: string;
+
+export const routes: Routes = [
+        {path: '', canActivateChild:[KeycloakGuard], children: [
+            { path: 'account', loadChildren: resourceUrl + '/app/content/account-page/account.module.js#AccountModule' },
+            { path: 'password', loadChildren: resourceUrl + '/app/content/password-page/password.module.js#PasswordModule' },
+            { path: 'authenticator', loadChildren: resourceUrl + '/app/content/authenticator-page/authenticator.module.js#AuthenticatorModule' },
+            { path: 'sessions', loadChildren: resourceUrl + '/app/content/sessions-page/sessions.module.js#SessionsModule' },
+            { path: 'applications', loadChildren: resourceUrl + '/app/content/applications-page/applications.module.js#ApplicationsModule' },
+            { path: ':**', loadChildren: resourceUrl + '/app/content/page-not-found/page-not-found.module.js#PageNotFoundModule' },
+            ]
+        }
+    ];
+
+@NgModule({
+  imports: [RouterModule.forRoot(routes)],
+  exports: [RouterModule],
+  declarations: [HomePageComponent]
+})
+export class AppRoutingModule {}
+
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/assets/img/keycloak-logo-min.png b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/assets/img/keycloak-logo-min.png
new file mode 100644
index 0000000..0bbf1d5
Binary files /dev/null and b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/assets/img/keycloak-logo-min.png differ
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/account-page/account.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/account-page/account.module.ts
new file mode 100644
index 0000000..1e65b14
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/account-page/account.module.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule }      from '@angular/core';
+import { CommonModule }  from '@angular/common';
+import { FormsModule } from '@angular/forms';
+
+import { TranslateModule } from '@ngx-translate/core';
+
+import { AccountPageComponent } from './account-page.component';
+import { AccountRoutingModule } from './account-routing.module';
+
+@NgModule({
+  imports:      [ CommonModule, FormsModule, TranslateModule, AccountRoutingModule ],
+  declarations: [ AccountPageComponent ],
+  providers:    [ ]
+})
+export class AccountModule {}
+
+
+
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/account-page/account-routing.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/account-page/account-routing.module.ts
new file mode 100644
index 0000000..635f4b8
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/account-page/account-routing.module.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule }             from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { AccountPageComponent } from './account-page.component';
+
+const routes: Routes = [
+    { path: '**', component: AccountPageComponent },
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule]
+})
+export class AccountRoutingModule {}
+
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/applications-page/applications.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/applications-page/applications.module.ts
new file mode 100644
index 0000000..5cc64fc
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/applications-page/applications.module.ts
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule }      from '@angular/core';
+import { CommonModule }  from '@angular/common';
+
+import { TranslateModule } from '@ngx-translate/core';
+
+import {WidgetsModule} from '../widgets/widgets.module';
+
+import { ApplicationsPageComponent } from './applications-page.component';
+import { ApplicationsRoutingModule } from './applications-routing.module';
+import { LargeAppCardComponent } from './large-app-card.component';
+import { SmallAppCardComponent } from './small-app-card.component';
+import { RowAppCardComponent } from './row-app-card.component';
+
+@NgModule({
+  imports:      [ CommonModule, 
+                  TranslateModule, 
+                  ApplicationsRoutingModule,
+                  WidgetsModule ],
+  declarations: [ ApplicationsPageComponent,
+                  LargeAppCardComponent,
+                  SmallAppCardComponent,
+                  RowAppCardComponent ],
+  providers:    [ ]
+})
+export class ApplicationsModule {}
+
+
+
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/applications-page/applications-routing.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/applications-page/applications-routing.module.ts
new file mode 100644
index 0000000..f35db61
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/applications-page/applications-routing.module.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule }             from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { ApplicationsPageComponent } from './applications-page.component';
+
+const routes: Routes = [
+    { path: '**', component: ApplicationsPageComponent },
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule]
+})
+export class ApplicationsRoutingModule {}
+
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/authenticator-page/authenticator.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/authenticator-page/authenticator.module.ts
new file mode 100644
index 0000000..780bd7c
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/authenticator-page/authenticator.module.ts
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule }      from '@angular/core';
+import { CommonModule }  from '@angular/common';
+
+import { TranslateModule } from '@ngx-translate/core';
+
+import { AuthenticatorPageComponent } from './authenticator-page.component';
+import { AuthenticatorRoutingModule } from './authenticator-routing.module';
+
+@NgModule({
+  imports:      [ CommonModule, TranslateModule, AuthenticatorRoutingModule ],
+  declarations: [ AuthenticatorPageComponent ],
+  providers:    [ ]
+})
+export class AuthenticatorModule {}
+
+
+
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/authenticator-page/authenticator-routing.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/authenticator-page/authenticator-routing.module.ts
new file mode 100644
index 0000000..47c4d73
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/authenticator-page/authenticator-routing.module.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule }             from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { AuthenticatorPageComponent } from './authenticator-page.component';
+
+const routes: Routes = [
+    { path: '**', component: AuthenticatorPageComponent },
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule]
+})
+export class AuthenticatorRoutingModule {}
+
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/home-page/home-page.component.css b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/home-page/home-page.component.css
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/home-page/home-page.component.css
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/home-page/home-page.component.html b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/home-page/home-page.component.html
new file mode 100644
index 0000000..27a4940
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/home-page/home-page.component.html
@@ -0,0 +1,68 @@
+<div class="cards-pf">
+    <div><h1 class="text-center">Welcome to Keycloak Account Management</h1></div>
+    <div class="container-fluid container-cards-pf">
+        <div class="row row-cards-pf">
+            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
+                <div class="card-pf card-pf-view card-pf-view-select card-pf-view-single-select">
+                    <div class="card-pf-body">
+                        <div class="card-pf-top-element">
+                            <span class="fa pficon-user card-pf-icon-circle"></span>
+                        </div>
+                        <h2 class="card-pf-title text-center">
+                            Personal Info
+                        </h2>
+                        <h3 class="card-pf-info text-center">
+                            More stuff goes here
+                        </h3>
+                    </div>
+                </div>
+            </div>
+            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
+                <div class="card-pf card-pf-view card-pf-view-select card-pf-view-single-select">
+                    <div class="card-pf-body">
+                        <div class="card-pf-top-element">
+                            <span class="fa fa-shield card-pf-icon-circle"></span>
+                        </div>
+                        <h2 class="card-pf-title text-center">
+                            Account Security
+                        </h2>
+                        <h3 class="card-pf-info text-center">
+                            More stuff goes here
+                        </h3>
+                    </div>
+                </div>
+            </div>
+            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
+                <div class="card-pf card-pf-view card-pf-view-select card-pf-view-single-select">
+                    <div class="card-pf-body">
+                        <div class="card-pf-top-element">
+                            <span class="fa fa-th card-pf-icon-circle"></span>
+                        </div>
+                        <h2 class="card-pf-title text-center">
+                            Applications
+                        </h2>
+                        <h3 class="card-pf-info text-center">
+                            More stuff goes here
+                        </h3>
+                    </div>
+                </div>
+            </div>
+            <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
+                <div class="card-pf card-pf-view card-pf-view-select card-pf-view-single-select">
+                    <div class="card-pf-body">
+                        <div class="card-pf-top-element">
+                            <span class="fa pficon-repository card-pf-icon-circle"></span>
+                        </div>
+                        <h2 class="card-pf-title text-center">
+                            My Resources
+                        </h2>
+                        <h3 class="card-pf-info text-center">
+                            More stuff goes here
+                        </h3>
+                    </div>
+                </div>
+            </div>
+            
+        </div>
+    </div>
+</div>
\ No newline at end of file
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/home-page/home-page.component.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/home-page/home-page.component.ts
new file mode 100644
index 0000000..1a0c781
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/home-page/home-page.component.ts
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2017 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {Component} from '@angular/core';
+
+@Component({
+    selector: 'home-page',
+    templateUrl: './home-page.component.html',
+    styleUrls: ['./home-page.component.css']
+})
+export class HomePageComponent {
+    
+    constructor() {}
+    
+}
\ No newline at end of file
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/page-not-found/page-not-found.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/page-not-found/page-not-found.module.ts
new file mode 100644
index 0000000..9274bb1
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/page-not-found/page-not-found.module.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule }      from '@angular/core';
+import { CommonModule }  from '@angular/common';
+import { FormsModule } from '@angular/forms';
+
+import { TranslateModule } from '@ngx-translate/core';
+
+import { PageNotFoundComponent } from './page-not-found.component';
+import { PageNotFoundRoutingModule } from './page-not-found-routing.module';
+
+@NgModule({
+  imports:      [ CommonModule, FormsModule, TranslateModule, PageNotFoundRoutingModule ],
+  declarations: [ PageNotFoundComponent ],
+  providers:    [ ]
+})
+export class PageNotFoundModule {}
+
+
+
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/page-not-found/page-not-found-routing.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/page-not-found/page-not-found-routing.module.ts
new file mode 100644
index 0000000..a23ca00
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/page-not-found/page-not-found-routing.module.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule }             from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { PageNotFoundComponent } from './page-not-found.component';
+
+const routes: Routes = [
+    { path: '**', component: PageNotFoundComponent}
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule]
+})
+export class PageNotFoundRoutingModule {}
+
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/password-page/password.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/password-page/password.module.ts
new file mode 100644
index 0000000..9bd5d9d
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/password-page/password.module.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule }      from '@angular/core';
+import { CommonModule }  from '@angular/common';
+import { FormsModule } from '@angular/forms';
+
+import { TranslateModule } from '@ngx-translate/core';
+
+import { PasswordPageComponent } from './password-page.component';
+import { PasswordRoutingModule } from './password-routing.module';
+
+@NgModule({
+  imports:      [ CommonModule, FormsModule, TranslateModule, PasswordRoutingModule ],
+  declarations: [ PasswordPageComponent ],
+  providers:    [ ]
+})
+export class PasswordModule {}
+
+
+
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/password-page/password-routing.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/password-page/password-routing.module.ts
new file mode 100644
index 0000000..3208b40
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/password-page/password-routing.module.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule }             from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { PasswordPageComponent } from './password-page.component';
+
+const routes: Routes = [
+    { path: '**', component: PasswordPageComponent },
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule]
+})
+export class PasswordRoutingModule {}
+
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/sessions-page/sessions.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/sessions-page/sessions.module.ts
new file mode 100644
index 0000000..cec77c8
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/sessions-page/sessions.module.ts
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule }      from '@angular/core';
+import { CommonModule }  from '@angular/common';
+
+import { TranslateModule } from '@ngx-translate/core';
+
+import {WidgetsModule} from '../widgets/widgets.module';
+
+import { SessionsRoutingModule } from './sessions-routing.module';
+
+import { SessionsPageComponent } from './sessions-page.component';
+import { LargeSessionCardComponent } from './large-session-card.component';
+import { SmallSessionCardComponent } from './small-session-card.component';
+
+@NgModule({
+  imports:      [ CommonModule, 
+                  TranslateModule, 
+                  SessionsRoutingModule,
+                  WidgetsModule ],
+  declarations: [ SessionsPageComponent,
+                  LargeSessionCardComponent,
+                  SmallSessionCardComponent ],
+  providers:    [ ]
+})
+export class SessionsModule {}
+
+
+
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/sessions-page/sessions-page.component.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/sessions-page/sessions-page.component.ts
index 95a519a..2ffb989 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/sessions-page/sessions-page.component.ts
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/sessions-page/sessions-page.component.ts
@@ -18,7 +18,7 @@ import {Component, OnInit} from '@angular/core';
 import {Response} from '@angular/http';
 
 import {AccountServiceClient} from '../../account-service/account.service';
- import {TranslateUtil} from '../../ngx-translate/translate.util';
+import {TranslateUtil} from '../../ngx-translate/translate.util';
 
 import {View} from '../widgets/toolbar.component';
 import {PropertyLabel} from '../widgets/property.label';
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/sessions-page/sessions-routing.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/sessions-page/sessions-routing.module.ts
new file mode 100644
index 0000000..da6e3ab
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/sessions-page/sessions-routing.module.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule }             from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { SessionsPageComponent } from './sessions-page.component';
+
+const routes: Routes = [
+    { path: '**', component: SessionsPageComponent },
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule]
+})
+export class SessionsRoutingModule {}
+
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/widgets/widgets.module.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/widgets/widgets.module.ts
new file mode 100644
index 0000000..422fd30
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/widgets/widgets.module.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { NgModule }      from '@angular/core';
+import { CommonModule }  from '@angular/common';
+import { FormsModule } from '@angular/forms';
+
+import { ToolbarComponent } from './toolbar.component';
+import {OrderbyPipe} from './orderby.pipe';
+import {FilterbyPipe} from './filterby.pipe';
+
+@NgModule({
+  imports:      [ CommonModule, FormsModule ],
+  declarations: [ ToolbarComponent, OrderbyPipe, FilterbyPipe ],
+  exports: [ ToolbarComponent,
+             OrderbyPipe,
+             FilterbyPipe ],
+  providers:    [ ]
+})
+export class WidgetsModule {}
+
+
+
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/keycloak-service/keycloak.guard.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/keycloak-service/keycloak.guard.ts
new file mode 100644
index 0000000..39239a1
--- /dev/null
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/keycloak-service/keycloak.guard.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2018 Red Hat, Inc. and/or its affiliates
+ * and other contributors as indicated by the @author tags.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+import {Injectable} from '@angular/core';
+import {CanActivateChild, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
+import {KeycloakService} from './keycloak.service';
+
+@Injectable()
+export class KeycloakGuard implements CanActivateChild {
+    constructor(private keycloakService: KeycloakService) {}
+    
+    canActivateChild(route: ActivatedRouteSnapshot,
+                state: RouterStateSnapshot): boolean {
+
+        if (this.keycloakService.authenticated()) {
+            return true;
+        }
+
+        this.keycloakService.login();
+        return false;
+    }
+}
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/keycloak-service/keycloak.js b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/keycloak-service/keycloak.js
index a784936..80b4477 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/keycloak-service/keycloak.js
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/keycloak-service/keycloak.js
@@ -40,6 +40,8 @@
             }
         }
 
+        var useNonce = true;
+        
         kc.init = function (initOptions) {
             kc.authenticated = false;
 
@@ -50,7 +52,7 @@
             } else if (initOptions && initOptions.adapter === 'default') {
                 adapter = loadAdapter();
             } else {
-                if (window.Cordova) {
+                if (window.Cordova || window.cordova) {
                     adapter = loadAdapter('cordova');
                 } else {
                     adapter = loadAdapter();
@@ -58,6 +60,10 @@
             }
 
             if (initOptions) {
+                if (typeof initOptions.useNonce !== 'undefined') {
+                    useNonce = initOptions.useNonce;
+                }
+
                 if (typeof initOptions.checkLoginIframe !== 'undefined') {
                     loginIframe.enable = initOptions.checkLoginIframe;
                 }
@@ -159,10 +165,15 @@
                 var callback = parseCallback(window.location.href);
 
                 if (callback) {
-                    setupCheckLoginIframe();
                     window.history.replaceState({}, null, callback.newUrl);
-                    processCallback(callback, initPromise);
-                    return;
+                }
+
+                if (callback && callback.valid) {
+                    return setupCheckLoginIframe().success(function() {
+                        processCallback(callback, initPromise);
+                    }).error(function (e) {
+                        initPromise.setError();
+                    });
                 } else if (initOptions) {
                     if (initOptions.token && initOptions.refreshToken) {
                         setToken(initOptions.token, initOptions.refreshToken, initOptions.idToken);
@@ -221,7 +232,7 @@
             var callbackState = {
                 state: state,
                 nonce: nonce,
-                redirectUri: encodeURIComponent(redirectUri),
+                redirectUri: encodeURIComponent(redirectUri)
             }
 
             if (options && options.prompt) {
@@ -230,22 +241,25 @@
 
             callbackStorage.add(callbackState);
 
-            var action = 'auth';
+            var baseUrl;
             if (options && options.action == 'register') {
-                action = 'registrations';
+                baseUrl = kc.endpoints.register();
+            } else {
+                baseUrl = kc.endpoints.authorize();
             }
 
             var scope = (options && options.scope) ? "openid " + options.scope : "openid";
 
-            var url = getRealmUrl()
-                + '/protocol/openid-connect/' + action
+            var url = baseUrl
                 + '?client_id=' + encodeURIComponent(kc.clientId)
                 + '&redirect_uri=' + encodeURIComponent(redirectUri)
                 + '&state=' + encodeURIComponent(state)
-                + '&nonce=' + encodeURIComponent(nonce)
                 + '&response_mode=' + encodeURIComponent(kc.responseMode)
                 + '&response_type=' + encodeURIComponent(kc.responseType)
                 + '&scope=' + encodeURIComponent(scope);
+                if (useNonce) {
+                    url = url + '&nonce=' + encodeURIComponent(nonce);
+                }
 
             if (options && options.prompt) {
                 url += '&prompt=' + encodeURIComponent(options.prompt);
@@ -275,8 +289,7 @@
         }
 
         kc.createLogoutUrl = function(options) {
-            var url = getRealmUrl()
-                + '/protocol/openid-connect/logout'
+            var url = kc.endpoints.logout()
                 + '?redirect_uri=' + encodeURIComponent(adapter.redirectUri(options, false));
 
             return url;
@@ -295,11 +308,14 @@
         }
 
         kc.createAccountUrl = function(options) {
-            var url = getRealmUrl()
+            var realm = getRealmUrl();
+            var url = undefined;
+            if (typeof realm !== 'undefined') {
+                url = realm
                 + '/account'
                 + '?referrer=' + encodeURIComponent(kc.clientId)
                 + '&referrer_uri=' + encodeURIComponent(adapter.redirectUri(options));
-
+            }
             return url;
         }
 
@@ -347,7 +363,7 @@
         }
 
         kc.loadUserInfo = function() {
-            var url = getRealmUrl() + '/protocol/openid-connect/userinfo';
+            var url = kc.endpoints.userinfo();
             var req = new XMLHttpRequest();
             req.open('GET', url, true);
             req.setRequestHeader('Accept', 'application/json');
@@ -412,7 +428,7 @@
                     promise.setSuccess(false);
                 } else {
                     var params = 'grant_type=refresh_token&' + 'refresh_token=' + kc.refreshToken;
-                    var url = getRealmUrl() + '/protocol/openid-connect/token';
+                    var url = kc.endpoints.token();
 
                     refreshQueue.push(promise);
 
@@ -486,10 +502,14 @@
         }
 
         function getRealmUrl() {
-            if (kc.authServerUrl.charAt(kc.authServerUrl.length - 1) == '/') {
-                return kc.authServerUrl + 'realms/' + encodeURIComponent(kc.realm);
+            if (typeof kc.authServerUrl !== 'undefined') {
+                if (kc.authServerUrl.charAt(kc.authServerUrl.length - 1) == '/') {
+                    return kc.authServerUrl + 'realms/' + encodeURIComponent(kc.realm);
+                } else {
+                    return kc.authServerUrl + '/realms/' + encodeURIComponent(kc.realm);
+                }
             } else {
-                return kc.authServerUrl + '/realms/' + encodeURIComponent(kc.realm);
+            	return undefined;
             }
         }
 
@@ -523,7 +543,7 @@
 
             if ((kc.flow != 'implicit') && code) {
                 var params = 'code=' + code + '&grant_type=authorization_code';
-                var url = getRealmUrl() + '/protocol/openid-connect/token';
+                var url = kc.endpoints.token();
 
                 var req = new XMLHttpRequest();
                 req.open('POST', url, true);
@@ -560,9 +580,9 @@
 
                 setToken(accessToken, refreshToken, idToken, timeLocal);
 
-                if ((kc.tokenParsed && kc.tokenParsed.nonce != oauth.storedNonce) ||
+                if (useNonce && ((kc.tokenParsed && kc.tokenParsed.nonce != oauth.storedNonce) ||
                     (kc.refreshTokenParsed && kc.refreshTokenParsed.nonce != oauth.storedNonce) ||
-                    (kc.idTokenParsed && kc.idTokenParsed.nonce != oauth.storedNonce)) {
+                    (kc.idTokenParsed && kc.idTokenParsed.nonce != oauth.storedNonce))) {
 
                     console.info('[KEYCLOAK] Invalid nonce, clearing token');
                     kc.clearToken();
@@ -587,6 +607,65 @@
                 configUrl = config;
             }
 
+            function setupOidcEndoints(oidcConfiguration) {
+                if (! oidcConfiguration) {
+                    kc.endpoints = {
+                        authorize: function() {
+                            return getRealmUrl() + '/protocol/openid-connect/auth';
+                        },
+                        token: function() {
+                            return getRealmUrl() + '/protocol/openid-connect/token';
+                        },
+                        logout: function() {
+                            return getRealmUrl() + '/protocol/openid-connect/logout';
+                        },
+                        checkSessionIframe: function() {
+                            var src = getRealmUrl() + '/protocol/openid-connect/login-status-iframe.html';
+                            if (kc.iframeVersion) {
+                              src = src + '?version=' + kc.iframeVersion;
+                            }
+                            return src;
+                        },
+                        register: function() {
+                            return getRealmUrl() + '/protocol/openid-connect/registrations';
+                        },
+                        userinfo: function() {
+                            return getRealmUrl() + '/protocol/openid-connect/userinfo';
+                        }
+                    };
+                } else {
+                    kc.endpoints = {
+                        authorize: function() {
+                            return oidcConfiguration.authorization_endpoint;
+                        },
+                        token: function() {
+                            return oidcConfiguration.token_endpoint;
+                        },
+                        logout: function() {
+                            if (!oidcConfiguration.end_session_endpoint) {
+                                throw "Not supported by the OIDC server";
+                            }
+                            return oidcConfiguration.end_session_endpoint;
+                        },
+                        checkSessionIframe: function() {
+                            if (!oidcConfiguration.check_session_iframe) {
+                                throw "Not supported by the OIDC server";
+                            }
+                            return oidcConfiguration.check_session_iframe;
+                        },
+                        register: function() {
+                            throw 'Redirection to "Register user" page not supported in standard OIDC mode';
+                        },
+                        userinfo: function() {
+                            if (!oidcConfiguration.userinfo_endpoint) {
+                                throw "Not supported by the OIDC server";
+                            }
+                            return oidcConfiguration.userinfo_endpoint;
+                        }
+                    }
+                }
+            }
+
             if (configUrl) {
                 var req = new XMLHttpRequest();
                 req.open('GET', configUrl, true);
@@ -601,7 +680,7 @@
                             kc.realm = config['realm'];
                             kc.clientId = config['resource'];
                             kc.clientSecret = (config['credentials'] || {})['secret'];
-
+                            setupOidcEndoints(null);
                             promise.setSuccess();
                         } else {
                             promise.setError();
@@ -611,30 +690,62 @@
 
                 req.send();
             } else {
-                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';
-                }
-
                 if (!config.clientId) {
                     throw 'clientId missing';
                 }
 
-                kc.authServerUrl = config.url;
-                kc.realm = config.realm;
                 kc.clientId = config.clientId;
                 kc.clientSecret = (config.credentials || {}).secret;
 
-                promise.setSuccess();
+                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);
+                    promise.setSuccess();
+                } else {
+                    if (typeof oidcProvider === 'string') {
+                        var oidcProviderConfigUrl;
+                        if (oidcProvider.charAt(oidcProvider.length - 1) == '/') {
+                            oidcProviderConfigUrl = oidcProvider + '.well-known/openid-configuration';
+                        } else {
+                            oidcProviderConfigUrl = oidcProvider + '/.well-known/openid-configuration';
+                        }
+                        var req = new XMLHttpRequest();
+                        req.open('GET', oidcProviderConfigUrl, true);
+                        req.setRequestHeader('Accept', 'application/json');
+
+                        req.onreadystatechange = function () {
+                            if (req.readyState == 4) {
+                                if (req.status == 200 || fileLoaded(req)) {
+                                    var oidcProviderConfig = JSON.parse(req.responseText);
+                                    setupOidcEndoints(oidcProviderConfig);
+                                    promise.setSuccess();
+                                } else {
+                                    promise.setError();
+                                }
+                            }
+                        };
+
+                        req.send();
+                    } else {
+                        setupOidcEndoints(oidcProvider);
+                        promise.setSuccess();
+                    }
+                }
             }
 
             return promise.promise;
@@ -753,23 +864,137 @@
         }
 
         function parseCallback(url) {
-            var oauth = new CallbackParser(url, kc.responseMode).parseUri();
+            var oauth = parseCallbackUrl(url);
+            if (!oauth) {
+                return;
+            }
+
             var oauthState = callbackStorage.get(oauth.state);
 
-            if (oauthState && (oauth.code || oauth.error || oauth.access_token || oauth.id_token)) {
+            if (oauthState) {
+                oauth.valid = true;
                 oauth.redirectUri = oauthState.redirectUri;
                 oauth.storedNonce = oauthState.nonce;
                 oauth.prompt = oauthState.prompt;
+            }
 
-                if (oauth.fragment) {
-                    oauth.newUrl += '#' + oauth.fragment;
+            return oauth;
+        }
+
+        function parseCallbackUrl(url) {
+            var supportedParams;
+            switch (kc.flow) {
+                case 'standard':
+                    supportedParams = ['code', 'state', 'session_state'];
+                    break;
+                case 'implicit':
+                    supportedParams = ['access_token', 'id_token', 'state', 'session_state'];
+                    break;
+                case 'hybrid':
+                    supportedParams = ['access_token', 'id_token', 'code', 'state', 'session_state'];
+                    break;
+            }
+
+            supportedParams.push('error');
+            supportedParams.push('error_description');
+            supportedParams.push('error_uri');
+
+            var queryIndex = url.indexOf('?');
+            var fragmentIndex = url.indexOf('#');
+
+            var newUrl;
+            var parsed;
+
+            if (kc.responseMode === 'query' && queryIndex !== -1) {
+                newUrl = url.substring(0, queryIndex);
+                parsed = parseCallbackParams(url.substring(queryIndex + 1, fragmentIndex !== -1 ? fragmentIndex : url.length), supportedParams);
+                if (parsed.paramsString !== '') {
+                    newUrl += '?' + parsed.paramsString;
+                }
+                if (fragmentIndex !== -1) {
+                    newUrl += url.substring(fragmentIndex);
                 }
+            } else if (kc.responseMode === 'fragment' && fragmentIndex !== -1) {
+                newUrl = url.substring(0, fragmentIndex);
+                parsed = parseCallbackParams(url.substring(fragmentIndex + 1), supportedParams);
+                if (parsed.paramsString !== '') {
+                    newUrl += '#' + parsed.paramsString;
+                }
+            }
 
-                return oauth;
+            if (parsed && parsed.oauthParams) {
+                if (kc.flow === 'standard' || kc.flow === 'hybrid') {
+                    if ((parsed.oauthParams.code || parsed.oauthParams.error) && parsed.oauthParams.state) {
+                        parsed.oauthParams.newUrl = newUrl;
+                        return parsed.oauthParams;
+                    }
+                } else if (kc.flow === 'implicit') {
+                    if ((parsed.oauthParams.access_token || parsed.oauthParams.error) && parsed.oauthParams.state) {
+                        parsed.oauthParams.newUrl = newUrl;
+                        return parsed.oauthParams;
+                    }
+                }
             }
         }
 
+        function parseCallbackParams(paramsString, supportedParams) {
+            var p = paramsString.split('&');
+            var result = {
+                paramsString: '',
+                oauthParams: {}
+            }
+            for (var i = 0; i < p.length; i++) {
+                var t = p[i].split('=');
+                if (supportedParams.indexOf(t[0]) !== -1) {
+                    result.oauthParams[t[0]] = t[1];
+                } else {
+                    if (result.paramsString !== '') {
+                        result.paramsString += '&';
+                    }
+                    result.paramsString += p[i];
+                }
+            }
+            return result;
+        }
+
         function createPromise() {
+            if (typeof Promise === "function") {
+                return createNativePromise();
+            } else {
+                return createLegacyPromise();
+            }
+        }
+
+        function createNativePromise() {
+            // Need to create a native Promise which also preserves the
+            // interface of the custom promise type previously used by the API
+            var p = {
+                setSuccess: function(result) {
+                    p.success = true;
+                    p.resolve(result);
+                },
+
+                setError: function(result) {
+                    p.success = false;
+                    p.reject(result);
+                }
+            };
+            p.promise = new Promise(function(resolve, reject) {
+                p.resolve = resolve;
+                p.reject = reject;
+            });
+            p.promise.success = function(callback) {
+                p.promise.then(callback);
+                return p.promise;
+            }
+            p.promise.error = function(callback) {
+                p.promise.catch(callback);
+                return p.promise;
+            }
+            return p;
+        }
+
+        function createLegacyPromise() {
             var p = {
                 setSuccess: function(result) {
                     p.success = true;
@@ -826,23 +1051,20 @@
             loginIframe.iframe = iframe;
 
             iframe.onload = function() {
-                var realmUrl = getRealmUrl();
-                if (realmUrl.charAt(0) === '/') {
+                var authUrl = kc.endpoints.authorize();
+                if (authUrl.charAt(0) === '/') {
                     loginIframe.iframeOrigin = getOrigin();
                 } else {
-                    loginIframe.iframeOrigin = realmUrl.substring(0, realmUrl.indexOf('/', 8));
+                    loginIframe.iframeOrigin = authUrl.substring(0, authUrl.indexOf('/', 8));
                 }
                 promise.setSuccess();
 
                 setTimeout(check, loginIframe.interval * 1000);
             }
 
-            var src = getRealmUrl() + '/protocol/openid-connect/login-status-iframe.html';
-            if (kc.iframeVersion) {
-                src = src + '?version=' + kc.iframeVersion;
-            }
-
+            var src = kc.endpoints.checkSessionIframe();
             iframe.setAttribute('src', src );
+            iframe.setAttribute('title', 'keycloak-session-iframe' );
             iframe.style.display = 'none';
             document.body.appendChild(iframe);
 
@@ -920,7 +1142,12 @@
                     },
 
                     accountManagement : function() {
-                        window.location.href = kc.createAccountUrl();
+                        var accountUrl = kc.createAccountUrl();
+                        if (typeof accountUrl !== 'undefined') {
+                            window.location.href = accountUrl;
+                        } else {
+                            throw "Not supported by the OIDC server";
+                        }
                         return createPromise().promise;
                     },
 
@@ -934,12 +1161,7 @@
                         } else if (kc.redirectUri) {
                             return kc.redirectUri;
                         } else {
-                            var redirectUri = location.href;
-                            if (location.hash && encodeHash) {
-                                redirectUri = redirectUri.substring(0, location.href.indexOf('#'));
-                                redirectUri += (redirectUri.indexOf('?') == -1 ? '?' : '&') + 'redirect_fragment=' + encodeURIComponent(location.hash.substring(1));
-                            }
-                            return redirectUri;
+                            return location.href;
                         }
                     }
                 };
@@ -947,7 +1169,14 @@
 
             if (type == 'cordova') {
                 loginIframe.enable = false;
-
+                var cordovaOpenWindowWrapper = function(loginUrl, target, options) {
+                    if (window.cordova && window.cordova.InAppBrowser) {
+                        // Use inappbrowser for IOS and Android if available
+                        return window.cordova.InAppBrowser.open(loginUrl, target, options);
+                    } else {
+                        return window.open(loginUrl, target, options);
+                    }
+                };
                 return {
                     login: function(options) {
                         var promise = createPromise();
@@ -958,8 +1187,7 @@
                         }
 
                         var loginUrl = kc.createLoginUrl(options);
-                        var ref = window.open(loginUrl, '_blank', o);
-
+                        var ref = cordovaOpenWindowWrapper(loginUrl, '_blank', o);
                         var completed = false;
 
                         ref.addEventListener('loadstart', function(event) {
@@ -992,7 +1220,7 @@
                         var promise = createPromise();
 
                         var logoutUrl = kc.createLogoutUrl(options);
-                        var ref = window.open(logoutUrl, '_blank', 'location=no,hidden=yes');
+                        var ref = cordovaOpenWindowWrapper(logoutUrl, '_blank', 'location=no,hidden=yes');
 
                         var error;
 
@@ -1025,7 +1253,7 @@
 
                     register : function() {
                         var registerUrl = kc.createRegisterUrl();
-                        var ref = window.open(registerUrl, '_blank', 'location=no');
+                        var ref = cordovaOpenWindowWrapper(registerUrl, '_blank', 'location=no');
                         ref.addEventListener('loadstart', function(event) {
                             if (event.url.indexOf('http://localhost') == 0) {
                                 ref.close();
@@ -1035,12 +1263,16 @@
 
                     accountManagement : function() {
                         var accountUrl = kc.createAccountUrl();
-                        var ref = window.open(accountUrl, '_blank', 'location=no');
-                        ref.addEventListener('loadstart', function(event) {
-                            if (event.url.indexOf('http://localhost') == 0) {
-                                ref.close();
-                            }
-                        });
+                        if (typeof accountUrl !== 'undefined') {
+                            var ref = cordovaOpenWindowWrapper(accountUrl, '_blank', 'location=no');
+                            ref.addEventListener('loadstart', function(event) {
+                                if (event.url.indexOf('http://localhost') == 0) {
+                                    ref.close();
+                                }
+                            });
+                        } else {
+                            throw "Not supported by the OIDC server";
+                        }
                     },
 
                     redirectUri: function(options) {
@@ -1170,99 +1402,6 @@
 
             return new CookieStorage();
         }
-
-        var CallbackParser = function(uriToParse, responseMode) {
-            if (!(this instanceof CallbackParser)) {
-                return new CallbackParser(uriToParse, responseMode);
-            }
-            var parser = this;
-
-            var initialParse = function() {
-                var baseUri = null;
-                var queryString = null;
-                var fragmentString = null;
-
-                var questionMarkIndex = uriToParse.indexOf("?");
-                var fragmentIndex = uriToParse.indexOf("#", questionMarkIndex + 1);
-                if (questionMarkIndex == -1 && fragmentIndex == -1) {
-                    baseUri = uriToParse;
-                } else if (questionMarkIndex != -1) {
-                    baseUri = uriToParse.substring(0, questionMarkIndex);
-                    queryString = uriToParse.substring(questionMarkIndex + 1);
-                    if (fragmentIndex != -1) {
-                        fragmentIndex = queryString.indexOf("#");
-                        fragmentString = queryString.substring(fragmentIndex + 1);
-                        queryString = queryString.substring(0, fragmentIndex);
-                    }
-                } else {
-                    baseUri = uriToParse.substring(0, fragmentIndex);
-                    fragmentString = uriToParse.substring(fragmentIndex + 1);
-                }
-
-                return { baseUri: baseUri, queryString: queryString, fragmentString: fragmentString };
-            }
-
-            var parseParams = function(paramString) {
-                var result = {};
-                var params = paramString.split('&');
-                for (var i = 0; i < params.length; i++) {
-                    var p = params[i].split('=');
-                    var paramName = decodeURIComponent(p[0]);
-                    var paramValue = decodeURIComponent(p[1]);
-                    result[paramName] = paramValue;
-                }
-                return result;
-            }
-
-            var handleQueryParam = function(paramName, paramValue, oauth) {
-                var supportedOAuthParams = [ 'code', 'state', 'error', 'error_description' ];
-
-                for (var i = 0 ; i< supportedOAuthParams.length ; i++) {
-                    if (paramName === supportedOAuthParams[i]) {
-                        oauth[paramName] = paramValue;
-                        return true;
-                    }
-                }
-                return false;
-            }
-
-
-            parser.parseUri = function() {
-                var parsedUri = initialParse();
-
-                var queryParams = {};
-                if (parsedUri.queryString) {
-                    queryParams = parseParams(parsedUri.queryString);
-                }
-
-                var oauth = { newUrl: parsedUri.baseUri };
-                for (var param in queryParams) {
-                    switch (param) {
-                        case 'redirect_fragment':
-                            oauth.fragment = queryParams[param];
-                            break;
-                        default:
-                            if (responseMode != 'query' || !handleQueryParam(param, queryParams[param], oauth)) {
-                                oauth.newUrl += (oauth.newUrl.indexOf('?') == -1 ? '?' : '&') + param + '=' + encodeURIComponent(queryParams[param]);
-                            }
-                            break;
-                    }
-                }
-
-                if (responseMode === 'fragment') {
-                    var fragmentParams = {};
-                    if (parsedUri.fragmentString) {
-                        fragmentParams = parseParams(parsedUri.fragmentString);
-                    }
-                    for (var param in fragmentParams) {
-                        oauth[param] = fragmentParams[param];
-                    }
-                }
-
-                return oauth;
-            }
-        }
-
     }
 
     if ( typeof module === "object" && module && typeof module.exports === "object" ) {
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/keycloak-service/keycloak.service.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/keycloak-service/keycloak.service.ts
index 54f2eaa..97a7407 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/keycloak-service/keycloak.service.ts
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/keycloak-service/keycloak.service.ts
@@ -15,6 +15,7 @@
  * limitations under the License.
  */
 import {Injectable} from '@angular/core';
+import {KeycloakLoginOptions} from './keycloak.d';
 
 // If using a local keycloak.js, uncomment this import.  With keycloak.js fetched
 // from the server, you get a compile-time warning on use of the Keycloak()
@@ -23,7 +24,7 @@ import {Injectable} from '@angular/core';
 // 
 import * as Keycloak from './keycloak';
 
-type KeycloakClient = Keycloak.KeycloakInstance;
+export type KeycloakClient = Keycloak.KeycloakInstance;
 type InitOptions = Keycloak.KeycloakInitOptions;
 
 @Injectable()
@@ -52,17 +53,21 @@ export class KeycloakService {
                 });
         });
     }
+    
+    static setKeycloakAuth(kc:KeycloakClient) {
+        this.keycloakAuth = kc;
+    }
 
     authenticated(): boolean {
         return KeycloakService.keycloakAuth.authenticated;
     }
 
-    login() {
-        KeycloakService.keycloakAuth.login();
+    login(options?: KeycloakLoginOptions) {
+        KeycloakService.keycloakAuth.login(options);
     }
 
-    logout() {
-        KeycloakService.keycloakAuth.logout();
+    logout(redirectUri?: string) {
+        KeycloakService.keycloakAuth.logout({redirectUri: redirectUri});
     }
 
     account() {
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/top-nav/top-nav.component.html b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/top-nav/top-nav.component.html
index 4b30962..0669b26 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/top-nav/top-nav.component.html
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/top-nav/top-nav.component.html
@@ -1,17 +1,17 @@
-
+<!-- Top Nav -->
 
 <nav class="navbar navbar-pf-alt">
     <notification></notification>
 
     <div class="navbar-header">
-        <button (click)="menuClicked()" type="button" class="navbar-toggle">
+        <button *ngIf="keycloakService.authenticated() && showSideNav" (click)="menuClicked()" type="button" class="navbar-toggle">
             <span class="sr-only">Toggle navigation</span>
             <span class="icon-bar"></span>
             <span class="icon-bar"></span>
             <span class="icon-bar"></span>
         </button>
         <a href="http://www.keycloak.org" class="navbar-brand">
-            <img class="navbar-brand-icon" type="image/svg+xml" src="{{resourceUrl}}/app/assets/img/keycloak-logo.png" alt="" width="auto" height="30px"/>
+            <img class="navbar-brand-icon" type="image/svg+xml" src="{{resourceUrl}}/app/assets/img/keycloak-logo-min.png" alt="" width="auto" height="30px"/>
         </a>
     </div>
     <nav class="collapse navbar-collapse">
@@ -21,17 +21,7 @@
             <li *ngIf="referrer.exists()">
                 <a class="nav-item-iconic" href="{{referrer.getUri()}}"><span class="pficon-arrow"></span> {{'backTo' | translate:referrer.getName()}}</a>
             </li>
-            <li class="dropdown">
-                <a class="dropdown-toggle nav-item-iconic" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
-                    <span title="Help" class="fa pficon-help"></span>
-                    <span class="caret"></span>
-                </a>
-                <ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
-                    <li><a href="#">Help</a></li>
-                    <li><a href="#">About</a></li>
-                </ul>
-            </li>
-            <li class="dropdown">
+            <li class="dropdown" (click)="logout()">
                 <a class="dropdown-toggle nav-item-iconic" id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
                     <span title="Username" class="fa pficon-user"></span>
                     <span class="caret"></span>
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/top-nav/top-nav.component.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/top-nav/top-nav.component.ts
index 88a0c14..65f3ea0 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/app/top-nav/top-nav.component.ts
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/app/top-nav/top-nav.component.ts
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import {Component, OnInit} from '@angular/core';
+import {Component, OnInit, Input} from '@angular/core';
 import {TranslateUtil} from '../ngx-translate/translate.util';
 import {KeycloakService} from '../keycloak-service/keycloak.service';
 import {ResponsivenessService} from "../responsiveness-service/responsiveness.service";
@@ -30,6 +30,7 @@ declare const referrer_uri: string;
     styleUrls: ['./top-nav.component.css']
 })
 export class TopNavComponent implements OnInit {
+    @Input() showSideNav: String;
 
     public resourceUrl: string = resourceUrl;
     
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/main.ts b/themes/src/main/resources/theme/keycloak-preview/account/resources/main.ts
index b5db7b0..ded194f 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/main.ts
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/main.ts
@@ -21,7 +21,8 @@ import { platformBrowser } from '@angular/platform-browser';
 import { AppModule } from './app/app.module';
 //import { environment } from './environments/environment';
 
-import { KeycloakService } from './app/keycloak-service/keycloak.service';
+import { KeycloakService, KeycloakClient } from './app/keycloak-service/keycloak.service';
+
 
 //if (environment.production) {
 //  enableProdMode();
@@ -30,17 +31,17 @@ import { KeycloakService } from './app/keycloak-service/keycloak.service';
 declare const authUrl: string;
 declare const resourceUrl: string;
 declare const realm: string;
+declare const keycloak: KeycloakClient;
+
+KeycloakService.setKeycloakAuth(keycloak);
+
+loadCss('/styles.css');
+platformBrowserDynamic().bootstrapModule(AppModule);
 
-const noLogin: boolean = false; // convenient for development
-if (noLogin) {
-    platformBrowserDynamic().bootstrapModule(AppModule);
-} else {
-    KeycloakService.init(authUrl + '/realms/' + realm + '/account/keycloak.json',
-                         {onLoad: 'login-required'})
-        .then(() => {
-            platformBrowserDynamic().bootstrapModule(AppModule);
-        })
-        .catch((e: any) => {
-            console.log('Error in bootstrap: ' + JSON.stringify(e));
-        });
+function loadCss(url:string) {
+    const link = document.createElement("link");
+    link.href = resourceUrl + url;
+    link.rel = "stylesheet";
+    link.media = "screen, print";
+    document.head.appendChild(link);
 }
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 1ea8c3c..d2d733a 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
@@ -24,18 +24,22 @@
   "author": "Stan Silvert",
   "license": "Apache 2.0",
   "dependencies": {
-    "@angular/common": "~4.0.0",
-    "@angular/compiler": "~4.0.0",
-    "@angular/core": "~4.0.0",
-    "@angular/forms": "~4.0.0",
-    "@angular/http": "~4.0.0",
-    "@angular/platform-browser": "~4.0.0",
-    "@angular/platform-browser-dynamic": "~4.0.0",
-    "@angular/router": "~4.0.0",
-    "@ngx-translate/core": "^7.1.0",
+    "@angular/animations": "'5.0.0'",
+    "@angular/common": "'5.0.0'",
+    "@angular/compiler": "'5.0.0'",
+    "@angular/compiler-cli": "'5.0.0'",
+    "@angular/core": "'5.0.0'",
+    "@angular/forms": "'5.0.0'",
+    "@angular/http": "'5.0.0'",
+    "@angular/platform-browser": "'5.0.0'",
+    "@angular/platform-browser-dynamic": "'5.0.0'",
+    "@angular/platform-server": "'5.0.0'",
+    "@angular/router": "'5.0.0'",
+    "@ngx-translate/core": "^9.1.1",
     "core-js": "^2.4.1",
     "patternfly": "^3.23.2",
-    "rxjs": "^5.4.2",
+    "rxjs": "5.5.2",
+    "rxjs-system-bundle": "^5.5.6",
     "systemjs": "^0.20.17",
     "zone.js": "^0.8.4"
   },
@@ -55,7 +59,7 @@
     "protractor": "~4.0.14",
     "rimraf": "^2.5.4",
     "tslint": "^3.15.1",
-    "typescript": "^2.4.2"
+    "typescript": "2.4.2"
   },
   "repository": {}
 }
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/styles.css b/themes/src/main/resources/theme/keycloak-preview/account/resources/styles.css
index 58e1a7d..e69de29 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/styles.css
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/styles.css
@@ -1,5 +0,0 @@
-h1 {
-  color: #369;
-  font-family: Arial, Helvetica, sans-serif;
-  font-size: 250%;
-}
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 7814857..6a100cd 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
@@ -14,20 +14,32 @@
       'app': resourceUrl + '/app',
 
       // angular bundles
-      '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
-      '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
-      '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
-      '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
-      '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
-      '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
-      '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
-      '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
+      '@angular/core': 'npm:@angular/core/bundles/core.umd.min.js',
+      '@angular/common': 'npm:@angular/common/bundles/common.umd.min.js',
+      '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.min.js',
+      '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.min.js',
+      '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.min.js',
+      '@angular/http': 'npm:@angular/http/bundles/http.umd.min.js',
+      '@angular/router': 'npm:@angular/router/bundles/router.umd.min.js',
+      '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.min.js',
       
       // other libraries
-      '@ngx-translate/core':       'npm:@ngx-translate/core/bundles/core.umd.js',
-      'rxjs':                      'npm:rxjs',
+      '@ngx-translate/core':       'npm:@ngx-translate/core/bundles/core.umd.min.js',
       'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
     },
+    bundles: {
+        "npm:rxjs-system-bundle/Rx.system.min.js": [
+          "rxjs",
+          "rxjs/*",
+          "rxjs/operator/*",
+          "rxjs/observable/*",
+          "rxjs/scheduler/*",
+          "rxjs/symbol/*",
+          "rxjs/add/operator/*",
+          "rxjs/add/observable/*",
+          "rxjs/util/*"
+        ]
+      },
     // packages tells the System loader how to load when no filename and/or no extension
     packages: {
       app: {
@@ -42,7 +54,7 @@
           defaultExtension: 'js'
       },
       rxjs: {
-        defaultExtension: 'js'
+        defaultExtension: false
       }
     }
   });
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/resources/yarn.lock b/themes/src/main/resources/theme/keycloak-preview/account/resources/yarn.lock
index c335da6..4bdfbbf 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/resources/yarn.lock
+++ b/themes/src/main/resources/theme/keycloak-preview/account/resources/yarn.lock
@@ -2,41 +2,80 @@
 # yarn lockfile v1
 
 
-"@angular/common@~4.0.0":
-  version "4.0.3"
-  resolved "https://registry.yarnpkg.com/@angular/common/-/common-4.0.3.tgz#17472895eb425f2812b3a79162b5b494d2506a5b"
+"@angular/animations@'5.0.0'":
+  version "5.2.7"
+  resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-5.2.7.tgz#a99fe128f3809e3f8082441a6e676992b9352db7"
+  dependencies:
+    tslib "^1.7.1"
+
+"@angular/common@'5.0.0'":
+  version "5.2.7"
+  resolved "https://registry.yarnpkg.com/@angular/common/-/common-5.2.7.tgz#11bb9f00afe91af8d772ecdff83c2e179f9a67a0"
+  dependencies:
+    tslib "^1.7.1"
+
+"@angular/compiler-cli@'5.0.0'":
+  version "5.2.7"
+  resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-5.2.7.tgz#3bad9d5e4c25ebc51e1bb67b71b26a97d6d3bbc5"
+  dependencies:
+    chokidar "^1.4.2"
+    minimist "^1.2.0"
+    reflect-metadata "^0.1.2"
+    tsickle "^0.27.2"
+
+"@angular/compiler@'5.0.0'":
+  version "5.2.7"
+  resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-5.2.7.tgz#31dcc7ac18cc23cb115e76c541b982737ff93ec9"
+  dependencies:
+    tslib "^1.7.1"
 
-"@angular/compiler@~4.0.0":
-  version "4.0.3"
-  resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-4.0.3.tgz#8b3cad338ac539328e10a6a4bfaa057094f7bc89"
+"@angular/core@'5.0.0'":
+  version "5.2.7"
+  resolved "https://registry.yarnpkg.com/@angular/core/-/core-5.2.7.tgz#e5607fc39d90f9fe4fbaaeeeb6cdb9371966bfe3"
+  dependencies:
+    tslib "^1.7.1"
 
-"@angular/core@~4.0.0":
-  version "4.0.3"
-  resolved "https://registry.yarnpkg.com/@angular/core/-/core-4.0.3.tgz#61be21db6aa5778e33159ffd38cbbebaf16120d9"
+"@angular/forms@'5.0.0'":
+  version "5.2.7"
+  resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-5.2.7.tgz#a0c41fdb6b8ba2c32653cc3058d5fa47db91fbf8"
+  dependencies:
+    tslib "^1.7.1"
 
-"@angular/forms@~4.0.0":
-  version "4.0.3"
-  resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-4.0.3.tgz#fb8e6e0aede782bf58730a31d1179b323271816e"
+"@angular/http@'5.0.0'":
+  version "5.2.7"
+  resolved "https://registry.yarnpkg.com/@angular/http/-/http-5.2.7.tgz#a163f6958f12d2665419123861b0d613c1c82afb"
+  dependencies:
+    tslib "^1.7.1"
 
-"@angular/http@~4.0.0":
-  version "4.0.3"
-  resolved "https://registry.yarnpkg.com/@angular/http/-/http-4.0.3.tgz#efbb701a215ec7704c021676484b85ed47392f4b"
+"@angular/platform-browser-dynamic@'5.0.0'":
+  version "5.2.7"
+  resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-5.2.7.tgz#91f903c1f73de2fba1004bc31ed1c3117c7f0406"
+  dependencies:
+    tslib "^1.7.1"
 
-"@angular/platform-browser-dynamic@~4.0.0":
-  version "4.0.3"
-  resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-4.0.3.tgz#5fa3b98f725999b631d7d7174e6e43dcbf6aa9ac"
+"@angular/platform-browser@'5.0.0'":
+  version "5.2.7"
+  resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-5.2.7.tgz#cfd86040c25380aabf0322ef47aecc61f23cc532"
+  dependencies:
+    tslib "^1.7.1"
 
-"@angular/platform-browser@~4.0.0":
-  version "4.0.3"
-  resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-4.0.3.tgz#170b18d5af4ee02b248aa6a1f1e0584ac841681e"
+"@angular/platform-server@'5.0.0'":
+  version "5.2.7"
+  resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-5.2.7.tgz#e2eb290952dbe6ab04b4edae115a0d02b8b2dc4c"
+  dependencies:
+    domino "^1.0.29"
+    tslib "^1.7.1"
+    xhr2 "^0.1.4"
 
-"@angular/router@~4.0.0":
-  version "4.0.3"
-  resolved "https://registry.yarnpkg.com/@angular/router/-/router-4.0.3.tgz#24184e9b1266c4ad017b2be81573464b1e4c5dfa"
+"@angular/router@'5.0.0'":
+  version "5.2.7"
+  resolved "https://registry.yarnpkg.com/@angular/router/-/router-5.2.7.tgz#691c375fe32f01bea56d169469ad8f254b136af9"
+  dependencies:
+    tslib "^1.7.1"
 
-"@ngx-translate/core@^7.1.0":
-  version "7.1.0"
-  resolved "https://registry.yarnpkg.com/@ngx-translate/core/-/core-7.1.0.tgz#5087a65c8ff312e4244ca0646ed45cde83b170cd"
+"@ngx-translate/core@^9.1.1":
+  version "9.1.1"
+  resolved "https://registry.yarnpkg.com/@ngx-translate/core/-/core-9.1.1.tgz#ae103928836b8a9e069fd2e2e76fa2198cc7e628"
 
 "@types/jasmine@2.5.36", "@types/jasmine@^2.5.36":
   version "2.5.36"
@@ -471,7 +510,7 @@ chalk@^1.1.1, chalk@^1.1.3:
     strip-ansi "^3.0.0"
     supports-color "^2.0.0"
 
-chokidar@1.7.0, chokidar@^1.4.1:
+chokidar@1.7.0, chokidar@^1.4.1, chokidar@^1.4.2:
   version "1.7.0"
   resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
   dependencies:
@@ -769,6 +808,10 @@ dom-serialize@^2.2.0:
     extend "^3.0.0"
     void-elements "^2.0.0"
 
+domino@^1.0.29:
+  version "1.0.30"
+  resolved "https://registry.yarnpkg.com/domino/-/domino-1.0.30.tgz#54a4154ecae968616680f8feba3cedff355c71f4"
+
 drmonty-datatables-colvis@~1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/drmonty-datatables-colvis/-/drmonty-datatables-colvis-1.1.2.tgz#96ab9edfb48643cc2edda3f87b88933cdee8127c"
@@ -2196,6 +2239,10 @@ readdirp@^2.0.0:
     readable-stream "^2.0.2"
     set-immediate-shim "^1.0.1"
 
+reflect-metadata@^0.1.2:
+  version "0.1.12"
+  resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.12.tgz#311bf0c6b63cd782f228a81abe146a2bfa9c56f2"
+
 regex-cache@^0.4.2:
   version "0.4.3"
   resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145"
@@ -2310,9 +2357,13 @@ rx@4.1.0:
   version "4.1.0"
   resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782"
 
-rxjs@^5.4.2:
-  version "5.4.2"
-  resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.4.2.tgz#2a3236fcbf03df57bae06fd6972fd99e5c08fcf7"
+rxjs-system-bundle@^5.5.6:
+  version "5.5.6"
+  resolved "https://registry.yarnpkg.com/rxjs-system-bundle/-/rxjs-system-bundle-5.5.6.tgz#3af9c02a36938f750fe33751cca2397fcf3d04b8"
+
+rxjs@5.5.2:
+  version "5.5.2"
+  resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.2.tgz#28d403f0071121967f18ad665563255d54236ac3"
   dependencies:
     symbol-observable "^1.0.1"
 
@@ -2497,6 +2548,12 @@ socket.io@1.7.3:
     socket.io-client "1.7.3"
     socket.io-parser "2.3.1"
 
+source-map-support@^0.5.0:
+  version "0.5.3"
+  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.3.tgz#2b3d5fff298cfa4d1afd7d4352d569e9a0158e76"
+  dependencies:
+    source-map "^0.6.0"
+
 source-map-support@~0.4.0:
   version "0.4.15"
   resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1"
@@ -2507,6 +2564,10 @@ source-map@^0.5.3, source-map@^0.5.6:
   version "0.5.6"
   resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
 
+source-map@^0.6.0:
+  version "0.6.1"
+  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+
 spawn-command@^0.0.2-1:
   version "0.0.2"
   resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2.tgz#9544e1a43ca045f8531aac1a48cb29bdae62338e"
@@ -2614,8 +2675,8 @@ supports-color@^3.2.3:
     has-flag "^1.0.0"
 
 symbol-observable@^1.0.1:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d"
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
 
 systemjs@^0.20.17:
   version "0.20.17"
@@ -2673,6 +2734,19 @@ tree-kill@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.1.0.tgz#c963dcf03722892ec59cba569e940b71954d1729"
 
+tsickle@^0.27.2:
+  version "0.27.2"
+  resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.27.2.tgz#f33d46d046f73dd5c155a37922e422816e878736"
+  dependencies:
+    minimist "^1.2.0"
+    mkdirp "^0.5.1"
+    source-map "^0.6.0"
+    source-map-support "^0.5.0"
+
+tslib@^1.7.1:
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8"
+
 tslint@^3.15.1:
   version "3.15.1"
   resolved "https://registry.yarnpkg.com/tslint/-/tslint-3.15.1.tgz#da165ca93d8fdc2c086b51165ee1bacb48c98ea5"
@@ -2706,7 +2780,7 @@ type-is@~1.6.14:
     media-typer "0.3.0"
     mime-types "~2.1.15"
 
-typescript@^2.4.2:
+typescript@2.4.2:
   version "2.4.2"
   resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.4.2.tgz#f8395f85d459276067c988aa41837a8f82870844"
 
@@ -2868,6 +2942,10 @@ wtf-8@1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/wtf-8/-/wtf-8-1.0.0.tgz#392d8ba2d0f1c34d1ee2d630f15d0efb68e1048a"
 
+xhr2@^0.1.4:
+  version "0.1.4"
+  resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.4.tgz#7f87658847716db5026323812f818cadab387a5f"
+
 xml2js@0.4.4:
   version "0.4.4"
   resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.4.tgz#3111010003008ae19240eba17497b57c729c555d"
diff --git a/themes/src/main/resources/theme/keycloak-preview/account/theme.properties b/themes/src/main/resources/theme/keycloak-preview/account/theme.properties
index 4cd0e08..fb2e245 100644
--- a/themes/src/main/resources/theme/keycloak-preview/account/theme.properties
+++ b/themes/src/main/resources/theme/keycloak-preview/account/theme.properties
@@ -1,3 +1,2 @@
 parent=base
-import=login/keycloak
 deprecatedMode=false
\ No newline at end of file