keycloak-uncached
Changes
themes/src/main/resources/theme/keycloak-preview/account/resources/app/app-routing.module.ts 44(+44 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/assets/img/keycloak-logo-min.png 0(+0 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/account-page/account.module.ts 34(+34 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/account-page/account-routing.module.ts 31(+31 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/applications-page/applications.module.ts 44(+44 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/applications-page/applications-routing.module.ts 31(+31 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/authenticator-page/authenticator.module.ts 33(+33 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/authenticator-page/authenticator-routing.module.ts 31(+31 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/home-page/home-page.component.css 0(+0 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/home-page/home-page.component.html 68(+68 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/home-page/home-page.component.ts 28(+28 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/page-not-found/page-not-found.module.ts 34(+34 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/page-not-found/page-not-found-routing.module.ts 31(+31 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/password-page/password.module.ts 34(+34 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/password-page/password-routing.module.ts 31(+31 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/sessions-page/sessions.module.ts 43(+43 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/sessions-page/sessions-page.component.ts 2(+1 -1)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/sessions-page/sessions-routing.module.ts 31(+31 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/widgets/filterby.pipe.ts 0(+0 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/widgets/orderby.pipe.ts 0(+0 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/content/widgets/widgets.module.ts 36(+36 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/keycloak-service/keycloak.guard.ts 36(+36 -0)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/keycloak-service/keycloak.js 467(+303 -164)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/keycloak-service/keycloak.service.ts 15(+10 -5)
themes/src/main/resources/theme/keycloak-preview/account/resources/app/top-nav/top-nav.component.html 18(+4 -14)
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