Fixed jwt handling

This commit is contained in:
Sven Heidemann 2023-03-20 16:30:07 +01:00
parent ba1f4ee955
commit fdc9a118c8
6 changed files with 126 additions and 134 deletions

View File

@ -1,18 +1,19 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from "@angular/core";
import { Router } from '@angular/router'; import { Router } from "@angular/router";
import { LangChangeEvent, TranslateService } from '@ngx-translate/core'; import { LangChangeEvent, TranslateService } from "@ngx-translate/core";
import { MenuItem, PrimeNGConfig } from 'primeng/api'; import { MenuItem, PrimeNGConfig } from "primeng/api";
import { catchError } from 'rxjs/operators'; import { catchError } from "rxjs/operators";
import { AuthService } from 'src/app/services/auth/auth.service'; import { AuthService } from "src/app/services/auth/auth.service";
import { SettingsService } from 'src/app/services/settings/settings.service'; import { SettingsService } from "src/app/services/settings/settings.service";
import { SpinnerService } from 'src/app/services/spinner/spinner.service'; import { SpinnerService } from "src/app/services/spinner/spinner.service";
import { ThemeService } from 'src/app/services/theme/theme.service'; import { ThemeService } from "src/app/services/theme/theme.service";
import { throwError } from "rxjs"; import { throwError } from "rxjs";
import { SidebarService } from "../../services/sidebar/sidebar.service";
@Component({ @Component({
selector: 'app-header', selector: "app-header",
templateUrl: './header.component.html', templateUrl: "./header.component.html",
styleUrls: ['./header.component.scss'] styleUrls: ["./header.component.scss"]
}) })
export class HeaderComponent implements OnInit { export class HeaderComponent implements OnInit {
langList: MenuItem[] = []; langList: MenuItem[] = [];
@ -26,8 +27,10 @@ export class HeaderComponent implements OnInit {
private spinnerService: SpinnerService, private spinnerService: SpinnerService,
private settings: SettingsService, private settings: SettingsService,
private translateService: TranslateService, private translateService: TranslateService,
private config: PrimeNGConfig private config: PrimeNGConfig,
) { } private sidebarService: SidebarService,
) {
}
ngOnInit(): void { ngOnInit(): void {
this.initMenuLists(); this.initMenuLists();
@ -38,9 +41,12 @@ export class HeaderComponent implements OnInit {
} }
initUserMenuList(): void { initUserMenuList(): void {
if (!this.authService.isLoggedIn$.value) {
return;
}
this.spinnerService.showSpinner(); this.spinnerService.showSpinner();
const mail = this.authService.getEMailFromDecodedToken(this.authService.getDecodedToken()); const mail = this.authService.getEMailFromDecodedToken(this.authService.getDecodedToken());
this.authService.getUserByEMail(mail ?? '') this.authService.getUserByEMail(mail ?? "")
.pipe(catchError(error => { .pipe(catchError(error => {
this.spinnerService.hideSpinner(); this.spinnerService.hideSpinner();
this.authService.logout(); this.authService.logout();
@ -48,7 +54,7 @@ export class HeaderComponent implements OnInit {
})) }))
.subscribe(user => { .subscribe(user => {
this.spinnerService.hideSpinner(); this.spinnerService.hideSpinner();
this.sidebarService.setMenu(true);
this.userMenuList = [ this.userMenuList = [
{ {
@ -59,22 +65,22 @@ export class HeaderComponent implements OnInit {
separator: true separator: true
}, },
{ {
label: this.translateService.instant('header.change_password'), command: () => { label: this.translateService.instant("header.change_password"), command: () => {
this.changePassword(); this.changePassword();
}, },
icon: 'pi pi-key' icon: "pi pi-key"
}, },
{ {
label: this.translateService.instant('header.settings'), command: () => { label: this.translateService.instant("header.settings"), command: () => {
this.userSettings(); this.userSettings();
}, },
icon: 'pi pi-cog' icon: "pi pi-cog"
}, },
{ {
label: this.translateService.instant('header.logout'), command: () => { label: this.translateService.instant("header.logout"), command: () => {
this.logout(); this.logout();
}, },
icon: 'pi pi-sign-out' icon: "pi pi-sign-out"
} }
]; ];
}); });
@ -83,17 +89,17 @@ export class HeaderComponent implements OnInit {
initMenuLists(): void { initMenuLists(): void {
this.langList = [ this.langList = [
{ {
label: 'English', command: () => { label: "English", command: () => {
this.translate('en'); this.translate("en");
this.setLang('en'); this.setLang("en");
}, }
}, },
{ {
label: 'Deutsch', command: () => { label: "Deutsch", command: () => {
this.translate('de'); this.translate("de");
this.setLang('de'); this.setLang("de");
}, }
}, }
]; ];
this.initUserMenuList(); this.initUserMenuList();
@ -117,11 +123,11 @@ export class HeaderComponent implements OnInit {
} }
changePassword(): void { changePassword(): void {
this.router.navigate(['/change-password']); this.router.navigate(["/change-password"]);
} }
userSettings(): void { userSettings(): void {
this.router.navigate(['/user-settings']); this.router.navigate(["/user-settings"]);
} }
logout(): void { logout(): void {
@ -130,7 +136,7 @@ export class HeaderComponent implements OnInit {
translate(lang: string) { translate(lang: string) {
this.translateService.use(lang); this.translateService.use(lang);
this.translateService.get('primeng').subscribe(res => this.config.setTranslation(res)); this.translateService.get("primeng").subscribe(res => this.config.setTranslation(res));
} }
loadLang(): void { loadLang(): void {
@ -138,28 +144,26 @@ export class HeaderComponent implements OnInit {
const mail = this.authService.getEMailFromDecodedToken(token); const mail = this.authService.getEMailFromDecodedToken(token);
if (!mail) { if (!mail) {
this.translate('en'); this.translate("en");
return; return;
} }
let lang = localStorage.getItem(`${mail}_lang`); let lang = localStorage.getItem(`${mail}_lang`);
if (!lang) { if (!lang) {
lang = 'en'; lang = "en";
this.setLang(lang); this.setLang(lang);
} }
this.translate(lang); this.translate(lang);
} }
setLang(lang: string): void { setLang(lang: string): void {
this.authService.isUserLoggedInAsync().then(result => { if (!this.authService.isLoggedIn$.value) {
if (!result) {
return; return;
} }
const token = this.authService.getDecodedToken(); const token = this.authService.getDecodedToken();
const mail = this.authService.getEMailFromDecodedToken(token); const mail = this.authService.getEMailFromDecodedToken(token);
localStorage.setItem(`${mail}_lang`, lang); localStorage.setItem(`${mail}_lang`, lang);
});
} }
} }

View File

@ -1,18 +1,18 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from "@angular/core";
import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from "@angular/forms";
import { ActivatedRoute, Router } from '@angular/router'; import { ActivatedRoute, Router } from "@angular/router";
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from "@ngx-translate/core";
import { catchError } from 'rxjs/operators'; import { catchError } from "rxjs/operators";
import { ResetPasswordDTO } from 'src/app/models/auth/reset-password.dto'; import { ResetPasswordDTO } from "src/app/models/auth/reset-password.dto";
import { AuthService } from 'src/app/services/auth/auth.service'; import { AuthService } from "src/app/services/auth/auth.service";
import { SpinnerService } from 'src/app/services/spinner/spinner.service'; import { SpinnerService } from "src/app/services/spinner/spinner.service";
import { ToastService } from 'src/app/services/toast/toast.service'; import { ToastService } from "src/app/services/toast/toast.service";
import { throwError } from "rxjs"; import { throwError } from "rxjs";
@Component({ @Component({
selector: 'app-forget-password', selector: "app-forget-password",
templateUrl: './forget-password.component.html', templateUrl: "./forget-password.component.html",
styleUrls: ['./forget-password.component.scss'] styleUrls: ["./forget-password.component.scss"]
}) })
export class ForgetPasswordComponent implements OnInit { export class ForgetPasswordComponent implements OnInit {
@ -35,19 +35,18 @@ export class ForgetPasswordComponent implements OnInit {
private route: ActivatedRoute, private route: ActivatedRoute,
private toastService: ToastService, private toastService: ToastService,
private translate: TranslateService private translate: TranslateService
) { } ) {
}
ngOnInit(): void { ngOnInit(): void {
this.spinnerService.showSpinner(); this.spinnerService.showSpinner();
this.authService.isUserLoggedInAsync().then(result => { if (!this.authService.isLoggedIn$.value) {
if (result) { this.router.navigate(["/dashboard"]);
this.router.navigate(['/dashboard']);
} }
this.initForms(); this.initForms();
this.checkResetPasswordId(); this.checkResetPasswordId();
this.spinnerService.hideSpinner(); this.spinnerService.hideSpinner();
});
} }
initForms(): void { initForms(): void {
@ -62,11 +61,11 @@ export class ForgetPasswordComponent implements OnInit {
} }
login(): void { login(): void {
this.router.navigate(['/auth/login']); this.router.navigate(["/auth/login"]);
} }
register(): void { register(): void {
this.router.navigate(['/auth/register']); this.router.navigate(["/auth/register"]);
} }
forgotPassword(): void { forgotPassword(): void {
@ -84,33 +83,35 @@ export class ForgetPasswordComponent implements OnInit {
})).subscribe(res => { })).subscribe(res => {
this.spinnerService.hideSpinner(); this.spinnerService.hideSpinner();
this.ready = true; this.ready = true;
setTimeout(() => { this.router.navigate(['/dashboard']); }, 5000); setTimeout(() => {
this.router.navigate(["/dashboard"]);
}, 5000);
}); });
} }
checkResetPasswordId(): void { checkResetPasswordId(): void {
const id = this.route.snapshot.params['id']; const id = this.route.snapshot.params["id"];
if (id) { if (id) {
this.resetPasswordId = id; this.resetPasswordId = id;
this.spinnerService.showSpinner(); this.spinnerService.showSpinner();
this.authService.getEMailFromforgotPasswordId(id) this.authService.getEMailFromforgotPasswordId(id)
.pipe(catchError(error => { .pipe(catchError(error => {
this.spinnerService.hideSpinner(); this.spinnerService.hideSpinner();
this.router.navigate(['/auth/forgot-password']); this.router.navigate(["/auth/forgot-password"]);
return throwError(() => error); return throwError(() => error);
})).subscribe(email => { })).subscribe(email => {
this.spinnerService.hideSpinner(); this.spinnerService.hideSpinner();
if (email) { if (email) {
this.emailForm.value.email = email; this.emailForm.value.email = email;
} else { } else {
this.router.navigate(['/auth/forgot-password']); this.router.navigate(["/auth/forgot-password"]);
} }
}); });
} }
} }
resetPassword(): void { resetPassword(): void {
const id = this.route.snapshot.params['id']; const id = this.route.snapshot.params["id"];
if (this.emailForm.value.password !== this.emailForm.value.passwordRepeat) { if (this.emailForm.value.password !== this.emailForm.value.passwordRepeat) {
this.repeatErrors.password = true; this.repeatErrors.password = true;
return; return;
@ -124,14 +125,14 @@ export class ForgetPasswordComponent implements OnInit {
this.authService.resetPassword(resetPasswordDTO) this.authService.resetPassword(resetPasswordDTO)
.pipe(catchError(error => { .pipe(catchError(error => {
this.router.navigate(['/auth/login']); this.router.navigate(["/auth/login"]);
this.spinnerService.hideSpinner(); this.spinnerService.hideSpinner();
return throwError(() => error); return throwError(() => error);
})) }))
.subscribe(resp => { .subscribe(resp => {
this.spinnerService.hideSpinner(); this.spinnerService.hideSpinner();
this.toastService.success(this.translate.instant('auth.forgot_password.message.reset_password'), this.translate.instant('auth.forgot_password.message.reset_password_d')); this.toastService.success(this.translate.instant("auth.forgot_password.message.reset_password"), this.translate.instant("auth.forgot_password.message.reset_password_d"));
this.router.navigate(['/auth/login']); this.router.navigate(["/auth/login"]);
}); });
} }
} }

View File

@ -48,8 +48,7 @@ export class LoginComponent implements OnInit {
ngOnInit(): void { ngOnInit(): void {
this.initLoginForm(); this.initLoginForm();
this.spinnerService.showSpinner(); this.spinnerService.showSpinner();
this.authService.isUserLoggedInAsync().then(result => { if (this.authService.isLoggedIn$.value) {
if (result) {
this.router.navigate(["/dashboard"]); this.router.navigate(["/dashboard"]);
return; return;
} }
@ -57,7 +56,6 @@ export class LoginComponent implements OnInit {
this.checkDiscordLogin(); this.checkDiscordLogin();
this.resetStateFlags(); this.resetStateFlags();
this.spinnerService.hideSpinner(); this.spinnerService.hideSpinner();
});
} }
checkDiscordLogin() { checkDiscordLogin() {

View File

@ -49,12 +49,10 @@ export class RegistrationComponent implements OnInit, OnDestroy {
private settings: SettingsService private settings: SettingsService
) { ) {
this.spinnerService.showSpinner(); this.spinnerService.showSpinner();
this.authService.isUserLoggedInAsync().then(res => { if (!this.authService.isLoggedIn$.value) {
if (res) {
this.router.navigate(["/dashboard"]); this.router.navigate(["/dashboard"]);
} }
this.spinnerService.hideSpinner(); this.spinnerService.hideSpinner();
});
} }
ngOnInit(): void { ngOnInit(): void {

View File

@ -2,7 +2,7 @@ import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Injectable } from "@angular/core"; import { Injectable } from "@angular/core";
import { Router } from "@angular/router"; import { Router } from "@angular/router";
import { JwtHelperService } from "@auth0/angular-jwt"; import { JwtHelperService } from "@auth0/angular-jwt";
import { firstValueFrom, Observable, Subject, Subscription, throwError } from "rxjs"; import { BehaviorSubject, firstValueFrom, Observable, Subject, Subscription, throwError } from "rxjs";
import { catchError } from "rxjs/operators"; import { catchError } from "rxjs/operators";
import { AdminUpdateUserDTO } from "src/app/models/auth/admin-update-user.dto"; import { AdminUpdateUserDTO } from "src/app/models/auth/admin-update-user.dto";
import { AuthRoles } from "src/app/models/auth/auth-roles.enum"; import { AuthRoles } from "src/app/models/auth/auth-roles.enum";
@ -23,8 +23,7 @@ import { OAuthDTO } from "../../models/auth/oauth.dto";
}) })
export class AuthService { export class AuthService {
private isLoggedIn!: boolean; isLoggedIn$ = new BehaviorSubject<boolean>(false);
isLoggedIn$ = new Subject<boolean>();
constructor( constructor(
private appsettings: SettingsService, private appsettings: SettingsService,
@ -33,9 +32,6 @@ export class AuthService {
private jwtHelper: JwtHelperService, private jwtHelper: JwtHelperService,
private spinnerService: SpinnerService private spinnerService: SpinnerService
) { ) {
this.isLoggedIn$.subscribe(value => {
this.isLoggedIn = value;
});
} }
/* data requests */ /* data requests */
@ -262,6 +258,7 @@ export class AuthService {
async isUserLoggedInAsync(): Promise<boolean> { async isUserLoggedInAsync(): Promise<boolean> {
const token = this.getToken(); const token = this.getToken();
console.log(1, token);
if (!token || !token.refreshToken) { if (!token || !token.refreshToken) {
this.isLoggedIn$.next(false); this.isLoggedIn$.next(false);
@ -279,17 +276,13 @@ export class AuthService {
return false; return false;
} }
if (this.isLoggedIn) {
this.spinnerService.showSpinner(); this.spinnerService.showSpinner();
const resfreshedToken = await firstValueFrom(await this.refresh(token)); const resfreshedToken = await firstValueFrom(await this.refresh(token));
this.spinnerService.hideSpinner(); this.spinnerService.hideSpinner();
if (resfreshedToken) { if (resfreshedToken) {
this.saveToken(resfreshedToken); this.saveToken(resfreshedToken);
return true; return true;
} }
}
return false; return false;
} }

View File

@ -4,18 +4,18 @@ import { Themes } from "src/app/models/view/themes.enum";
import { AuthService } from "../auth/auth.service"; import { AuthService } from "../auth/auth.service";
@Injectable({ @Injectable({
providedIn: 'root' providedIn: "root"
}) })
export class ThemeService { export class ThemeService {
themeName: string = Themes.Default; themeName: string = Themes.Default;
sidebarWidth = '150px'; sidebarWidth = "150px";
isSidebarOpen = false; isSidebarOpen = false;
themeName$ = new BehaviorSubject<string>(Themes.Default); themeName$ = new BehaviorSubject<string>(Themes.Default);
isSidebarOpen$ = new BehaviorSubject<boolean>(true); isSidebarOpen$ = new BehaviorSubject<boolean>(true);
sidebarWidth$ = new BehaviorSubject<string>('175px'); sidebarWidth$ = new BehaviorSubject<string>("175px");
constructor( constructor(
private authService: AuthService private authService: AuthService
@ -25,7 +25,7 @@ export class ThemeService {
}); });
this.isSidebarOpen$.subscribe(isSidebarOpen => { this.isSidebarOpen$.subscribe(isSidebarOpen => {
this.isSidebarOpen = isSidebarOpen; this.isSidebarOpen = isSidebarOpen;
this.sidebarWidth$.next(isSidebarOpen ? '175px' : '75px'); this.sidebarWidth$.next(isSidebarOpen ? "175px" : "75px");
}); });
this.sidebarWidth$.subscribe(sidebarWidth => { this.sidebarWidth$.subscribe(sidebarWidth => {
this.sidebarWidth = sidebarWidth; this.sidebarWidth = sidebarWidth;
@ -63,8 +63,7 @@ export class ThemeService {
return; return;
} }
this.authService.isUserLoggedInAsync().then(result => { if (!this.authService.isLoggedIn$.value) {
if (!result) {
localStorage.setItem(`default_themeName`, Themes.Default); localStorage.setItem(`default_themeName`, Themes.Default);
this.themeName$.next(Themes.Default); this.themeName$.next(Themes.Default);
} }
@ -76,7 +75,6 @@ export class ThemeService {
} }
localStorage.setItem(`default_themeName`, name); localStorage.setItem(`default_themeName`, name);
this.themeName$.next(name); this.themeName$.next(name);
});
} }
loadMenu() { loadMenu() {