Skip to content

Commit ba29dac

Browse files
Implement solution provided by @voegtlel and @andpii
#850 (comment) #850 (comment)
1 parent c724ad7 commit ba29dac

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

projects/lib/src/oauth-service.ts

+54
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ export class OAuthService extends AuthConfig implements OnDestroy {
107107
protected sessionCheckTimer: any;
108108
protected silentRefreshSubject: string;
109109
protected inImplicitFlow = false;
110+
protected lastUpdatedAccessToken: string | null = null;
110111

111112
protected saveNoncesInLocalStorage = false;
112113
private document: Document;
@@ -171,6 +172,10 @@ export class OAuthService extends AuthConfig implements OnDestroy {
171172
}
172173

173174
this.setupRefreshTimer();
175+
176+
if (this.hasValidAccessToken()) {
177+
this.lastUpdatedAccessToken = this.getAccessToken();
178+
}
174179
}
175180

176181
private checkLocalStorageAccessable() {
@@ -927,6 +932,27 @@ export class OAuthService extends AuthConfig implements OnDestroy {
927932
* method silentRefresh.
928933
*/
929934
public refreshToken(): Promise<TokenResponse> {
935+
// Handle multiple browser tabs if navigator.locks is available
936+
if (!navigator.locks) {
937+
return this._refreshToken();
938+
}
939+
return navigator.locks.request(
940+
`refresh_token_${location.origin}`,
941+
async (): Promise<TokenResponse> => {
942+
if (this.lastUpdatedAccessToken !== this.getAccessToken()) {
943+
// Was already updated in another tab/window
944+
this.eventsSubject.next(new OAuthSuccessEvent('token_received'));
945+
this.eventsSubject.next(new OAuthSuccessEvent('token_refreshed'));
946+
this.lastUpdatedAccessToken = this.getAccessToken();
947+
return;
948+
} else {
949+
// Simply run the original update
950+
return this._refreshToken();
951+
}
952+
}
953+
);
954+
}
955+
protected _refreshToken(): Promise<TokenResponse> {
930956
this.assertUrlNotNullAndCorrectProtocol(
931957
this.tokenEndpoint,
932958
'tokenEndpoint'
@@ -1051,6 +1077,32 @@ export class OAuthService extends AuthConfig implements OnDestroy {
10511077
public silentRefresh(
10521078
params: object = {},
10531079
noPrompt = true
1080+
): Promise<OAuthEvent> {
1081+
// Handle multiple browser tabs if navigator.locks is available
1082+
if (!navigator.locks) {
1083+
return this._silentRefresh(params, noPrompt);
1084+
}
1085+
return navigator.locks.request(
1086+
`silent_refresh_${location.origin}`,
1087+
async (): Promise<OAuthEvent> => {
1088+
if (this.lastUpdatedAccessToken !== this.getAccessToken()) {
1089+
// Was already updated in another tab/window
1090+
this.eventsSubject.next(new OAuthSuccessEvent('token_received'));
1091+
this.eventsSubject.next(new OAuthSuccessEvent('token_refreshed'));
1092+
const event = new OAuthSuccessEvent('silently_refreshed');
1093+
this.eventsSubject.next(event);
1094+
this.lastUpdatedAccessToken = this.getAccessToken();
1095+
return event;
1096+
} else {
1097+
// Simply run the original update
1098+
return this._silentRefresh(params, noPrompt);
1099+
}
1100+
}
1101+
);
1102+
}
1103+
protected _silentRefresh(
1104+
params: object = {},
1105+
noPrompt = true
10541106
): Promise<OAuthEvent> {
10551107
const claims: object = this.getIdentityClaims() || {};
10561108

@@ -1677,6 +1729,7 @@ export class OAuthService extends AuthConfig implements OnDestroy {
16771729
customParameters?: Map<string, string>
16781730
): void {
16791731
this._storage.setItem('access_token', accessToken);
1732+
this.lastUpdatedAccessToken = accessToken;
16801733
if (grantedScopes && !Array.isArray(grantedScopes)) {
16811734
this._storage.setItem(
16821735
'granted_scopes',
@@ -2496,6 +2549,7 @@ export class OAuthService extends AuthConfig implements OnDestroy {
24962549

24972550
const id_token = this.getIdToken();
24982551
this._storage.removeItem('access_token');
2552+
this.lastUpdatedAccessToken = null;
24992553
this._storage.removeItem('id_token');
25002554
this._storage.removeItem('refresh_token');
25012555

0 commit comments

Comments
 (0)