Skip to content

Commit ff2844e

Browse files
authored
Merge pull request #5023 from tdonohue/port_4663_to_9x
[Port dspace-9_x] Fix authentication method retrieval after Tomcat restart
2 parents 2e0167b + 15babab commit ff2844e

3 files changed

Lines changed: 33 additions & 7 deletions

File tree

src/app/core/auth/auth.actions.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,16 @@ export class AuthenticatedAction implements Action {
6969
public type: string = AuthActionTypes.AUTHENTICATED;
7070
payload: AuthTokenInfo;
7171

72-
constructor(token: AuthTokenInfo) {
72+
/**
73+
* Whether we should consider the given authentication info final.
74+
* If the backend restarted we may have a token that hasn't expired yet, but it will be invalid anyway.
75+
* In this case we'll have to check twice.
76+
*/
77+
checkAgain: boolean;
78+
79+
constructor(token: AuthTokenInfo, checkAgain = false) {
7380
this.payload = token;
81+
this.checkAgain = checkAgain;
7482
}
7583
}
7684

src/app/core/auth/auth.effects.spec.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,25 +156,37 @@ describe('AuthEffects', () => {
156156

157157
describe('when token is valid', () => {
158158
it('should return a AUTHENTICATED_SUCCESS action in response to a AUTHENTICATED action', () => {
159-
actions = hot('--a-', { a: { type: AuthActionTypes.AUTHENTICATED, payload: token } });
159+
actions = hot('--a-', { a: new AuthenticatedAction(token) });
160160

161161
const expected = cold('--b-', { b: new AuthenticatedSuccessAction(true, token, EPersonMock._links.self.href) });
162162

163163
expect(authEffects.authenticated$).toBeObservable(expected);
164164
});
165165
});
166166

167-
describe('when token is not valid', () => {
167+
describe('when token is expired', () => {
168168
it('should return a AUTHENTICATED_ERROR action in response to a AUTHENTICATED action', () => {
169169
spyOn((authEffects as any).authService, 'authenticatedUser').and.returnValue(observableThrow(new Error('Message Error test')));
170170

171-
actions = hot('--a-', { a: { type: AuthActionTypes.AUTHENTICATED, payload: token } });
171+
actions = hot('--a-', { a: new AuthenticatedAction(token) });
172172

173173
const expected = cold('--b-', { b: new AuthenticatedErrorAction(new Error('Message Error test')) });
174174

175175
expect(authEffects.authenticated$).toBeObservable(expected);
176176
});
177177
});
178+
179+
describe('when token is not valid but also not expired (~ cookie)', () => {
180+
it('should return a AUTHENTICATED_ERROR action in response to a AUTHENTICATED action', () => {
181+
spyOn((authEffects as any).authService, 'authenticatedUser').and.returnValue(observableThrow(new Error('Message Error test')));
182+
183+
actions = hot('--a-', { a: new AuthenticatedAction(token, true) });
184+
185+
const expected = cold('--b-', { b: new CheckAuthenticationTokenCookieAction() });
186+
187+
expect(authEffects.authenticated$).toBeObservable(expected);
188+
});
189+
});
178190
});
179191

180192
describe('authenticatedSuccess$', () => {
@@ -210,7 +222,7 @@ describe('AuthEffects', () => {
210222

211223
actions = hot('--a-', { a: { type: AuthActionTypes.CHECK_AUTHENTICATION_TOKEN } });
212224

213-
const expected = cold('--b-', { b: new AuthenticatedAction(token) });
225+
const expected = cold('--b-', { b: new AuthenticatedAction(token, true) });
214226

215227
expect(authEffects.checkToken$).toBeObservable(expected);
216228
});

src/app/core/auth/auth.effects.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,13 @@ export class AuthEffects {
121121
switchMap((action: AuthenticatedAction) => {
122122
return this.authService.authenticatedUser(action.payload).pipe(
123123
map((userHref: string) => new AuthenticatedSuccessAction((userHref !== null), action.payload, userHref)),
124-
catchError((error: unknown) => errorToAuthAction$(AuthenticatedErrorAction, error)),
124+
catchError((error: unknown) => {
125+
if (action.checkAgain) {
126+
return of(new CheckAuthenticationTokenCookieAction());
127+
} else {
128+
return errorToAuthAction$(AuthenticatedErrorAction, error);
129+
}
130+
}),
125131
);
126132
}),
127133
));
@@ -176,7 +182,7 @@ export class AuthEffects {
176182
public checkToken$: Observable<Action> = createEffect(() => this.actions$.pipe(ofType(AuthActionTypes.CHECK_AUTHENTICATION_TOKEN),
177183
switchMap(() => {
178184
return this.authService.hasValidAuthenticationToken().pipe(
179-
map((token: AuthTokenInfo) => new AuthenticatedAction(token)),
185+
map((token: AuthTokenInfo) => new AuthenticatedAction(token, true)),
180186
catchError((error: unknown) => of(new CheckAuthenticationTokenCookieAction())),
181187
);
182188
}),

0 commit comments

Comments
 (0)