KEYCLOAK-6494: Address load time of new acct mgt console (#5100)
* Optimize loading. min bundles, stop double-loading, rxjs-system instead of plain rxjs, clean up 404's * Create module loading hierarchy. Allows for lazy loading. * Upgrade NG, remove jquery, load keycloak.js only from auth/js * Delay systemjs loading. Load home page instead of account. * KEYCLOAK-6496: Cleanup and polish code after optimizations. * Fix message bundle to be back the way it was. * Remove unused png's. Remove comments in index.ftl. Remove javaMessages.
This commit is contained in:
1 parent
ffeb0420bf
commit
80feb67fc2
37 files changed
+1278
-362
No files matched your search
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
<!-- Polyfill(s) for older browsers -->
|
||||
<script src="${resourceUrl}/node_modules/core-js/client/shim.min.js"></script>
|
||||
<script src="${resourceUrl}/node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
|
||||
<script src="${resourceUrl}/node_modules/patternfly/dist/js/patternfly.min.js"></script>
|
||||
<script src="${authUrl}/js/keycloak.js"></script>
|
||||
|
||||
<script>
|
||||
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>
|
||||
|
||||
|
||||
<!-- 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>
|
||||
|
||||
<#if properties.scripts?has_content>
|
||||
<#list properties.scripts?split(' ') as script>
|
||||
<script type="text/javascript" src="${resourceUrl}/${script}"></script>
|
||||
<script type="text/javascript" src="${resourceUrl}/${script}"></script>
|
||||
</#list>
|
||||
</#if>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script src="${resourceUrl}/node_modules/zone.js/dist/zone.js"></script>
|
||||
<script src="${resourceUrl}/node_modules/systemjs/dist/system.src.js"></script>
|
||||
|
||||
|
||||
<!-- Top Navigation -->
|
||||
<nav class="navbar navbar-pf-alt">
|
||||
|
||||
<script src="${resourceUrl}/systemjs.config.js"></script>
|
||||
<script>
|
||||
System.import('${resourceUrl}/main.js').catch(function (err) {
|
||||
console.error(err);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
<body class="cards-pf kc-background">
|
||||
<div class='logo-centered kc-logo-text'/>
|
||||
</body>
|
||||
</app-root>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<app-root></app-root>
|
||||
</body>
|
||||
</html>
|
||||
+44
@@ -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 {}
|
||||
|
||||
+5
-3
@@ -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>
|
||||
+21
-2
@@ -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 {
|
||||
|
||||
+5
-43
@@ -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,
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
+31
@@ -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 {}
|
||||
|
||||
+34
@@ -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 {}
|
||||
|
||||
|
||||
|
||||
+31
@@ -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 {}
|
||||
|
||||
+44
@@ -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 {}
|
||||
|
||||
|
||||
|
||||
+31
@@ -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 {}
|
||||
|
||||
+33
@@ -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 {}
|
||||
|
||||
|
||||
|
||||
Whitespace-only changes.
+68
@@ -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>
|
||||
+28
@@ -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() {}
|
||||
|
||||
}
|
||||
+31
@@ -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 {}
|
||||
|
||||
+34
@@ -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 {}
|
||||
|
||||
|
||||
|
||||
+31
@@ -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 {}
|
||||
|
||||
+34
@@ -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 {}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -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';
|
||||
|
||||
+31
@@ -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 {}
|
||||
|
||||
+43
@@ -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 {}
|
||||
|
||||
|
||||
|
||||
File renamed without changes.
File renamed without changes.
+36
@@ -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 {}
|
||||
|
||||
|
||||
|
||||
+36
@@ -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;
|
||||
}
|
||||
}
|
||||
+303
-164
@@ -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" ) {
|
||||
|
||||
+10
-5
@@ -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() {
|
||||
|
||||
+4
-14
@@ -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>
|
||||
|
||||
+2
-1
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
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));
|
||||
});
|
||||
KeycloakService.setKeycloakAuth(keycloak);
|
||||
|
||||
loadCss('/styles.css');
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
|
||||
function loadCss(url:string) {
|
||||
const link = document.createElement("link");
|
||||
link.href = resourceUrl + url;
|
||||
link.rel = "stylesheet";
|
||||
link.media = "screen, print";
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
@@ -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": {}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
h1 {
|
||||
color: #369;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 250%;
|
||||
}
|
||||
+23
-11
@@ -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
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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/compiler@~4.0.0":
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-4.0.3.tgz#8b3cad338ac539328e10a6a4bfaa057094f7bc89"
|
||||
"@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/core@~4.0.0":
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@angular/core/-/core-4.0.3.tgz#61be21db6aa5778e33159ffd38cbbebaf16120d9"
|
||||
"@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/forms@~4.0.0":
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-4.0.3.tgz#fb8e6e0aede782bf58730a31d1179b323271816e"
|
||||
"@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/http@~4.0.0":
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@angular/http/-/http-4.0.3.tgz#efbb701a215ec7704c021676484b85ed47392f4b"
|
||||
"@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/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/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/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/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/router@~4.0.0":
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@angular/router/-/router-4.0.3.tgz#24184e9b1266c4ad017b2be81573464b1e4c5dfa"
|
||||
"@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"
|
||||
|
||||
"@ngx-translate/core@^7.1.0":
|
||||
version "7.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@ngx-translate/core/-/core-7.1.0.tgz#5087a65c8ff312e4244ca0646ed45cde83b170cd"
|
||||
"@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-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@'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@^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"
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
parent=base
|
||||
import=login/keycloak
|
||||
deprecatedMode=false
|
||||
Reference in new issue
Block a user