Skip to content

Commit 78116da

Browse files
Francesco MautoAndrea Barbasso
authored andcommitted
Merged in task/dspace-cris-2024_02_x/DSC-2400 (pull request DSpace#4615)
[DSC-2400] fix redirect for item page resolver Approved-by: Andrea Barbasso
2 parents dda2c0b + ab80117 commit 78116da

10 files changed

Lines changed: 1784 additions & 1617 deletions

File tree

bitbucket-pipelines.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ definitions:
6262
- step: &angular-build
6363
name: angular-build
6464
image:
65-
name: cypress/browsers:node-20.18.0-chrome-130.0.6723.69-1-ff-131.0.3-edge-130.0.2849.52-1
65+
name: cypress/browsers:node-22.21.0-chrome-141.0.7390.107-1-ff-144.0-edge-141.0.3537.92-1
6666
run-as-user: 1000
6767
size: 4x
6868
caches:
@@ -78,7 +78,7 @@ definitions:
7878
- step: &unittest-code-checks
7979
name: test-code-checks
8080
image:
81-
name: cypress/browsers:node-20.18.0-chrome-130.0.6723.69-1-ff-131.0.3-edge-130.0.2849.52-1
81+
name: cypress/browsers:node-22.21.0-chrome-141.0.7390.107-1-ff-144.0-edge-141.0.3537.92-1
8282
run-as-user: 1000
8383
size: 4x
8484
caches:
@@ -96,7 +96,7 @@ definitions:
9696
- step: &run-e2e-tests
9797
name: Run E2E test
9898
image:
99-
name: cypress/browsers:node-20.18.0-chrome-130.0.6723.69-1-ff-131.0.3-edge-130.0.2849.52-1
99+
name: cypress/browsers:node-22.21.0-chrome-141.0.7390.107-1-ff-144.0-edge-141.0.3537.92-1
100100
run-as-user: 0
101101
size: 4x
102102
services:

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@
115115
"date-fns": "^2.29.3",
116116
"date-fns-tz": "^1.3.7",
117117
"deepmerge": "^4.3.1",
118-
"domino-ext": "^2.1.4",
119118
"ejs": "^3.1.10",
120119
"express": "^4.21.2",
121120
"express-rate-limit": "^5.1.3",

server.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import * as express from 'express';
2424
import * as ejs from 'ejs';
2525
import * as compression from 'compression';
2626
import * as expressStaticGzip from 'express-static-gzip';
27-
import * as domino from 'domino-ext';
2827
/* eslint-enable import/no-namespace */
2928
import axios from 'axios';
3029
import LRU from 'lru-cache';
@@ -85,20 +84,10 @@ let anonymousCache: LRU<string, any>;
8584
// extend environment with app config for server
8685
extendEnvironmentWithAppConfig(environment, appConfig);
8786

88-
// Create a DOM window object based on the template
89-
const _window = domino.createWindow(indexHtml);
90-
9187
// The REST server base URL
9288
const REST_BASE_URL = environment.rest.ssrBaseUrl || environment.rest.baseUrl;
9389

9490
const IIIF_ALLOWED_ORIGINS = environment.rest.allowedOrigins || [];
95-
96-
// Assign the DOM window and document objects to the global object
97-
(_window as any).screen = { deviceXDPI: 0, logicalXDPI: 0 };
98-
(global as any).window = _window;
99-
(global as any).document = _window.document;
100-
(global as any).navigator = _window.navigator;
101-
10291
// The Express app is exported so that it can be used by serverless Functions.
10392
export function app() {
10493

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: 9 additions & 4 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';
@@ -556,15 +557,19 @@ export class AuthService {
556557
/**
557558
* Set redirect url
558559
*/
559-
setRedirectUrl(url: string) {
560+
setRedirectUrl(redirectUrl: string, navigateUrl?: string) {
560561
// Add 1 hour to the current date
561562
const expireDate = Date.now() + (1000 * 60 * 60);
562563

563564
// Set the cookie expire date
564565
const expires = new Date(expireDate);
565-
const options: CookieAttributes = { expires: expires };
566-
this.storage.set(REDIRECT_COOKIE, url, options);
567-
this.store.dispatch(new SetRedirectUrlAction(isNotUndefined(url) ? url : ''));
566+
const options: Cookies.CookieAttributes = { expires: expires };
567+
this.storage.set(REDIRECT_COOKIE, redirectUrl, options);
568+
if (hasValue(navigateUrl)) {
569+
this.store.dispatch(new SetRedirectUrlAndNavigateAction(isNotUndefined(redirectUrl) ? redirectUrl : '', navigateUrl));
570+
} else {
571+
this.store.dispatch(new SetRedirectUrlAction(isNotUndefined(redirectUrl) ? redirectUrl : ''));
572+
}
568573
}
569574

570575
/**

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: observableOf(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)