Share credentials between app tabs

This commit is contained in:
Michał Zieliński
2023-11-07 16:30:34 +01:00
parent db09a8c90f
commit 3a805216a5
2 changed files with 92 additions and 5 deletions

View File

@@ -13,16 +13,29 @@ export class AuthGuard {
private router$: Router,
) {}
canActivate(): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
if (this.auth$.user && this.auth$.webCredentials) {
if (this.auth$.isAuthenticated()) {
if (this.loginUrl) {
this.router$.navigate([this.loginUrl]);
this.loginUrl = null;
}
return true;
} else {
this.loginUrl = window.location.pathname;
this.router$.navigate(['']);
return false;
console.log('Not auth try to wait');
return this.tryWaitForAuthData();
}
}
async tryWaitForAuthData(): Promise<boolean> {
return new Promise((resolve) => {
setTimeout(() => {
if (this.auth$.isAuthenticated()) {
resolve(true);
} else {
console.log('GoToLogin');
this.loginUrl = window.location.pathname;
this.router$.navigate(['']);
resolve(false);
}
}, 100);
})
}
}

View File

@@ -16,9 +16,14 @@ export class AuthService {
user!: User;
apiTokenExpirationTime!: Moment;
bc!: BroadcastChannel;
constructor(
private http$: HttpClient,
) { }
) {
this.createBroadcastChannel();
this.askForAuthData();
}
ping() {
return new Promise((resolve, reject) => {
@@ -64,4 +69,73 @@ export class AuthService {
getAPITokenObservable(): Observable<void> {
return from(this.getAPIToken());
}
isAuthenticated(): boolean {
return !!this.apiToken &&
!!this.webCredentials &&
!!this.user &&
this.apiTokenExpirationTime.isAfter(moment());
}
// broadcastChannel
createBroadcastChannel() {
try {
this.bc = new BroadcastChannel('auth');
this.bc.onmessage = (event: MessageEvent<AuthMessage>) => {
this.broadcastListener(event);
}
} catch (e) {
console.log('eee', e);
}
}
broadcastListener(event: MessageEvent<AuthMessage>) {
switch (event.data.type) {
case BroadcastType.REQUEST_AUTH_DATA:
this.sendAuthData();
break;
case BroadcastType.SEND_AUTH_DATA:
this.recieveAuthData(event.data.data!);
break;
case BroadcastType.LOGOUT:
break;
default:
break;
}
}
askForAuthData() {
this.bc.postMessage({
type: BroadcastType.REQUEST_AUTH_DATA
});
}
sendAuthData() {
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;
this.apiToken = data.apiToken;
this.apiTokenExpirationTime = moment(data.apiTokenExpirationTime);
this.retrieveUserFromCredentials(this.webCredentials);
}
}
enum BroadcastType {
REQUEST_AUTH_DATA = 'request',
SEND_AUTH_DATA = 'send',
LOGOUT = 'logout'
}
interface AuthData {
webCredentials: string,
apiToken: string,
apiTokenExpirationTime: string
}
interface AuthMessage {
sender: string,
type: BroadcastType,
data?: AuthData
}