From 77497a642d39b58c4a9772f22ca70937426370f8 Mon Sep 17 00:00:00 2001 From: Eneko Nieto Date: Sat, 13 Feb 2021 00:37:10 +0100 Subject: [PATCH] Overlay until log status received --- src/app/app.component.css | 24 ++++++++ src/app/app.component.html | 11 ++-- src/app/app.component.ts | 36 ++++-------- src/app/pages/home/home.component.html | 11 +++- src/app/pages/home/home.component.ts | 28 ++++----- src/app/services/api.service.ts | 33 +++++++++-- src/app/services/auth.service.ts | 67 +++++++++++++++++++++- src/app/views/header/header.component.html | 2 +- src/app/views/header/header.component.ts | 48 ++++------------ src/app/views/list/list.component.ts | 2 +- src/app/views/list/list.datasource.ts | 4 +- src/flags.ts | 5 +- 12 files changed, 172 insertions(+), 99 deletions(-) diff --git a/src/app/app.component.css b/src/app/app.component.css index e69de29..178b186 100644 --- a/src/app/app.component.css +++ b/src/app/app.component.css @@ -0,0 +1,24 @@ +.overlay { + position: fixed; + background-color: firebrick; + left: 0; + right: 0; + top: 0; + bottom: 0; + text-align: center; +} + +.logo { + width: 50%; + padding-top: 100px; +} + +.spinner-container { + height: 360px; + width: 390px; + margin: auto; +} + +.spinner-container mat-spinner { + margin: 130px auto 0 auto; +} diff --git a/src/app/app.component.html b/src/app/app.component.html index 6aa0064..d9d3a7f 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -4,8 +4,11 @@
- -
- -
+ +
+ +
+ +
+
\ No newline at end of file diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 12f8df2..7744258 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,35 +1,21 @@ -import { Component } from '@angular/core'; -import { OAuthService, NullValidationHandler } from 'angular-oauth2-oidc'; -import { Router } from '@angular/router'; -import { filter } from 'rxjs/operators'; -import { authConfig } from './auth.config'; -import { useHash } from '../flags'; +import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import { AuthService } from './services/auth.service'; @Component({ // tslint:disable-next-line:component-selector selector: 'app-root', templateUrl: './app.component.html', + styleUrls: ['./app.component.css'], }) -export class AppComponent { - constructor(private router: Router, private oauthService: OAuthService) { - this.configureCodeFlow(); +export class AppComponent implements OnInit { + showOverlay = true; - // Automatically load user profile - this.oauthService.events - .pipe(filter((e) => e.type === 'token_received')) - .subscribe((_) => { - console.log('state', this.oauthService.state); - this.oauthService.loadUserProfile(); - }); - } + constructor( + private authService: AuthService + ) { } - private configureCodeFlow(): void { - this.oauthService.configure(authConfig); - this.oauthService.loadDiscoveryDocumentAndTryLogin().then((_) => { - if (useHash) { - this.router.navigate(['/']); - } - }); - this.oauthService.setupAutomaticSilentRefresh(); + async ngOnInit(): Promise { + await this.authService.isLogged; + this.showOverlay = false; } } diff --git a/src/app/pages/home/home.component.html b/src/app/pages/home/home.component.html index addcf92..1b0a494 100644 --- a/src/app/pages/home/home.component.html +++ b/src/app/pages/home/home.component.html @@ -1,10 +1,15 @@ - + My travels - + + - Logueate para ver tus viajes + + + Logueate para ver tus viajes + diff --git a/src/app/pages/home/home.component.ts b/src/app/pages/home/home.component.ts index 62da92b..5fd82b4 100644 --- a/src/app/pages/home/home.component.ts +++ b/src/app/pages/home/home.component.ts @@ -1,8 +1,8 @@ import { Component, OnInit } from '@angular/core'; -import { OAuthService } from 'angular-oauth2-oidc'; -import { ActivatedRoute, Router } from '@angular/router'; -import { ApiService } from '../../services/api.service'; +import { Router } from '@angular/router'; +import { AuthService } from 'src/app/services/auth.service'; import { Travel } from '../../entities/travel'; +import { ApiService } from '../../services/api.service'; @Component({ templateUrl: './home.component.html', @@ -26,16 +26,16 @@ export class HomeComponent implements OnInit { myTravelsApiCall = this.apiService.getMyTravels; constructor( - private route: ActivatedRoute, + // private route: ActivatedRoute, private router: Router, - private oauthService: OAuthService, + private authService: AuthService, private apiService: ApiService - ) {} + ) { } ngOnInit(): void { - this.route.params.subscribe((p) => { - this.login = p['login']; - }); + // this.route.params.subscribe((p) => { + // this.login = p['login']; + // }); } newTravel(): void { @@ -47,12 +47,8 @@ export class HomeComponent implements OnInit { this.router.navigateByUrl('/travel/' + travel.id); } - loadUserProfile(): void { - this.oauthService.loadUserProfile().then((userProfile) => (this.userProfile = userProfile)); - } - - get logged(): boolean { - return this.oauthService.getIdentityClaims() != null; - // return this.oauthService.hasValidIdToken() && this.oauthService.hasValidAccessToken(); + get isLogged(): Promise { + return this.authService.isLogged; + // return this.authService.isLogged(); } } diff --git a/src/app/services/api.service.ts b/src/app/services/api.service.ts index 54d6e4d..e61d89e 100644 --- a/src/app/services/api.service.ts +++ b/src/app/services/api.service.ts @@ -7,6 +7,7 @@ import { Travel, TravelId } from '../entities/travel'; import { PUBLIC_API_URL, TRAVEL_API_URL, USER_API_URL } from '../app.config'; import { ListDto } from '../entities/list-dto'; import { User } from '../entities/user'; +import { AuthService } from './auth.service'; export type ApiCall = (params?: { [param: string]: any }) => (Observable>>); @@ -14,7 +15,10 @@ export type ApiCall = (params?: { [param: string]: any }) => (Observable>(url, { params }); return response$.pipe( - retry(0), // retry a failed request up to 3 times - catchError(this.handleError) // then handle the error - ); + retry(0), // retry a failed request up to 3 times + catchError(this.handleError) // then handle the error + ); } + // private callProtectedApi( + // url: string, + // params?: { [param: string]: any }, + // body?: any + // ): Observable> { + // const observable = new Observable>(observer => { + // this.authService.configurePromise.then(logged => { + // if (logged) { + // this.callApi(url, params, body).subscribe(res => { + // observer.next(res); + // }); + // } + // else { + // console.error('callProtectedApi: NOT LOGGED'); + // observer.error('NOT LOGGED'); + // } + // }); + // }); + // return observable; + // } + private handleError(error: HttpErrorResponse): Observable { if (error.error instanceof ErrorEvent) { // A client-side or network error occurred. Handle it accordingly. diff --git a/src/app/services/auth.service.ts b/src/app/services/auth.service.ts index be8d431..dae3189 100644 --- a/src/app/services/auth.service.ts +++ b/src/app/services/auth.service.ts @@ -1,5 +1,6 @@ import { Injectable } from '@angular/core'; import { OAuthService } from 'angular-oauth2-oidc'; +import { authConfig } from '../auth.config'; import { Travel } from '../entities/travel'; import { User } from '../entities/user'; @@ -7,8 +8,26 @@ import { User } from '../entities/user'; providedIn: 'root' }) export class AuthService { + private configurePromise = null; - constructor(private oauthService: OAuthService) { } + constructor( + private oauthService: OAuthService + ) { } + + get isLogged(): Promise { + if (this.configurePromise == null) { + this.configurePromise = this.configureAndTryLogin(); + } + return this.configurePromise; + } + + login(): void { + this.oauthService.initLoginFlow(); + } + + logout(): void { + this.oauthService.revokeTokenAndLogout(); + } currentUser(): User { const claims = this.oauthService.getIdentityClaims(); @@ -16,6 +35,9 @@ export class AuthService { } canEditTravel(travel: Travel): boolean { + if (travel == null) { + return false; + } const user = this.currentUser(); if (user == null) { return false; @@ -23,4 +45,47 @@ export class AuthService { return user.admin || (user.id === travel.driverInfo.id); } + + private async configureAndTryLogin(): Promise { + this.oauthService.configure(authConfig); + this.oauthService.setupAutomaticSilentRefresh(); + + return new Promise((resolve) => { + this.oauthService.loadDiscoveryDocumentAndTryLogin().then((_) => { + if (this.oauthService.getIdentityClaims() != null) { + if (this.oauthService.hasValidIdToken() && this.oauthService.hasValidAccessToken()) { + console.log('NO NEED FOR TOKEN REFRESH'); + resolve(true); + } + else { + this.oauthService.refreshToken().then(() => { + console.log('TOKEN REFRESHED'); + resolve(true); + }).catch(e => { + console.error('ERROR REFRESHING TOKEN'); + console.error(e); + resolve(false); + }); + } + } + else { + console.error('NOT LOGGED!'); + resolve(false); + } + }); + }); + + // Automatically load user profile + // this.oauthService.events + // .pipe(filter((e) => e.type === 'token_received')) + // .subscribe((_) => { + // console.log('state', this.oauthService.state); + // this.oauthService.loadUserProfile(); + + // this.apiService.getUser().subscribe(user => { + // console.log('USER'); + // console.log(user); + // }); + // }); + } } diff --git a/src/app/views/header/header.component.html b/src/app/views/header/header.component.html index 46d456a..4aac0ce 100644 --- a/src/app/views/header/header.component.html +++ b/src/app/views/header/header.component.html @@ -3,7 +3,7 @@ -
+
{{ name }} diff --git a/src/app/views/header/header.component.ts b/src/app/views/header/header.component.ts index b566545..2d38ff3 100644 --- a/src/app/views/header/header.component.ts +++ b/src/app/views/header/header.component.ts @@ -1,57 +1,29 @@ -import { Component, OnInit } from '@angular/core'; -import { OAuthService } from 'angular-oauth2-oidc'; -import { ApiService } from 'src/app/services/api.service'; -import { authConfig } from '../../auth.config'; +import { Component } from '@angular/core'; +import { AuthService } from 'src/app/services/auth.service'; @Component({ selector: 'app-header', templateUrl: './header.component.html', styleUrls: ['./header.component.css'], }) -export class HeaderComponent implements OnInit { +export class HeaderComponent { constructor( - private oauthService: OAuthService, - private apiService: ApiService + private authService: AuthService ) { } - ngOnInit(): void { - console.log('INIT logged=' + String(this.logged)); - this.oauthService.configure(authConfig); - this.oauthService.loadDiscoveryDocumentAndTryLogin().then(success => { - console.log('Autologin success=' + success + ' logged=' + String(this.logged)); - console.log('USER autologin'); - if (this.logged) { - this.apiService.getUser().subscribe(user => { - console.log(user); - }); - } - }); - } - async login(): Promise { - this.oauthService.loadDiscoveryDocumentAndLogin().then(success => { - console.log('USER login'); - if (this.logged) { - this.apiService.getUser().subscribe(user => { - console.log(user); - }); - } - }); + this.authService.login(); } logout(): void { - this.oauthService.revokeTokenAndLogout(); + this.authService.logout(); } - get logged(): boolean { - return this.oauthService.getIdentityClaims() != null; + get isLogged(): Promise { + return this.authService.isLogged; } - get name(): any { - const claims = this.oauthService.getIdentityClaims(); - if (!claims) { - return null; - } - return claims['name']; + get name(): string { + return this.authService.currentUser()?.name; } } diff --git a/src/app/views/list/list.component.ts b/src/app/views/list/list.component.ts index bce4c3b..cdfa34e 100644 --- a/src/app/views/list/list.component.ts +++ b/src/app/views/list/list.component.ts @@ -19,7 +19,7 @@ import { ListDataSource } from './list.datasource'; @Component({ selector: 'app-list', templateUrl: './list.component.html', - styleUrls: ['./list.component.css'], + styleUrls: ['./list.component.css'] }) export class ListComponent implements OnInit, AfterViewInit { dataSource: ListDataSource; diff --git a/src/app/views/list/list.datasource.ts b/src/app/views/list/list.datasource.ts index 60a85dc..d77689c 100644 --- a/src/app/views/list/list.datasource.ts +++ b/src/app/views/list/list.datasource.ts @@ -1,9 +1,9 @@ import { CollectionViewer, DataSource } from '@angular/cdk/collections'; -import { Observable, BehaviorSubject, of, throwError } from 'rxjs'; +import { BehaviorSubject, Observable, throwError } from 'rxjs'; import { catchError, finalize } from 'rxjs/operators'; import { ApiResponse } from '../../entities/api-response'; import { ListDto } from '../../entities/list-dto'; -import { ApiCall, ApiService } from '../../services/api.service'; +import { ApiCall } from '../../services/api.service'; export class ListDataSource implements DataSource { private listSubject = new BehaviorSubject([]); diff --git a/src/flags.ts b/src/flags.ts index dad065f..c3c9f5d 100644 --- a/src/flags.ts +++ b/src/flags.ts @@ -1,6 +1,3 @@ -// Use HashLocationStrategy for routing? -export const useHash = false; - // Set this to true, to use silent refresh; otherwise the example // uses the refresh_token via an AJAX coll to get new tokens. -export const useSilentRefreshForCodeFlow = false; +export const useSilentRefreshForCodeFlow = true;