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 {
webCredentials!: string;
apiToken!: string;
user!: User;
apiTokenExpirationTime!: Moment;
webCredentials?: string;
apiToken?: string;
user?: User;
apiTokenExpirationTime?: Moment;
public isGoogleLibLoaded: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
@@ -61,7 +61,7 @@ export class AuthService {
// 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({
next: (data) => {
this.user.id = data.id;
this.user!.id = data.id;
this.apiToken = data.token;
this.apiTokenExpirationTime = moment(data.expirationTime);
resolve(data);
@@ -80,7 +80,23 @@ export class AuthService {
return !!this.apiToken &&
!!this.webCredentials &&
!!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
createBroadcastChannel() {
@@ -90,6 +106,7 @@ export class AuthService {
}
}
broadcastListener(event: MessageEvent<AuthMessage>) {
console.log('BroadcastChannel message recieved', event.data.type);
switch (event.data.type) {
case BroadcastType.REQUEST_AUTH_DATA:
this.sendAuthData();
@@ -98,6 +115,7 @@ export class AuthService {
this.recieveAuthData(event.data.data!);
break;
case BroadcastType.LOGOUT:
this.logout();
break;
default:
break;
@@ -109,14 +127,16 @@ export class AuthService {
});
}
sendAuthData() {
this.bc.postMessage({
type: BroadcastType.SEND_AUTH_DATA,
data: {
webCredentials: this.webCredentials,
apiToken: this.apiToken,
apiTokenExpirationTime: this.apiTokenExpirationTime.toISOString()
}
});
if (this.isAuthenticated()) {
this.bc.postMessage({
type: BroadcastType.SEND_AUTH_DATA,
data: {
webCredentials: this.webCredentials,
apiToken: this.apiToken,
apiTokenExpirationTime: this.apiTokenExpirationTime?.toISOString()
}
});
}
}
recieveAuthData(data: AuthData) {
this.webCredentials = data.webCredentials;

View File

@@ -20,7 +20,7 @@ export class AuthInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
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(
mergeMap(() => {
return next.handle(request.clone({

View File

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