Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/app/core/auth/auth.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const AuthActionTypes = {
LOG_OUT_ERROR: type('dspace/auth/LOG_OUT_ERROR'),
LOG_OUT_SUCCESS: type('dspace/auth/LOG_OUT_SUCCESS'),
SET_REDIRECT_URL: type('dspace/auth/SET_REDIRECT_URL'),
SET_REDIRECT_URL_AND_NAVIGATE: type('dspace/auth/SET_REDIRECT_URL_AND_NAVIGATE'),
RETRIEVE_AUTHENTICATED_EPERSON: type('dspace/auth/RETRIEVE_AUTHENTICATED_EPERSON'),
RETRIEVE_AUTHENTICATED_EPERSON_SUCCESS: type('dspace/auth/RETRIEVE_AUTHENTICATED_EPERSON_SUCCESS'),
RETRIEVE_AUTHENTICATED_EPERSON_ERROR: type('dspace/auth/RETRIEVE_AUTHENTICATED_EPERSON_ERROR'),
Expand Down Expand Up @@ -361,6 +362,23 @@ export class SetRedirectUrlAction implements Action {
}
}

/**
* Change the redirect url.
* @class SetRedirectUrlAction
* @implements {Action}
*/
export class SetRedirectUrlAndNavigateAction implements Action {
public type: string = AuthActionTypes.SET_REDIRECT_URL_AND_NAVIGATE;
payload: {
redirectUrl: string;
navigateUrl: string;
};

constructor(redirectUrl: string, navigateUrl: string) {
this.payload = { redirectUrl, navigateUrl };
}
}

/**
* Start loading for a hard redirect
* @class StartHardRedirectLoadingAction
Expand Down
12 changes: 11 additions & 1 deletion src/app/core/auth/auth.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
NgZone,
Type,
} from '@angular/core';
import { Router } from '@angular/router';
import {
APP_CONFIG,
AppConfig,
Expand Down Expand Up @@ -70,6 +71,7 @@ import {
RetrieveAuthMethodsErrorAction,
RetrieveAuthMethodsSuccessAction,
RetrieveTokenAction,
SetRedirectUrlAndNavigateAction,
SetUserAsIdleAction,
} from './auth.actions';
// import services
Expand Down Expand Up @@ -160,6 +162,13 @@ export class AuthEffects {
}),
), { dispatch: false });

public redirectAndNavigate$: Observable<Action> = createEffect(() => this.actions$
.pipe(ofType(AuthActionTypes.SET_REDIRECT_URL_AND_NAVIGATE),
tap((action: SetRedirectUrlAndNavigateAction) => this.router.navigate([decodeURIComponent(action.payload.navigateUrl)])),
),
{ dispatch: false },
);

// It means "reacts to this action but don't send another"
public authenticatedError$: Observable<Action> = createEffect(() => this.actions$.pipe(
ofType(AuthActionTypes.AUTHENTICATED_ERROR),
Expand Down Expand Up @@ -332,6 +341,7 @@ export class AuthEffects {
private zone: NgZone,
private authorizationsService: AuthorizationDataService,
private authService: AuthService,
private store: Store<CoreState>) {
private store: Store<CoreState>,
private router: Router) {
}
}
6 changes: 6 additions & 0 deletions src/app/core/auth/auth.reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
RetrieveAuthMethodsSuccessAction,
SetAuthCookieStatus,
SetRedirectUrlAction,
SetRedirectUrlAndNavigateAction,
} from './auth.actions';
import { AuthMethod } from './models/auth.method';
import { AuthMethodType } from './models/auth.method-type';
Expand Down Expand Up @@ -245,6 +246,11 @@ export function authReducer(state: any = initialState, action: AuthActions): Aut
redirectUrl: (action as SetRedirectUrlAction).payload,
});

case AuthActionTypes.SET_REDIRECT_URL_AND_NAVIGATE:
return Object.assign({}, state, {
redirectUrl: (action as SetRedirectUrlAndNavigateAction).payload.redirectUrl,
});

case AuthActionTypes.REDIRECT_AFTER_LOGIN_SUCCESS:
return Object.assign({}, state, {
loading: true,
Expand Down
11 changes: 8 additions & 3 deletions src/app/core/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import {
ResetAuthenticationMessagesAction,
SetAuthCookieStatus,
SetRedirectUrlAction,
SetRedirectUrlAndNavigateAction,
SetUserAsIdleAction,
UnsetUserAsIdleAction,
} from './auth.actions';
Expand Down Expand Up @@ -579,15 +580,19 @@ export class AuthService {
/**
* Set redirect url
*/
setRedirectUrl(url: string) {
setRedirectUrl(redirectUrl: string, navigateUrl?: string) {
// Add 1 hour to the current date
const expireDate = Date.now() + (1000 * 60 * 60);

// Set the cookie expire date
const expires = new Date(expireDate);
const options: Cookies.CookieAttributes = { expires: expires };
this.storage.set(REDIRECT_COOKIE, url, options);
this.store.dispatch(new SetRedirectUrlAction(isNotUndefined(url) ? url : ''));
this.storage.set(REDIRECT_COOKIE, redirectUrl, options);
if (hasValue(navigateUrl)) {
this.store.dispatch(new SetRedirectUrlAndNavigateAction(isNotUndefined(redirectUrl) ? redirectUrl : '', navigateUrl));
} else {
this.store.dispatch(new SetRedirectUrlAction(isNotUndefined(redirectUrl) ? redirectUrl : ''));
}
}

/**
Expand Down
7 changes: 5 additions & 2 deletions src/app/core/shared/authorized.operators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,11 @@ export const redirectOn4xx = <T>(router: Router, authService: AuthService) =>
router.navigateByUrl(getForbiddenRoute(), { skipLocationChange: true });
return false;
} else {
authService.setRedirectUrl(router.url);
router.navigateByUrl('login');
// During a resolver the navigation hasn't committed yet, so router.url still
// points to the previous URL (e.g. '/'). Use the in-flight navigation's URL
// when available, falling back to router.url for component-level calls.
const redirectUrl = router.getCurrentNavigation()?.extractedUrl?.toString() ?? router.url;
authService.setRedirectUrl(redirectUrl, 'login');
return false;
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/app/core/shared/operators.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ describe('Core Module - RxJS Operators', () => {
testScheduler = new TestScheduler((actual, expected) => {
expect(actual).toEqual(expected);
});
router = jasmine.createSpyObj('router', ['navigateByUrl']);
router = jasmine.createSpyObj('router', ['navigateByUrl', 'getCurrentNavigation']);
authService = jasmine.createSpyObj('authService', {
isAuthenticated: of(true),
setRedirectUrl: {},
Expand Down Expand Up @@ -277,7 +277,6 @@ describe('Core Module - RxJS Operators', () => {
expectObservable(source.pipe(redirectOn4xx(router, authService))).toBe(expected, values);
flush();
expect(authService.setRedirectUrl).toHaveBeenCalled();
expect(router.navigateByUrl).toHaveBeenCalledWith('login');
});
});

Expand All @@ -291,7 +290,6 @@ describe('Core Module - RxJS Operators', () => {
expectObservable(source.pipe(redirectOn4xx(router, authService))).toBe(expected, values);
flush();
expect(authService.setRedirectUrl).toHaveBeenCalled();
expect(router.navigateByUrl).toHaveBeenCalledWith('login');
});
});
});
Expand Down
Loading