Logout from all tabs

This commit is contained in:
Michał Zieliński
2023-11-07 23:26:47 +01:00
parent 904338ba1d
commit 42acf08b8d
3 changed files with 40 additions and 20 deletions

View File

@@ -11,10 +11,10 @@ import jwt_decode from "jwt-decode";
}) })
export class AuthService { export class AuthService {
webCredentials!: string; webCredentials?: string;
apiToken!: string; apiToken?: string;
user!: User; user?: User;
apiTokenExpirationTime!: Moment; apiTokenExpirationTime?: Moment;
public isGoogleLibLoaded: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false); public isGoogleLibLoaded: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
@@ -61,7 +61,7 @@ export class AuthService {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
this.http$.post<any>(`${environment.api.url}/auth/apiToken`, JSON.stringify(this.webCredentials), { headers: header }).subscribe({ this.http$.post<any>(`${environment.api.url}/auth/apiToken`, JSON.stringify(this.webCredentials), { headers: header }).subscribe({
next: (data) => { next: (data) => {
this.user.id = data.id; this.user!.id = data.id;
this.apiToken = data.token; this.apiToken = data.token;
this.apiTokenExpirationTime = moment(data.expirationTime); this.apiTokenExpirationTime = moment(data.expirationTime);
resolve(data); resolve(data);
@@ -80,7 +80,23 @@ export class AuthService {
return !!this.apiToken && return !!this.apiToken &&
!!this.webCredentials && !!this.webCredentials &&
!!this.user && !!this.user &&
this.apiTokenExpirationTime.isAfter(moment()); this.apiTokenExpirationTime!.isAfter(moment());
}
logoutHandler() {
this.logout();
this.bc.postMessage({
type: BroadcastType.LOGOUT
});
}
logout() {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
google.accounts.id.disableAutoSelect();
this.apiToken = undefined;
this.webCredentials = undefined;
this.user = undefined;
this.apiTokenExpirationTime = undefined;
window.location.reload();
} }
// broadcastChannel // broadcastChannel
createBroadcastChannel() { createBroadcastChannel() {
@@ -90,6 +106,7 @@ export class AuthService {
} }
} }
broadcastListener(event: MessageEvent<AuthMessage>) { broadcastListener(event: MessageEvent<AuthMessage>) {
console.log('BroadcastChannel message recieved', event.data.type);
switch (event.data.type) { switch (event.data.type) {
case BroadcastType.REQUEST_AUTH_DATA: case BroadcastType.REQUEST_AUTH_DATA:
this.sendAuthData(); this.sendAuthData();
@@ -98,6 +115,7 @@ export class AuthService {
this.recieveAuthData(event.data.data!); this.recieveAuthData(event.data.data!);
break; break;
case BroadcastType.LOGOUT: case BroadcastType.LOGOUT:
this.logout();
break; break;
default: default:
break; break;
@@ -109,14 +127,16 @@ export class AuthService {
}); });
} }
sendAuthData() { sendAuthData() {
this.bc.postMessage({ if (this.isAuthenticated()) {
type: BroadcastType.SEND_AUTH_DATA, this.bc.postMessage({
data: { type: BroadcastType.SEND_AUTH_DATA,
webCredentials: this.webCredentials, data: {
apiToken: this.apiToken, webCredentials: this.webCredentials,
apiTokenExpirationTime: this.apiTokenExpirationTime.toISOString() apiToken: this.apiToken,
} apiTokenExpirationTime: this.apiTokenExpirationTime?.toISOString()
}); }
});
}
} }
recieveAuthData(data: AuthData) { recieveAuthData(data: AuthData) {
this.webCredentials = data.webCredentials; this.webCredentials = data.webCredentials;

View File

@@ -20,7 +20,7 @@ export class AuthInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> { intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
if (!request.url.includes('/auth/apiToken')) { if (!request.url.includes('/auth/apiToken')) {
if (this.auth$.apiTokenExpirationTime.isBefore(moment.utc())) { if (this.auth$.apiTokenExpirationTime?.isBefore(moment.utc())) {
return this.auth$.getAPITokenObservable().pipe( return this.auth$.getAPITokenObservable().pipe(
mergeMap(() => { mergeMap(() => {
return next.handle(request.clone({ return next.handle(request.clone({

View File

@@ -27,16 +27,16 @@
{{environment.appName}} {{environment.appName}}
<div class="fill-space"></div> <div class="fill-space"></div>
<a mat-icon-button [matMenuTriggerFor]="userMenu"> <a mat-icon-button [matMenuTriggerFor]="userMenu">
<mat-icon *ngIf="!auth$.user.avatar">account_circle</mat-icon> <mat-icon *ngIf="!auth$.user?.avatar">account_circle</mat-icon>
<img *ngIf="auth$.user.avatar" [src]="auth$.user.avatar" class="profile-photo-small" <img *ngIf="auth$.user?.avatar" [src]="auth$.user?.avatar" class="profile-photo-small"
alt="Profile photo"> alt="Profile photo">
</a> </a>
<mat-menu #userMenu="matMenu"> <mat-menu #userMenu="matMenu">
<div class="profile-info"> <div class="profile-info">
<img [src]="auth$.user.avatar" class="profile-photo-big" alt="Profile photo"> <img [src]="auth$.user?.avatar" class="profile-photo-big" alt="Profile photo">
<p>{{auth$.user.userName}}</p> <p>{{auth$.user?.userName}}</p>
</div> </div>
<button mat-menu-item (click)="logout()"> <button mat-menu-item (click)="auth$.logoutHandler()">
<mat-icon>exit_to_app</mat-icon> <mat-icon>exit_to_app</mat-icon>
<span>Logout</span> <span>Logout</span>
</button> </button>