Commit 3bc1986b authored by François Agneray's avatar François Agneray
Browse files

Update Angular10 and integrate keycloak

parent 3c06b5bc
3.4.0
\ No newline at end of file
3.5.0
\ No newline at end of file
FROM node:13-slim
FROM node:14-slim
ENV DEBIAN_FRONTEND=noninteractive
......
......@@ -3,7 +3,7 @@
"compilerOptions": {
"outDir": "../out-tsc/e2e",
"module": "commonjs",
"target": "es5",
"target": "es2018",
"types": [
"jasmine",
"jasminewd2",
......
......@@ -11,52 +11,54 @@
},
"private": true,
"dependencies": {
"@angular/animations": "~9.1.1",
"@angular/common": "~9.1.1",
"@angular/compiler": "~9.1.1",
"@angular/core": "~9.1.1",
"@angular/forms": "~9.1.1",
"@angular/platform-browser": "~9.1.1",
"@angular/platform-browser-dynamic": "~9.1.1",
"@angular/router": "~9.1.1",
"@fortawesome/fontawesome-free": "^5.13.0",
"@ng-select/ng-select": "^4.0.0",
"@ngrx/effects": "^9.1.0",
"@ngrx/entity": "^9.1.0",
"@ngrx/router-store": "^9.1.0",
"@ngrx/store": "^9.1.0",
"@ngrx/store-devtools": "^9.1.0",
"bootstrap": "^4.4.1",
"@angular/animations": "~10.2.2",
"@angular/common": "~10.2.2",
"@angular/compiler": "~10.2.2",
"@angular/core": "~10.2.2",
"@angular/forms": "~10.2.2",
"@angular/platform-browser": "~10.2.2",
"@angular/platform-browser-dynamic": "~10.2.2",
"@angular/router": "~10.2.2",
"@fortawesome/fontawesome-free": "^5.15.1",
"@ng-select/ng-select": "^5.0.8",
"@ngrx/effects": "^10.0.1",
"@ngrx/entity": "^10.0.1",
"@ngrx/router-store": "^10.0.1",
"@ngrx/store": "^10.0.1",
"@ngrx/store-devtools": "^10.0.1",
"bootstrap": "^4.5.3",
"d3": "^5.15.1",
"ng-inline-svg": "^10.1.0",
"ngx-bootstrap": "^5.6.1",
"keycloak-angular": "^8.0.1",
"keycloak-js": "^11.0.3",
"ng-inline-svg": "^11.0.1",
"ngx-bootstrap": "^6.1.0",
"ngx-json-viewer": "^2.4.0",
"ngx-toastr": "^12.0.1",
"rxjs": "~6.5.4",
"tslib": "^1.9.0",
"ngx-toastr": "^13.1.0",
"rxjs": "~6.6.3",
"tslib": "^2.0.0",
"zone.js": "~0.10.3"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.901.1",
"@angular/cli": "~9.1.1",
"@angular/compiler-cli": "~9.1.1",
"@angular/language-service": "~9.1.1",
"@angular-devkit/build-angular": "~0.1002.0",
"@angular/cli": "~10.2.0",
"@angular/compiler-cli": "~10.2.2",
"@angular/language-service": "~10.2.2",
"@types/d3": "^5.7.2",
"@types/jasmine": "~3.3.8",
"@types/jasmine": "~3.6.1",
"@types/jasminewd2": "~2.0.3",
"@types/node": "^12.11.1",
"codelyzer": "^5.0.0",
"codelyzer": "^6.0.1",
"intl": "^1.2.5",
"jasmine-core": "~3.4.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.1.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.0",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tslint": "~5.15.0",
"typescript": "~3.7.5"
"jasmine-core": "~3.5.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~5.0.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage-istanbul-reporter": "~3.0.2",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "^1.5.0",
"protractor": "~7.0.0",
"ts-node": "~9.0.0",
"tslint": "~6.1.0",
"typescript": "~4.0.5"
}
}
import { APP_INITIALIZER } from '@angular/core';
import { from } from 'rxjs';
import { KeycloakService } from 'keycloak-angular';
import { environment } from '../environments/environment';
function initializeKeycloak(keycloak: KeycloakService) {
return async () => {
from(keycloak.keycloakEvents$).subscribe(event => console.log(event))
return keycloak.init({
config: {
url: environment.ssoAuthUrl,
realm: environment.ssoRealm,
clientId: environment.ssoClientId,
},
initOptions: {
onLoad: 'check-sso',
silentCheckSsoRedirectUri:
window.location.origin + '/assets/silent-check-sso.html'
},
loadUserProfileAtStartUp: true
});
}
}
export const initializeKeycloakAnis = {
provide: APP_INITIALIZER,
useFactory: initializeKeycloak,
multi: true,
deps: [ KeycloakService ],
};
\ No newline at end of file
......@@ -7,7 +7,9 @@ import { StoreModule } from '@ngrx/store';
import { StoreRouterConnectingModule, RouterState } from '@ngrx/router-store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { EffectsModule } from '@ngrx/effects';
import { KeycloakAngularModule } from 'keycloak-angular';
import { initializeKeycloakAnis } from './app.keycloak';
import { CustomRouterStateSerializer } from './shared/utils';
import { reducers, metaReducers } from './app.reducer';
import { CoreModule } from './core/core.module';
......@@ -24,6 +26,7 @@ import { environment } from '../environments/environment';
BrowserAnimationsModule,
HttpClientModule,
CoreModule,
KeycloakAngularModule,
StaticModule,
LoginModule,
MetamodelModule,
......@@ -45,6 +48,7 @@ import { environment } from '../environments/environment';
!environment.production ? StoreDevtoolsModule.instrument() : [],
EffectsModule.forRoot([])
],
bootstrap: [AppComponent]
providers: [ initializeKeycloakAnis ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
......@@ -30,7 +30,7 @@
</ul>
<button *ngIf="!isAuthenticated" class="btn btn-outline-success my-2 my-sm-0"
id="button-sign-in"
routerLink="/login">
(click)="emitLogin()">
Sign In / Register
</button>
<span *ngIf="isAuthenticated" id="dropdown-menu" dropdown>
......@@ -45,7 +45,7 @@
<ul id="basic-link-dropdown" *dropdownMenu class="dropdown-menu dropdown-menu-right dropdown-up" role="menu"
aria-labelledby="basic-link">
<li id="li-email" role="menuitem">
<span class="dropdown-item font-italic">{{ loginToken.email }}</span>
<span class="dropdown-item font-italic">Authenticated</span>
</li>
<li class="divider dropdown-divider"></li>
<li role="menuitem">
......@@ -71,7 +71,7 @@
<ul id="basic-link-dropdown" *dropdownMenu class="dropdown-menu dropdown-menu-right dropdown-up" role="menu"
aria-labelledby="basic-link">
<li *ngIf="isAuthenticated" role="menuitem">
<span class="dropdown-item font-italic">{{ loginToken.email }}</span>
<span class="dropdown-item font-italic">Authenticated</span>
</li>
<li *ngIf="isAuthenticated" class="divider dropdown-divider"></li>
<li role="menuitem">
......
......@@ -12,8 +12,8 @@ import { environment } from '../../../environments/environment'
})
export class NavComponent {
@Input() isAuthenticated: boolean;
@Input() loginToken: LoginToken;
@Input() instance: Instance;
@Output() login: EventEmitter<any> = new EventEmitter();
@Output() logout: EventEmitter<any> = new EventEmitter();
baseHref: string = environment.baseHref;
......@@ -38,6 +38,10 @@ export class NavComponent {
return false;
}
emitLogin() {
this.login.emit();
}
emitLogout() {
this.logout.emit();
}
......
<header>
<app-nav
[isAuthenticated]="isAuthenticated | async"
[loginToken]="loginToken | async"
[instance]="instance | async"
(login)="login()"
(logout)="logout()">
</app-nav>
</header>
......
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { Observable, from } from 'rxjs';
import { KeycloakService } from 'keycloak-angular';
import * as fromLogin from '../../login/store/login.reducer';
import * as loginActions from '../../login/store/login.action';
import * as loginSelector from '../../login/store/login.selector';
import { LoginToken } from '../../login/store/model';
import * as fromMetamodel from '../../metamodel/reducers';
import * as instanceActions from '../../metamodel/action/instance.action';
import * as metamodelSelector from '../../metamodel/selectors';
......@@ -14,7 +11,6 @@ import { Instance } from '../../metamodel/model';
import { VERSIONS } from '../../../settings/settings';
interface StoreState {
login: fromLogin.State;
metamodel: fromMetamodel.State;
}
......@@ -28,21 +24,22 @@ export class AppComponent implements OnInit {
public anisClientVersion: string = VERSIONS.anisClient;
public year = (new Date()).getFullYear();
public isAuthenticated: Observable<boolean>;
public loginToken: Observable<LoginToken>;
public instance: Observable<Instance>;
constructor(private store: Store<StoreState>) {
this.isAuthenticated = store.select(loginSelector.isAuthenticated);
this.loginToken = store.select(loginSelector.getLoginToken);
constructor(private store: Store<StoreState>, private keycloak: KeycloakService) {
this.isAuthenticated = from(this.keycloak.isLoggedIn());
this.instance = store.select(metamodelSelector.getInstance);
}
ngOnInit() {
this.store.dispatch(new loginActions.LoginLocalStorageAction());
this.store.dispatch(new instanceActions.LoadInstanceMetaAction());
}
login(): void {
this.keycloak.login();
}
logout(): void {
this.store.dispatch(new loginActions.LogoutAction());
this.keycloak.logout();
}
}
<html>
<body>
<script>
parent.postMessage(location.href, location.origin);
</script>
</body>
</html>
\ No newline at end of file
......@@ -9,5 +9,8 @@ export const environment = {
authUrl: 'http://localhost:8081',
spectraUrl: 'https://cesam.lam.fr/anis-tools/spectra_to_csv/?file=/dataproject/SPECTRA/',
instanceName: 'default',
baseHref: '/'
baseHref: '/',
ssoAuthUrl: 'http://localhost:8180/auth',
ssoRealm: 'anis',
ssoClientId: 'anis-client'
};
......@@ -7,7 +7,7 @@
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"module": "esnext",
"module": "es2020",
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
......
{
"extends": "tslint:recommended",
"rules": {
"align": {
"options": [
"parameters",
"statements"
]
},
"array-type": false,
"arrow-parens": false,
"arrow-return-shorthand": true,
"deprecation": {
"severity": "warn"
},
"component-class-suffix": true,
"contextual-lifecycle": true,
"curly": true,
"directive-class-suffix": true,
"directive-selector": [
true,
......@@ -21,10 +29,17 @@
"app",
"kebab-case"
],
"eofline": true,
"import-blacklist": [
true,
"rxjs/Rx"
],
"import-spacing": true,
"indent": {
"options": [
"spaces"
]
},
"interface-name": false,
"max-classes-per-file": false,
"max-line-length": [
......@@ -60,7 +75,6 @@
"no-non-null-assertion": true,
"no-redundant-jsdoc": true,
"no-switch-case-fall-through": true,
"no-use-before-declare": true,
"no-var-requires": false,
"object-literal-key-quotes": [
true,
......@@ -80,11 +94,60 @@
"no-output-native": true,
"no-output-on-prefix": true,
"no-output-rename": true,
"semicolon": {
"options": [
"always"
]
},
"space-before-function-paren": {
"options": {
"anonymous": "never",
"asyncArrow": "always",
"constructor": "never",
"method": "never",
"named": "never"
}
},
"no-outputs-metadata-property": true,
"template-banana-in-box": true,
"template-no-negated-async": true,
"typedef-whitespace": {
"options": [
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
},
{
"call-signature": "onespace",
"index-signature": "onespace",
"parameter": "onespace",
"property-declaration": "onespace",
"variable-declaration": "onespace"
}
]
},
"use-lifecycle-interface": true,
"use-pipe-transform-interface": true
"use-pipe-transform-interface": true,
"variable-name": {
"options": [
"ban-keywords",
"check-format",
"allow-pascal-case"
]
},
"whitespace": {
"options": [
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type",
"check-typecast"
]
}
},
"rulesDirectory": [
"codelyzer"
......
This diff is collapsed.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment