Improve AppState

This commit is contained in:
William Nolin 2021-12-14 19:28:50 -05:00
parent 07b410d053
commit cb7f38b46b
5 changed files with 24 additions and 50 deletions

View File

@ -48,9 +48,9 @@ export class Login extends ErrorHandlingComponent {
} }
submit() { submit() {
this.subscribeAndNavigate( this.subscribe(
this.accountService.login(this.userIdControl.value, this.passwordControl.value), this.accountService.login(this.userIdControl.value, this.passwordControl.value),
'/color' () => {}
) )
// Does not use SubscribingComponent shortcut because backend doesn't return expected error type // Does not use SubscribingComponent shortcut because backend doesn't return expected error type
// this.accountService.login(this.userIdControl.value, this.passwordControl.value) // this.accountService.login(this.userIdControl.value, this.passwordControl.value)

View File

@ -7,7 +7,6 @@ import {environment} from '../../../../environments/environment'
import {ApiService} from '../../shared/service/api.service' import {ApiService} from '../../shared/service/api.service'
import {Permission} from '../../shared/model/user' import {Permission} from '../../shared/model/user'
import {ErrorService} from '../../shared/service/error.service' import {ErrorService} from '../../shared/service/error.service'
import {globalLoadingWheel} from '../../shared/components/loading-wheel/loading-wheel.component'
import {AlertService} from '../../shared/service/alert.service' import {AlertService} from '../../shared/service/alert.service'
import {JwtService} from "./jwt.service"; import {JwtService} from "./jwt.service";
@ -92,37 +91,7 @@ export class AccountService implements OnDestroy {
const authorization = response.headers.get("Authorization") const authorization = response.headers.get("Authorization")
const jwt = this.jwtService.parseJwt(authorization) const jwt = this.jwtService.parseJwt(authorization)
this.appState.authenticatedUser = jwt.user this.appState.authenticateUser(jwt)
this.appState.authenticationExpiration = jwt.exp
}
loginOld(id: number, password: string, success: () => void) {
const loginForm = {id, password}
globalLoadingWheel.show()
this.http.post<any>(`${environment.apiUrl}/login`, loginForm, {
withCredentials: true,
observe: 'response' as 'body'
})
.pipe(
take(1),
takeUntil(this.destroy$)
)
.subscribe({
next: (response: HttpResponse<any>) => {
this.appState.authenticationExpiration = parseInt(response.headers.get('X-Authentication-Expiration'))
this.appState.isAuthenticated = true
this.setLoggedInUserFromApi()
success()
},
error: err => {
globalLoadingWheel.hide()
if (err.status === 401 || err.status === 403) {
this.alertService.pushError('Les identifiants entrés sont invalides')
} else {
this.errorService.handleError(err)
}
}
})
} }
logout(success: () => void) { logout(success: () => void) {

View File

@ -1,7 +1,7 @@
import {Injectable} from "@angular/core"; import {Injectable} from "@angular/core";
import {User} from "../../shared/model/user";
import jwtDecode from "jwt-decode"; import jwtDecode from "jwt-decode";
import {parseJson} from "@angular/cli/utilities/json-file"; import {parseJson} from "@angular/cli/utilities/json-file";
import {CreJwt} from "../../shared/app-state";
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -17,9 +17,3 @@ export class JwtService {
} }
} }
} }
interface CreJwt {
readonly sub: string
readonly exp: number,
readonly user: User
}

View File

@ -20,6 +20,12 @@ export class AppState {
) { ) {
} }
authenticateUser(jwt: CreJwt) {
this.authenticatedUser = jwt.user
this.authenticationExpiration = jwt.exp
this.isAuthenticated = true
}
resetAuthenticatedUser() { resetAuthenticatedUser() {
this.isAuthenticated = false this.isAuthenticated = false
this.authenticationExpiration = -1 this.authenticationExpiration = -1
@ -37,7 +43,7 @@ export class AppState {
return sessionStorage.getItem(this.KEY_AUTHENTICATED) === 'true' return sessionStorage.getItem(this.KEY_AUTHENTICATED) === 'true'
} }
set isAuthenticated(value: boolean) { private set isAuthenticated(value: boolean) {
sessionStorage.setItem(this.KEY_AUTHENTICATED, value.toString()) sessionStorage.setItem(this.KEY_AUTHENTICATED, value.toString())
this.authenticatedUser$.next({ this.authenticatedUser$.next({
authenticated: value, authenticated: value,
@ -49,7 +55,8 @@ export class AppState {
return parseInt(sessionStorage.getItem(this.KEY_AUTHENTICATION_EXPIRATION)) return parseInt(sessionStorage.getItem(this.KEY_AUTHENTICATION_EXPIRATION))
} }
set authenticationExpiration(value: number) { private set authenticationExpiration(value: number) {
console.error(value)
sessionStorage.setItem(this.KEY_AUTHENTICATION_EXPIRATION, value.toString()) sessionStorage.setItem(this.KEY_AUTHENTICATION_EXPIRATION, value.toString())
} }
@ -58,12 +65,10 @@ export class AppState {
return userString ? JSON.parse(userString) : null return userString ? JSON.parse(userString) : null
} }
set authenticatedUser(value: User) { private set authenticatedUser(value: User) {
if (value === null) { if (value === null) {
console.log(1) // sessionStorage.removeItem(this.KEY_LOGGED_IN_USER)
sessionStorage.removeItem(this.KEY_LOGGED_IN_USER)
} else { } else {
console.log(2)
sessionStorage.setItem(this.KEY_LOGGED_IN_USER, JSON.stringify(value)) sessionStorage.setItem(this.KEY_LOGGED_IN_USER, JSON.stringify(value))
} }
this.authenticatedUser$.next({ this.authenticatedUser$.next({
@ -76,3 +81,9 @@ export class AppState {
this.titleService.setTitle(`CRE: ${value}`) this.titleService.setTitle(`CRE: ${value}`)
} }
} }
export interface CreJwt {
readonly sub: string
readonly exp: number,
readonly user: User
}

View File

@ -4,10 +4,9 @@ import {Observable, Subject} from 'rxjs'
import {environment} from '../../../../environments/environment' import {environment} from '../../../../environments/environment'
import {AppState} from '../app-state' import {AppState} from '../app-state'
import {Router} from '@angular/router' import {Router} from '@angular/router'
import {map, share, takeUntil, tap} from 'rxjs/operators' import {map, share, takeUntil} from 'rxjs/operators'
import {valueOr} from '../utils/utils' import {valueOr} from '../utils/utils'
import {ErrorService} from './error.service' import {ErrorService} from './error.service'
import {globalLoadingWheel} from '../components/loading-wheel/loading-wheel.component'
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -78,7 +77,7 @@ export class ApiService implements OnDestroy {
console.error('httpOptions need to be specified to use credentials in HTTP methods.') console.error('httpOptions need to be specified to use credentials in HTTP methods.')
} }
} else { } else {
this.appState.resetAuthenticatedUser() // this.appState.resetAuthenticatedUser()
this.navigateToLogin() this.navigateToLogin()
} }
} }
@ -91,6 +90,7 @@ export class ApiService implements OnDestroy {
} }
private checkAuthenticated(): boolean { private checkAuthenticated(): boolean {
console.log(Date.now() / 1000, this.appState.authenticationExpiration)
return (this.appState.isAuthenticated && Date.now() <= this.appState.authenticationExpiration) || return (this.appState.isAuthenticated && Date.now() <= this.appState.authenticationExpiration) ||
(this.appState.authenticatedUser && this.appState.authenticatedUser.group != null) (this.appState.authenticatedUser && this.appState.authenticatedUser.group != null)
} }