Skip to content

Commit adc82b8

Browse files
committed
fix(error-interceptor): fixed logout
1 parent becbf62 commit adc82b8

2 files changed

Lines changed: 38 additions & 5 deletions

File tree

src/app/core/interceptors/error.interceptor.spec.ts

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { Router } from '@angular/router';
99

1010
import { SENTRY_TOKEN } from '@core/provider/sentry.provider';
1111
import { AuthService } from '@core/services/auth.service';
12+
import { UserSelectors } from '@core/store/user';
1213
import { ToastService } from '@osf/shared/services/toast.service';
1314
import { ViewOnlyLinkHelperService } from '@osf/shared/services/view-only-link-helper.service';
1415

@@ -17,6 +18,7 @@ import { AuthServiceMock, AuthServiceMockType } from '@testing/providers/auth-se
1718
import { LoaderServiceMock, provideLoaderServiceMock } from '@testing/providers/loader-service.mock';
1819
import { RouterMockBuilder, RouterMockType } from '@testing/providers/router-provider.mock';
1920
import { SentryMock, SentryMockType } from '@testing/providers/sentry-provider.mock';
21+
import { provideMockStore } from '@testing/providers/store-provider.mock';
2022
import { ToastServiceMock, ToastServiceMockType } from '@testing/providers/toast-provider.mock';
2123
import { ViewOnlyLinkHelperMock, ViewOnlyLinkHelperMockType } from '@testing/providers/view-only-link-helper.mock';
2224

@@ -31,7 +33,12 @@ describe('errorInterceptor', () => {
3133
let viewOnlyHelperMock: ViewOnlyLinkHelperMockType;
3234
let sentryMock: SentryMockType;
3335

34-
function setup(platformId: 'browser' | 'server' = 'browser', viewOnly = false, routerUrl = '/dashboard') {
36+
function setup(
37+
platformId: 'browser' | 'server' = 'browser',
38+
viewOnly = false,
39+
routerUrl = '/dashboard',
40+
isAuthenticated = false
41+
) {
3542
router = RouterMockBuilder.create().withUrl(routerUrl).withNavigate(vi.fn().mockResolvedValue(true)).build();
3643
toastServiceMock = ToastServiceMock.simple();
3744
loaderServiceMock = new LoaderServiceMock();
@@ -43,6 +50,9 @@ describe('errorInterceptor', () => {
4350
providers: [
4451
provideOSFCore(),
4552
provideLoaderServiceMock(loaderServiceMock),
53+
provideMockStore({
54+
selectors: [{ selector: UserSelectors.isAuthenticated, value: isAuthenticated }],
55+
}),
4656
MockProvider(Router, router),
4757
MockProvider(ToastService, toastServiceMock),
4858
MockProvider(AuthService, authServiceMock),
@@ -107,15 +117,30 @@ describe('errorInterceptor', () => {
107117
expect(toastServiceMock.showError).not.toHaveBeenCalled();
108118
});
109119

110-
it('should logout on 401 in browser when not view-only', async () => {
111-
setup('browser', false);
120+
it('should navigate to sign in on 401 in browser when anonymous and not view-only', async () => {
121+
setup('browser', false, '/dashboard', false);
112122
const request = createRequest('/api/v2/nodes/abc');
113123
const error = new HttpErrorResponse({ status: 401, error: {}, url: request.url });
114124

115125
const caught = await runInterceptor(request, error);
116126

117127
expect(caught?.status).toBe(401);
118-
expect(authServiceMock.logout).toHaveBeenCalled();
128+
expect(authServiceMock.navigateToSignIn).toHaveBeenCalled();
129+
expect(authServiceMock.logout).not.toHaveBeenCalled();
130+
expect(loaderServiceMock.hide).not.toHaveBeenCalled();
131+
expect(toastServiceMock.showError).not.toHaveBeenCalled();
132+
});
133+
134+
it('should logout on 401 in browser when authenticated and not view-only', async () => {
135+
setup('browser', false, '/dashboard', true);
136+
const request = createRequest('/api/v2/nodes/abc');
137+
const error = new HttpErrorResponse({ status: 401, error: {}, url: request.url });
138+
139+
const caught = await runInterceptor(request, error);
140+
141+
expect(caught?.status).toBe(401);
142+
expect(authServiceMock.logout).toHaveBeenCalledWith(window.location.href);
143+
expect(authServiceMock.navigateToSignIn).not.toHaveBeenCalled();
119144
expect(loaderServiceMock.hide).not.toHaveBeenCalled();
120145
expect(toastServiceMock.showError).not.toHaveBeenCalled();
121146
});

src/app/core/interceptors/error.interceptor.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Store } from '@ngxs/store';
2+
13
import { throwError } from 'rxjs';
24
import { catchError } from 'rxjs/operators';
35

@@ -9,6 +11,7 @@ import { Router } from '@angular/router';
911
import { ERROR_MESSAGES } from '@core/constants/error-messages';
1012
import { SENTRY_TOKEN } from '@core/provider/sentry.provider';
1113
import { AuthService } from '@core/services/auth.service';
14+
import { UserSelectors } from '@core/store/user';
1215
import { LoaderService } from '@osf/shared/services/loader.service';
1316
import { ToastService } from '@osf/shared/services/toast.service';
1417
import { ViewOnlyLinkHelperService } from '@osf/shared/services/view-only-link-helper.service';
@@ -23,6 +26,7 @@ export const errorInterceptor: HttpInterceptorFn = (req, next) => {
2326
const sentry = inject(SENTRY_TOKEN);
2427
const platformId = inject(PLATFORM_ID);
2528
const viewOnlyHelper = inject(ViewOnlyLinkHelperService);
29+
const store = inject(Store);
2630

2731
return next(req).pipe(
2832
catchError((error: HttpErrorResponse) => {
@@ -55,7 +59,11 @@ export const errorInterceptor: HttpInterceptorFn = (req, next) => {
5559
if (error.status === 401) {
5660
if (!viewOnlyHelper.hasViewOnlyParam(router)) {
5761
if (isPlatformBrowser(platformId)) {
58-
authService.logout();
62+
if (store.selectSnapshot(UserSelectors.isAuthenticated)) {
63+
authService.logout(window.location.href);
64+
} else {
65+
authService.navigateToSignIn();
66+
}
5967
}
6068
}
6169
return throwError(() => error);

0 commit comments

Comments
 (0)