aboutsummaryrefslogtreecommitdiff
path: root/Timeline/ClientApp/src/app/user
diff options
context:
space:
mode:
Diffstat (limited to 'Timeline/ClientApp/src/app/user')
-rw-r--r--Timeline/ClientApp/src/app/user/internal-user-service/internal-user.service.ts81
-rw-r--r--Timeline/ClientApp/src/app/user/user.module.ts4
2 files changed, 52 insertions, 33 deletions
diff --git a/Timeline/ClientApp/src/app/user/internal-user-service/internal-user.service.ts b/Timeline/ClientApp/src/app/user/internal-user-service/internal-user.service.ts
index 4767bd16..604393f4 100644
--- a/Timeline/ClientApp/src/app/user/internal-user-service/internal-user.service.ts
+++ b/Timeline/ClientApp/src/app/user/internal-user-service/internal-user.service.ts
@@ -2,10 +2,8 @@ import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Router } from '@angular/router';
-import { Observable, of, throwError, BehaviorSubject } from 'rxjs';
-import { map, catchError, retry } from 'rxjs/operators';
-
-import { nullIfUndefined } from '../../utilities/language-untilities';
+import { Observable, throwError, BehaviorSubject, of } from 'rxjs';
+import { map, catchError, retry, switchMap, tap } from 'rxjs/operators';
import { AlreadyLoginError, BadCredentialsError, BadNetworkError, UnknownError } from './errors';
import {
@@ -13,10 +11,9 @@ import {
CreateTokenResponse, ValidateTokenRequest, ValidateTokenResponse
} from './http-entities';
import { UserCredentials, UserInfo } from '../entities';
+import { MatSnackBar } from '@angular/material';
-export type UserLoginState = 'nologin' | 'invalidlogin' | 'success';
-
/**
* This service is only used internal in user module.
*/
@@ -36,41 +33,60 @@ export class InternalUserService {
return this.userInfoSubject;
}
- constructor(private httpClient: HttpClient, private router: Router) { }
+ constructor(private httpClient: HttpClient, private router: Router, private snackBar: MatSnackBar) {
+ const savedToken = window.localStorage.getItem('token');
+ if (savedToken === null) {
+ setTimeout(() => snackBar.open('No login before!', 'ok', { duration: 2000 }), 0);
+ } else {
+ this.validateToken(savedToken).subscribe(result => {
+ if (result === null) {
+ window.localStorage.removeItem('token');
+ setTimeout(() => snackBar.open('Last login is no longer invalid!', 'ok', { duration: 2000 }), 0);
+ } else {
+ this.token = savedToken;
+ this.userInfoSubject.next(result);
+ setTimeout(() => snackBar.open('You have login already!', 'ok', { duration: 2000 }), 0);
+ }
+ }, _ => {
+ setTimeout(() => snackBar.open('Failed to check last login', 'ok', { duration: 2000 }), 0);
+ });
+ }
- userRouteNavigate(commands: any[] | null) {
- this.router.navigate([{
- outlets: {
- user: commands
- }
- }]);
}
- refreshAndGetUserState(): Observable<UserLoginState> {
- if (this.token === undefined || this.token === null) {
- return of(<UserLoginState>'nologin');
- }
-
- return this.httpClient.post<ValidateTokenResponse>(validateTokenUrl, <ValidateTokenRequest>{ token: this.token }).pipe(
+ private validateToken(token: string): Observable<UserInfo | null> {
+ return this.httpClient.post<ValidateTokenResponse>(validateTokenUrl, <ValidateTokenRequest>{ token: token }).pipe(
retry(3),
- catchError(error => {
- console.error('Failed to validate token.');
- return throwError(error);
- }),
- map(result => {
+ switchMap(result => {
if (result.isValid) {
- this.userInfoSubject.next(nullIfUndefined(result.userInfo));
- return <UserLoginState>'success';
+ const { userInfo } = result;
+ if (userInfo) {
+ return of(userInfo);
+ } else {
+ return throwError(new Error('Wrong server response. IsValid is true but UserInfo is null.'));
+ }
} else {
- this.token = null;
- this.userInfoSubject.next(null);
- return <UserLoginState>'invalidlogin';
+ return of(null);
}
- })
+ }),
+ tap({
+ error: error => {
+ console.error('Failed to validate token.');
+ console.error(error);
+ }
+ }),
);
}
- tryLogin(credentials: UserCredentials): Observable<UserInfo> {
+ userRouteNavigate(commands: any[] | null) {
+ this.router.navigate([{
+ outlets: {
+ user: commands
+ }
+ }]);
+ }
+
+ tryLogin(credentials: UserCredentials, options: { remember: boolean } = { remember: true }): Observable<UserInfo> {
if (this.token) {
return throwError(new AlreadyLoginError());
}
@@ -90,6 +106,9 @@ export class InternalUserService {
}),
map(result => {
this.token = result.token;
+ if (options.remember) {
+ window.localStorage.setItem('token', result.token);
+ }
this.userInfoSubject.next(result.userInfo);
return result.userInfo;
})
diff --git a/Timeline/ClientApp/src/app/user/user.module.ts b/Timeline/ClientApp/src/app/user/user.module.ts
index 8f3b9a9c..7645d61d 100644
--- a/Timeline/ClientApp/src/app/user/user.module.ts
+++ b/Timeline/ClientApp/src/app/user/user.module.ts
@@ -6,7 +6,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterModule } from '@angular/router';
import {
MatFormFieldModule, MatProgressSpinnerModule,
- MatDialogModule, MatInputModule, MatButtonModule
+ MatDialogModule, MatInputModule, MatButtonModule, MatSnackBarModule
} from '@angular/material';
import { RequireNoLoginGuard, RequireLoginGuard } from './auth.guard';
@@ -25,7 +25,7 @@ import { UtilityModule } from '../utilities/utility.module';
{ path: '**', component: RedirectComponent, outlet: 'user' }
]),
CommonModule, HttpClientModule, ReactiveFormsModule, BrowserAnimationsModule,
- MatFormFieldModule, MatProgressSpinnerModule, MatDialogModule, MatInputModule, MatButtonModule,
+ MatFormFieldModule, MatProgressSpinnerModule, MatDialogModule, MatInputModule, MatButtonModule, MatSnackBarModule,
UtilityModule
],
exports: [RouterModule],