Skip to content

Commit f300d8d

Browse files
Francesco MautoAndrea Barbasso
authored andcommitted
Merged in task/dspace-cris-2025_02_x/DSC-2400 (pull request DSpace#4616)
[DSC-2400] fix redirect for item page resolver Approved-by: Andrea Barbasso
2 parents df8318e + cd8fc52 commit f300d8d

6 files changed

Lines changed: 46 additions & 8 deletions

File tree

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

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

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

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ import {
7979
RetrieveAuthMethodsErrorAction,
8080
RetrieveAuthMethodsSuccessAction,
8181
RetrieveTokenAction,
82+
SetRedirectUrlAndNavigateAction,
8283
SetUserAsIdleAction,
8384
} from './auth.actions';
8485
// import services
@@ -164,6 +165,13 @@ export class AuthEffects {
164165
}),
165166
), { dispatch: false });
166167

168+
public redirectAndNavigate$: Observable<Action> = createEffect(() => this.actions$
169+
.pipe(ofType(AuthActionTypes.SET_REDIRECT_URL_AND_NAVIGATE),
170+
tap((action: SetRedirectUrlAndNavigateAction) => this.router.navigate([decodeURIComponent(action.payload.navigateUrl)])),
171+
),
172+
{ dispatch: false },
173+
);
174+
167175
// It means "reacts to this action but don't send another"
168176
public authenticatedError$: Observable<Action> = createEffect(() => this.actions$.pipe(
169177
ofType(AuthActionTypes.AUTHENTICATED_ERROR),

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
RetrieveAuthMethodsSuccessAction,
1818
SetAuthCookieStatus,
1919
SetRedirectUrlAction,
20+
SetRedirectUrlAndNavigateAction,
2021
} from './auth.actions';
2122
import { AuthMethod } from './models/auth.method';
2223
import { AuthMethodType } from './models/auth.method-type';
@@ -267,6 +268,11 @@ export function authReducer(state: any = initialState, action: AuthActions): Aut
267268
redirectUrl: (action as SetRedirectUrlAction).payload,
268269
});
269270

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

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import {
6464
ResetAuthenticationMessagesAction,
6565
SetAuthCookieStatus,
6666
SetRedirectUrlAction,
67+
SetRedirectUrlAndNavigateAction,
6768
SetUserAsIdleAction,
6869
UnsetUserAsIdleAction,
6970
} from './auth.actions';
@@ -567,15 +568,19 @@ export class AuthService {
567568
/**
568569
* Set redirect url
569570
*/
570-
setRedirectUrl(url: string) {
571+
setRedirectUrl(redirectUrl: string, navigateUrl?: string) {
571572
// Add 1 hour to the current date
572573
const expireDate = Date.now() + (1000 * 60 * 60);
573574

574575
// Set the cookie expire date
575576
const expires = new Date(expireDate);
576577
const options: Cookies.CookieAttributes = { expires: expires };
577-
this.storage.set(REDIRECT_COOKIE, url, options);
578-
this.store.dispatch(new SetRedirectUrlAction(isNotUndefined(url) ? url : ''));
578+
this.storage.set(REDIRECT_COOKIE, redirectUrl, options);
579+
if (hasValue(navigateUrl)) {
580+
this.store.dispatch(new SetRedirectUrlAndNavigateAction(isNotUndefined(redirectUrl) ? redirectUrl : '', navigateUrl));
581+
} else {
582+
this.store.dispatch(new SetRedirectUrlAction(isNotUndefined(redirectUrl) ? redirectUrl : ''));
583+
}
579584
}
580585

581586
/**

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,11 @@ export const redirectOn4xx = <T>(router: Router, authService: AuthService) =>
4747
router.navigateByUrl(getForbiddenRoute(), { skipLocationChange: true });
4848
return false;
4949
} else {
50-
authService.setRedirectUrl(router.url);
51-
router.navigateByUrl('login');
50+
// During a resolver the navigation hasn't committed yet, so router.url still
51+
// points to the previous URL (e.g. '/'). Use the in-flight navigation's URL
52+
// when available, falling back to router.url for component-level calls.
53+
const redirectUrl = router.getCurrentNavigation()?.extractedUrl?.toString() ?? router.url;
54+
authService.setRedirectUrl(redirectUrl, 'login');
5255
return false;
5356
}
5457
}

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ describe('Core Module - RxJS Operators', () => {
190190
testScheduler = new TestScheduler((actual, expected) => {
191191
expect(actual).toEqual(expected);
192192
});
193-
router = jasmine.createSpyObj('router', ['navigateByUrl']);
193+
router = jasmine.createSpyObj('router', ['navigateByUrl', 'getCurrentNavigation']);
194194
authService = jasmine.createSpyObj('authService', {
195195
isAuthenticated: of(true),
196196
setRedirectUrl: {},
@@ -277,7 +277,6 @@ describe('Core Module - RxJS Operators', () => {
277277
expectObservable(source.pipe(redirectOn4xx(router, authService))).toBe(expected, values);
278278
flush();
279279
expect(authService.setRedirectUrl).toHaveBeenCalled();
280-
expect(router.navigateByUrl).toHaveBeenCalledWith('login');
281280
});
282281
});
283282

@@ -291,7 +290,6 @@ describe('Core Module - RxJS Operators', () => {
291290
expectObservable(source.pipe(redirectOn4xx(router, authService))).toBe(expected, values);
292291
flush();
293292
expect(authService.setRedirectUrl).toHaveBeenCalled();
294-
expect(router.navigateByUrl).toHaveBeenCalledWith('login');
295293
});
296294
});
297295
});

0 commit comments

Comments
 (0)