Skip to content

Commit 572ef88

Browse files
Francesco MautoAndrea Barbasso
authored andcommitted
Merged in task/dspace-cris-2023_02_x/DSC-2400 (pull request DSpace#4614)
[DSC-2400] fix redirect for item page resolver Approved-by: Andrea Barbasso
2 parents 2b970e1 + 549122a commit 572ef88

8 files changed

Lines changed: 2211 additions & 2972 deletions

File tree

bitbucket-pipelines.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ definitions:
66
- step: &unittest-code-checks
77
name: test-code-checks
88
image:
9-
name: cypress/browsers:node-18.20.3-chrome-125.0.6422.141-1-ff-126.0.1-edge-125.0.2535.85-1
9+
name: cypress/browsers:node-22.21.0-chrome-141.0.7390.107-1-ff-144.0-edge-141.0.3537.92-1
1010
run-as-user: 1000
1111
size: 4x
1212
caches:

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export const AuthActionTypes = {
3434
LOG_OUT_ERROR: type('dspace/auth/LOG_OUT_ERROR'),
3535
LOG_OUT_SUCCESS: type('dspace/auth/LOG_OUT_SUCCESS'),
3636
SET_REDIRECT_URL: type('dspace/auth/SET_REDIRECT_URL'),
37+
SET_REDIRECT_URL_AND_NAVIGATE: type('dspace/auth/SET_REDIRECT_URL_AND_NAVIGATE'),
3738
RETRIEVE_AUTHENTICATED_EPERSON: type('dspace/auth/RETRIEVE_AUTHENTICATED_EPERSON'),
3839
RETRIEVE_AUTHENTICATED_EPERSON_SUCCESS: type('dspace/auth/RETRIEVE_AUTHENTICATED_EPERSON_SUCCESS'),
3940
RETRIEVE_AUTHENTICATED_EPERSON_ERROR: type('dspace/auth/RETRIEVE_AUTHENTICATED_EPERSON_ERROR'),
@@ -359,6 +360,23 @@ export class SetRedirectUrlAction implements Action {
359360
}
360361
}
361362

363+
/**
364+
* Change the redirect url.
365+
* @class SetRedirectUrlAction
366+
* @implements {Action}
367+
*/
368+
export class SetRedirectUrlAndNavigateAction implements Action {
369+
public type: string = AuthActionTypes.SET_REDIRECT_URL_AND_NAVIGATE;
370+
payload: {
371+
redirectUrl: string;
372+
navigateUrl: string;
373+
};
374+
375+
constructor(redirectUrl: string, navigateUrl: string) {
376+
this.payload = { redirectUrl, navigateUrl };
377+
}
378+
}
379+
362380
/**
363381
* Start loading for a hard redirect
364382
* @class StartHardRedirectLoadingAction

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ import {
5151
RetrieveAuthMethodsErrorAction,
5252
RetrieveAuthMethodsSuccessAction,
5353
RetrieveTokenAction,
54-
SetUserAsIdleAction
54+
SetRedirectUrlAndNavigateAction,
55+
SetUserAsIdleAction,
5556
} from './auth.actions';
5657
import { hasValue, isNotNull } from '../../shared/empty.util';
5758
import { Router } from '@angular/router';
@@ -123,6 +124,13 @@ export class AuthEffects {
123124
})
124125
), { dispatch: false });
125126

127+
public redirectAndNavigate$: Observable<Action> = createEffect(() => this.actions$
128+
.pipe(ofType(AuthActionTypes.SET_REDIRECT_URL_AND_NAVIGATE),
129+
tap((action: SetRedirectUrlAndNavigateAction) => this.router.navigate([decodeURIComponent(action.payload.navigateUrl)])),
130+
),
131+
{ dispatch: false },
132+
);
133+
126134
// It means "reacts to this action but don't send another"
127135
public authenticatedError$: Observable<Action> = createEffect(() => this.actions$.pipe(
128136
ofType(AuthActionTypes.AUTHENTICATED_ERROR),

src/app/core/auth/auth.reducer.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ import {
1212
RefreshTokenAndRedirectSuccessAction,
1313
RefreshTokenSuccessAction,
1414
RetrieveAuthenticatedEpersonSuccessAction,
15-
RetrieveAuthMethodsSuccessAction, SetAuthCookieStatus,
16-
SetRedirectUrlAction
15+
RetrieveAuthMethodsSuccessAction,
16+
SetAuthCookieStatus,
17+
SetRedirectUrlAction,
18+
SetRedirectUrlAndNavigateAction,
1719
} from './auth.actions';
1820
// import models
1921
import { AuthTokenInfo } from './models/auth-token-info.model';
@@ -266,6 +268,11 @@ export function authReducer(state: any = initialState, action: AuthActions): Aut
266268
redirectUrl: (action as SetRedirectUrlAction).payload,
267269
});
268270

271+
case AuthActionTypes.SET_REDIRECT_URL_AND_NAVIGATE:
272+
return Object.assign({}, state, {
273+
redirectUrl: (action as SetRedirectUrlAndNavigateAction).payload.redirectUrl,
274+
});
275+
269276
case AuthActionTypes.REDIRECT_AFTER_LOGIN_SUCCESS:
270277
return Object.assign({}, state, {
271278
loading: true,

src/app/core/auth/auth.service.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
RefreshTokenAction,
3232
ResetAuthenticationMessagesAction, SetAuthCookieStatus,
3333
SetRedirectUrlAction,
34+
SetRedirectUrlAndNavigateAction,
3435
SetUserAsIdleAction,
3536
UnsetUserAsIdleAction
3637
} from './auth.actions';
@@ -518,15 +519,19 @@ export class AuthService {
518519
/**
519520
* Set redirect url
520521
*/
521-
setRedirectUrl(url: string) {
522+
setRedirectUrl(redirectUrl: string, navigateUrl?: string) {
522523
// Add 1 hour to the current date
523524
const expireDate = Date.now() + (1000 * 60 * 60);
524525

525526
// Set the cookie expire date
526527
const expires = new Date(expireDate);
527-
const options: CookieAttributes = {expires: expires};
528-
this.storage.set(REDIRECT_COOKIE, url, options);
529-
this.store.dispatch(new SetRedirectUrlAction(isNotUndefined(url) ? url : ''));
528+
const options: Cookies.CookieAttributes = { expires: expires };
529+
this.storage.set(REDIRECT_COOKIE, redirectUrl, options);
530+
if (hasValue(navigateUrl)) {
531+
this.store.dispatch(new SetRedirectUrlAndNavigateAction(isNotUndefined(redirectUrl) ? redirectUrl : '', navigateUrl));
532+
} else {
533+
this.store.dispatch(new SetRedirectUrlAction(isNotUndefined(redirectUrl) ? redirectUrl : ''));
534+
}
530535
}
531536

532537
/**

src/app/core/shared/authorized.operators.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@ export const redirectOn4xx = <T>(router: Router, authService: AuthService) =>
3333
router.navigateByUrl(getForbiddenRoute(), { skipLocationChange: true });
3434
return false;
3535
} else {
36-
authService.setRedirectUrl(router.url);
37-
router.navigateByUrl('login');
36+
// During a resolver the navigation hasn't committed yet, so router.url still
37+
// points to the previous URL (e.g. '/'). Use the in-flight navigation's URL
38+
// when available, falling back to router.url for component-level calls.
39+
const redirectUrl = router.getCurrentNavigation()?.extractedUrl?.toString() ?? router.url;
40+
authService.setRedirectUrl(redirectUrl, 'login');
3841
return false;
3942
}
4043
}

src/app/core/shared/operators.spec.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ describe('Core Module - RxJS Operators', () => {
180180
testScheduler = new TestScheduler((actual, expected) => {
181181
expect(actual).toEqual(expected);
182182
});
183-
router = jasmine.createSpyObj('router', ['navigateByUrl']);
183+
router = jasmine.createSpyObj('router', ['navigateByUrl', 'getCurrentNavigation']);
184184
authService = jasmine.createSpyObj('authService', {
185185
isAuthenticated: observableOf(true),
186186
setRedirectUrl: {}
@@ -267,7 +267,6 @@ describe('Core Module - RxJS Operators', () => {
267267
expectObservable(source.pipe(redirectOn4xx(router, authService))).toBe(expected, values);
268268
flush();
269269
expect(authService.setRedirectUrl).toHaveBeenCalled();
270-
expect(router.navigateByUrl).toHaveBeenCalledWith('login');
271270
});
272271
});
273272

@@ -281,7 +280,6 @@ describe('Core Module - RxJS Operators', () => {
281280
expectObservable(source.pipe(redirectOn4xx(router, authService))).toBe(expected, values);
282281
flush();
283282
expect(authService.setRedirectUrl).toHaveBeenCalled();
284-
expect(router.navigateByUrl).toHaveBeenCalledWith('login');
285283
});
286284
});
287285
});

0 commit comments

Comments
 (0)