;
-let de: DebugElement;
-let el: HTMLElement;
const menuService = new MenuServiceStub();
describe('App component', () => {
@@ -52,7 +51,7 @@ describe('App component', () => {
return TestBed.configureTestingModule({
imports: [
CommonModule,
- StoreModule.forRoot({}, storeModuleConfig),
+ StoreModule.forRoot(authReducer, storeModuleConfig),
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
@@ -82,12 +81,19 @@ describe('App component', () => {
// synchronous beforeEach
beforeEach(() => {
- fixture = TestBed.createComponent(AppComponent);
+ spyOnProperty(ngrx, 'select').and.callFake(() => {
+ return () => {
+ return () => cold('a', {
+ a: {
+ core: { auth: { loading: false } }
+ }
+ })
+ };
+ });
+ fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance; // component test instance
- // query for the
by CSS element selector
- de = fixture.debugElement.query(By.css('div.outer-wrapper'));
- el = de.nativeElement;
+ fixture.detectChanges();
});
it('should create component', inject([AppComponent], (app: AppComponent) => {
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index 10f81a9adc..d5488be610 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,4 +1,4 @@
-import { delay, filter, map, take } from 'rxjs/operators';
+import { delay, filter, map, take, distinctUntilChanged } from 'rxjs/operators';
import {
AfterViewInit,
ChangeDetectionStrategy,
@@ -19,7 +19,7 @@ import { MetadataService } from './core/metadata/metadata.service';
import { HostWindowResizeAction } from './shared/host-window.actions';
import { HostWindowState } from './shared/search/host-window.reducer';
import { NativeWindowRef, NativeWindowService } from './core/services/window.service';
-import { isAuthenticated } from './core/auth/selectors';
+import { isAuthenticated, isAuthenticationLoading } from './core/auth/selectors';
import { AuthService } from './core/auth/auth.service';
import { CSSVariableService } from './shared/sass-helper/sass-helper.service';
import { MenuService } from './shared/menu/menu.service';
@@ -52,6 +52,11 @@ export class AppComponent implements OnInit, AfterViewInit {
notificationOptions = environment.notifications;
models;
+ /**
+ * Whether or not the authenticated has finished loading
+ */
+ hasAuthFinishedLoading$: Observable
;
+
constructor(
@Inject(NativeWindowService) private _window: NativeWindowRef,
private translate: TranslateService,
@@ -89,6 +94,10 @@ export class AppComponent implements OnInit, AfterViewInit {
}
ngOnInit() {
+ this.hasAuthFinishedLoading$ = this.store.pipe(select(isAuthenticationLoading)).pipe(
+ map((isLoading: boolean) => isLoading === false),
+ distinctUntilChanged()
+ );
const env: string = environment.production ? 'Production' : 'Development';
const color: string = environment.production ? 'red' : 'green';
console.info(`Environment: %c${env}`, `color: ${color}; font-weight: bold;`);
diff --git a/src/app/core/auth/auth.actions.ts b/src/app/core/auth/auth.actions.ts
index be4bdf2a26..f80be89034 100644
--- a/src/app/core/auth/auth.actions.ts
+++ b/src/app/core/auth/auth.actions.ts
@@ -34,6 +34,7 @@ export const AuthActionTypes = {
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'),
+ REDIRECT_AFTER_LOGIN_SUCCESS: type('dspace/auth/REDIRECT_AFTER_LOGIN_SUCCESS')
};
/* tslint:disable:max-classes-per-file */
@@ -335,6 +336,20 @@ export class SetRedirectUrlAction implements Action {
}
}
+/**
+ * Start loading for a hard redirect
+ * @class StartHardRedirectLoadingAction
+ * @implements {Action}
+ */
+export class RedirectAfterLoginSuccessAction implements Action {
+ public type: string = AuthActionTypes.REDIRECT_AFTER_LOGIN_SUCCESS;
+ payload: string;
+
+ constructor(url: string) {
+ this.payload = url;
+ }
+}
+
/**
* Retrieve the authenticated eperson.
* @class RetrieveAuthenticatedEpersonAction
@@ -402,8 +417,8 @@ export type AuthActions
| RetrieveAuthMethodsSuccessAction
| RetrieveAuthMethodsErrorAction
| RetrieveTokenAction
- | ResetAuthenticationMessagesAction
| RetrieveAuthenticatedEpersonAction
| RetrieveAuthenticatedEpersonErrorAction
| RetrieveAuthenticatedEpersonSuccessAction
- | SetRedirectUrlAction;
+ | SetRedirectUrlAction
+ | RedirectAfterLoginSuccessAction;
diff --git a/src/app/core/auth/auth.effects.ts b/src/app/core/auth/auth.effects.ts
index 7d1750c04e..ab18dcb508 100644
--- a/src/app/core/auth/auth.effects.ts
+++ b/src/app/core/auth/auth.effects.ts
@@ -27,6 +27,7 @@ import {
CheckAuthenticationTokenCookieAction,
LogOutErrorAction,
LogOutSuccessAction,
+ RedirectAfterLoginSuccessAction,
RefreshTokenAction,
RefreshTokenErrorAction,
RefreshTokenSuccessAction,
@@ -79,7 +80,26 @@ export class AuthEffects {
public authenticatedSuccess$: Observable = this.actions$.pipe(
ofType(AuthActionTypes.AUTHENTICATED_SUCCESS),
tap((action: AuthenticatedSuccessAction) => this.authService.storeToken(action.payload.authToken)),
- map((action: AuthenticatedSuccessAction) => new RetrieveAuthenticatedEpersonAction(action.payload.userHref))
+ switchMap((action: AuthenticatedSuccessAction) => this.authService.getRedirectUrl().pipe(
+ take(1),
+ map((redirectUrl: string) => [action, redirectUrl])
+ )),
+ map(([action, redirectUrl]: [AuthenticatedSuccessAction, string]) => {
+ if (hasValue(redirectUrl)) {
+ return new RedirectAfterLoginSuccessAction(redirectUrl);
+ } else {
+ return new RetrieveAuthenticatedEpersonAction(action.payload.userHref);
+ }
+ })
+ );
+
+ @Effect({ dispatch: false })
+ public redirectAfterLoginSuccess$: Observable = this.actions$.pipe(
+ ofType(AuthActionTypes.REDIRECT_AFTER_LOGIN_SUCCESS),
+ tap((action: RedirectAfterLoginSuccessAction) => {
+ this.authService.clearRedirectUrl();
+ this.authService.navigateToRedirectUrl(action.payload);
+ })
);
// It means "reacts to this action but don't send another"
diff --git a/src/app/core/auth/auth.reducer.ts b/src/app/core/auth/auth.reducer.ts
index 34c8fe2b41..0ffd7d0519 100644
--- a/src/app/core/auth/auth.reducer.ts
+++ b/src/app/core/auth/auth.reducer.ts
@@ -62,7 +62,7 @@ export interface AuthState {
const initialState: AuthState = {
authenticated: false,
loaded: false,
- loading: false,
+ loading: undefined,
authMethods: []
};
@@ -201,6 +201,11 @@ export function authReducer(state: any = initialState, action: AuthActions): Aut
redirectUrl: (action as SetRedirectUrlAction).payload,
});
+ case AuthActionTypes.REDIRECT_AFTER_LOGIN_SUCCESS:
+ return Object.assign({}, state, {
+ loading: true,
+ });
+
default:
return state;
}
diff --git a/src/app/core/auth/auth.service.spec.ts b/src/app/core/auth/auth.service.spec.ts
index ccc77bd413..be309b15fb 100644
--- a/src/app/core/auth/auth.service.spec.ts
+++ b/src/app/core/auth/auth.service.spec.ts
@@ -323,35 +323,30 @@ describe('AuthService test', () => {
});
it('should set redirect url to previous page', () => {
- spyOn(routeServiceMock, 'getHistory').and.callThrough();
- authService.redirectAfterLoginSuccess(true);
- expect(routeServiceMock.getHistory).toHaveBeenCalled();
+ (storage.get as jasmine.Spy).and.returnValue('/collection/123');
+ authService.redirectAfterLoginSuccess();
// Reload with redirect URL set to /collection/123
expect(hardRedirectService.redirect).toHaveBeenCalledWith(jasmine.stringMatching(new RegExp('/reload/[0-9]*\\?redirect=' + encodeURIComponent('/collection/123'))));
});
it('should set redirect url to current page', () => {
- spyOn(routeServiceMock, 'getHistory').and.callThrough();
- authService.redirectAfterLoginSuccess(false);
- expect(routeServiceMock.getHistory).toHaveBeenCalled();
+ (storage.get as jasmine.Spy).and.returnValue('/home');
+ authService.redirectAfterLoginSuccess();
// Reload with redirect URL set to /home
expect(hardRedirectService.redirect).toHaveBeenCalledWith(jasmine.stringMatching(new RegExp('/reload/[0-9]*\\?redirect=' + encodeURIComponent('/home'))));
});
- it('should redirect to / and not to /login', () => {
- spyOn(routeServiceMock, 'getHistory').and.returnValue(observableOf(['/login', '/login']));
- authService.redirectAfterLoginSuccess(true);
- expect(routeServiceMock.getHistory).toHaveBeenCalled();
+ it('should redirect to regular reload and not to /login', () => {
+ (storage.get as jasmine.Spy).and.returnValue('/login');
+ authService.redirectAfterLoginSuccess();
// Reload without a redirect URL
expect(hardRedirectService.redirect).toHaveBeenCalledWith(jasmine.stringMatching(new RegExp('/reload/[0-9]*(?!\\?)$')));
});
- it('should redirect to / when no redirect url is found', () => {
- spyOn(routeServiceMock, 'getHistory').and.returnValue(observableOf(['']));
- authService.redirectAfterLoginSuccess(true);
- expect(routeServiceMock.getHistory).toHaveBeenCalled();
+ it('should not redirect when no redirect url is found', () => {
+ authService.redirectAfterLoginSuccess();
// Reload without a redirect URL
- expect(hardRedirectService.redirect).toHaveBeenCalledWith(jasmine.stringMatching(new RegExp('/reload/[0-9]*(?!\\?)$')));
+ expect(hardRedirectService.redirect).not.toHaveBeenCalled();
});
describe('impersonate', () => {
diff --git a/src/app/core/auth/auth.service.ts b/src/app/core/auth/auth.service.ts
index b8e6c6609a..f79ae5d0fd 100644
--- a/src/app/core/auth/auth.service.ts
+++ b/src/app/core/auth/auth.service.ts
@@ -14,7 +14,15 @@ import { AuthRequestService } from './auth-request.service';
import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service';
import { AuthStatus } from './models/auth-status.model';
import { AuthTokenInfo, TOKENITEM } from './models/auth-token-info.model';
-import { hasValue, hasValueOperator, isEmpty, isNotEmpty, isNotNull, isNotUndefined } from '../../shared/empty.util';
+import {
+ hasValue,
+ hasValueOperator,
+ isEmpty,
+ isNotEmpty,
+ isNotNull,
+ isNotUndefined,
+ hasNoValue
+} from '../../shared/empty.util';
import { CookieService } from '../services/cookie.service';
import {
getAuthenticatedUserId,
@@ -413,35 +421,19 @@ export class AuthService {
/**
* Redirect to the route navigated before the login
*/
- public redirectAfterLoginSuccess(isStandalonePage: boolean) {
+ public redirectAfterLoginSuccess() {
this.getRedirectUrl().pipe(
take(1))
.subscribe((redirectUrl) => {
-
- if (isNotEmpty(redirectUrl)) {
+ if (hasValue(redirectUrl)) {
this.clearRedirectUrl();
- this.router.onSameUrlNavigation = 'reload';
this.navigateToRedirectUrl(redirectUrl);
- } else {
- // If redirectUrl is empty use history.
- this.routeService.getHistory().pipe(
- take(1)
- ).subscribe((history) => {
- let redirUrl;
- if (isStandalonePage) {
- // For standalone login pages, use the previous route.
- redirUrl = history[history.length - 2] || '';
- } else {
- redirUrl = history[history.length - 1] || '';
- }
- this.navigateToRedirectUrl(redirUrl);
- });
}
});
}
- protected navigateToRedirectUrl(redirectUrl: string) {
+ public navigateToRedirectUrl(redirectUrl: string) {
let url = `/reload/${new Date().getTime()}`;
if (isNotEmpty(redirectUrl) && !redirectUrl.startsWith(LOGIN_ROUTE)) {
url += `?redirect=${encodeURIComponent(redirectUrl)}`;
@@ -460,12 +452,16 @@ export class AuthService {
* Get redirect url
*/
getRedirectUrl(): Observable {
- const redirectUrl = this.storage.get(REDIRECT_COOKIE);
- if (isNotEmpty(redirectUrl)) {
- return observableOf(redirectUrl);
- } else {
- return this.store.pipe(select(getRedirectUrl));
- }
+ return this.store.pipe(
+ select(getRedirectUrl),
+ map((urlFromStore: string) => {
+ if (hasValue(urlFromStore)) {
+ return urlFromStore;
+ } else {
+ return this.storage.get(REDIRECT_COOKIE);
+ }
+ })
+ );
}
/**
@@ -482,6 +478,16 @@ export class AuthService {
this.store.dispatch(new SetRedirectUrlAction(isNotUndefined(url) ? url : ''));
}
+ setRedirectUrlIfNotSet(newRedirectUrl: string) {
+ this.getRedirectUrl().pipe(
+ take(1))
+ .subscribe((currentRedirectUrl) => {
+ if (hasNoValue(currentRedirectUrl)) {
+ this.setRedirectUrl(newRedirectUrl);
+ }
+ })
+ }
+
/**
* Clear redirect url
*/
diff --git a/src/app/core/auth/authenticated.guard.ts b/src/app/core/auth/authenticated.guard.ts
index 2e70a70310..4feb6ebce0 100644
--- a/src/app/core/auth/authenticated.guard.ts
+++ b/src/app/core/auth/authenticated.guard.ts
@@ -9,11 +9,11 @@ import {
} from '@angular/router';
import { Observable } from 'rxjs';
-import { map } from 'rxjs/operators';
+import { map, find, switchMap } from 'rxjs/operators';
import { select, Store } from '@ngrx/store';
import { CoreState } from '../core.reducers';
-import { isAuthenticated } from './selectors';
+import { isAuthenticated, isAuthenticationLoading } from './selectors';
import { AuthService, LOGIN_ROUTE } from './auth.service';
/**
@@ -48,11 +48,10 @@ export class AuthenticatedGuard implements CanActivate {
}
private handleAuth(url: string): Observable {
- // get observable
- const observable = this.store.pipe(select(isAuthenticated));
-
// redirect to sign in page if user is not authenticated
- return observable.pipe(
+ return this.store.pipe(select(isAuthenticationLoading)).pipe(
+ find((isLoading: boolean) => isLoading === false),
+ switchMap(() => this.store.pipe(select(isAuthenticated))),
map((authenticated) => {
if (authenticated) {
return authenticated;
diff --git a/src/app/core/auth/server-auth.service.ts b/src/app/core/auth/server-auth.service.ts
index 7b78255001..84a74548ce 100644
--- a/src/app/core/auth/server-auth.service.ts
+++ b/src/app/core/auth/server-auth.service.ts
@@ -58,32 +58,4 @@ export class ServerAuthService extends AuthService {
map((status: AuthStatus) => Object.assign(new AuthStatus(), status))
);
}
-
- /**
- * Redirect to the route navigated before the login
- */
- public redirectAfterLoginSuccess(isStandalonePage: boolean) {
- this.getRedirectUrl().pipe(
- take(1))
- .subscribe((redirectUrl) => {
- if (isNotEmpty(redirectUrl)) {
- // override the route reuse strategy
- this.router.routeReuseStrategy.shouldReuseRoute = () => {
- return false;
- };
- this.router.navigated = false;
- const url = decodeURIComponent(redirectUrl);
- this.router.navigateByUrl(url);
- } else {
- // If redirectUrl is empty use history. For ssr the history array should contain the requested url.
- this.routeService.getHistory().pipe(
- filter((history) => history.length > 0),
- take(1)
- ).subscribe((history) => {
- this.navigateToRedirectUrl(history[history.length - 1] || '');
- });
- }
- })
- }
-
}
diff --git a/src/app/core/services/browser-hard-redirect.service.spec.ts b/src/app/core/services/browser-hard-redirect.service.spec.ts
index b94b52d46e..7eb2c6f494 100644
--- a/src/app/core/services/browser-hard-redirect.service.spec.ts
+++ b/src/app/core/services/browser-hard-redirect.service.spec.ts
@@ -5,7 +5,8 @@ describe('BrowserHardRedirectService', () => {
const mockLocation = {
href: undefined,
- origin: 'test origin',
+ pathname: '/pathname',
+ search: '/search',
} as Location;
const service: BrowserHardRedirectService = new BrowserHardRedirectService(mockLocation);
@@ -31,10 +32,10 @@ describe('BrowserHardRedirectService', () => {
})
});
- describe('when requesting the origin', () => {
+ describe('when requesting the current route', () => {
it('should return the location origin', () => {
- expect(service.getOriginFromUrl()).toEqual('test origin');
+ expect(service.getCurrentRoute()).toEqual(mockLocation.pathname + mockLocation.search);
});
});
});
diff --git a/src/app/core/services/browser-hard-redirect.service.ts b/src/app/core/services/browser-hard-redirect.service.ts
index 71ce7577d2..725848212f 100644
--- a/src/app/core/services/browser-hard-redirect.service.ts
+++ b/src/app/core/services/browser-hard-redirect.service.ts
@@ -1,11 +1,12 @@
-import {Inject, Injectable} from '@angular/core';
-import {LocationToken} from '../../../modules/app/browser-app.module';
+import { Inject, Injectable } from '@angular/core';
+import { LocationToken } from '../../../modules/app/browser-app.module';
+import { HardRedirectService } from './hard-redirect.service';
/**
* Service for performing hard redirects within the browser app module
*/
@Injectable()
-export class BrowserHardRedirectService {
+export class BrowserHardRedirectService implements HardRedirectService {
constructor(
@Inject(LocationToken) protected location: Location,
@@ -23,7 +24,7 @@ export class BrowserHardRedirectService {
/**
* Get the origin of a request
*/
- getOriginFromUrl() {
- return this.location.origin;
+ getCurrentRoute() {
+ return this.location.pathname + this.location.search;
}
}
diff --git a/src/app/core/services/hard-redirect.service.ts b/src/app/core/services/hard-redirect.service.ts
index e2c18b6138..09757a1250 100644
--- a/src/app/core/services/hard-redirect.service.ts
+++ b/src/app/core/services/hard-redirect.service.ts
@@ -15,7 +15,8 @@ export abstract class HardRedirectService {
abstract redirect(url: string);
/**
- * Get the origin of a request
+ * Get the current route, with query params included
+ * e.g. /search?page=1&query=open%20access&f.dateIssued.min=1980&f.dateIssued.max=2020
*/
- abstract getOriginFromUrl();
+ abstract getCurrentRoute();
}
diff --git a/src/app/core/services/server-hard-redirect.service.spec.ts b/src/app/core/services/server-hard-redirect.service.spec.ts
index 9704c64c74..2d09c21eb9 100644
--- a/src/app/core/services/server-hard-redirect.service.spec.ts
+++ b/src/app/core/services/server-hard-redirect.service.spec.ts
@@ -30,19 +30,14 @@ describe('ServerHardRedirectService', () => {
})
});
- describe('when requesting the origin', () => {
+ describe('when requesting the current route', () => {
beforeEach(() => {
- mockRequest.protocol = 'test-protocol';
- mockRequest.get.and.callFake((name) => {
- if (name === 'hostname') {
- return 'test-host';
- }
- });
+ mockRequest.originalUrl = 'original/url';
});
it('should return the location origin', () => {
- expect(service.getOriginFromUrl()).toEqual('test-protocol://test-host');
+ expect(service.getCurrentRoute()).toEqual(mockRequest.originalUrl);
});
});
});
diff --git a/src/app/core/services/server-hard-redirect.service.ts b/src/app/core/services/server-hard-redirect.service.ts
index 69b6739445..79755d2dc9 100644
--- a/src/app/core/services/server-hard-redirect.service.ts
+++ b/src/app/core/services/server-hard-redirect.service.ts
@@ -1,12 +1,13 @@
import { Inject, Injectable } from '@angular/core';
import { Request, Response } from 'express';
import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens';
+import { HardRedirectService } from './hard-redirect.service';
/**
* Service for performing hard redirects within the server app module
*/
@Injectable()
-export class ServerHardRedirectService {
+export class ServerHardRedirectService implements HardRedirectService {
constructor(
@Inject(REQUEST) protected req: Request,
@@ -55,8 +56,7 @@ export class ServerHardRedirectService {
/**
* Get the origin of a request
*/
- getOriginFromUrl() {
-
- return new URL(`${this.req.protocol}://${this.req.get('hostname')}`).toString();
+ getCurrentRoute() {
+ return this.req.originalUrl;
}
}
diff --git a/src/app/shared/log-in/container/log-in-container.component.spec.ts b/src/app/shared/log-in/container/log-in-container.component.spec.ts
index 41673cc773..aa4888104f 100644
--- a/src/app/shared/log-in/container/log-in-container.component.spec.ts
+++ b/src/app/shared/log-in/container/log-in-container.component.spec.ts
@@ -12,6 +12,7 @@ import { AuthService } from '../../../core/auth/auth.service';
import { AuthMethod } from '../../../core/auth/models/auth.method';
import { AuthServiceStub } from '../../testing/auth-service.stub';
import { createTestComponent } from '../../testing/utils.test';
+import { HardRedirectService } from '../../../core/services/hard-redirect.service';
describe('LogInContainerComponent', () => {
@@ -20,7 +21,13 @@ describe('LogInContainerComponent', () => {
const authMethod = new AuthMethod('password');
+ let hardRedirectService: HardRedirectService;
+
beforeEach(async(() => {
+ hardRedirectService = jasmine.createSpyObj('hardRedirectService', {
+ redirect: {},
+ getCurrentRoute: {}
+ });
// refine the test module by declaring the test component
TestBed.configureTestingModule({
imports: [
@@ -35,6 +42,7 @@ describe('LogInContainerComponent', () => {
],
providers: [
{provide: AuthService, useClass: AuthServiceStub},
+ { provide: HardRedirectService, useValue: hardRedirectService },
LogInContainerComponent
],
schemas: [
diff --git a/src/app/shared/log-in/log-in.component.spec.ts b/src/app/shared/log-in/log-in.component.spec.ts
index a9a42bf3dd..2536949849 100644
--- a/src/app/shared/log-in/log-in.component.spec.ts
+++ b/src/app/shared/log-in/log-in.component.spec.ts
@@ -18,6 +18,7 @@ import { NativeWindowService } from '../../core/services/window.service';
import { provideMockStore } from '@ngrx/store/testing';
import { createTestComponent } from '../testing/utils.test';
import { RouterTestingModule } from '@angular/router/testing';
+import { HardRedirectService } from '../../core/services/hard-redirect.service';
describe('LogInComponent', () => {
@@ -33,8 +34,13 @@ describe('LogInComponent', () => {
}
}
};
+ let hardRedirectService: HardRedirectService;
beforeEach(async(() => {
+ hardRedirectService = jasmine.createSpyObj('hardRedirectService', {
+ redirect: {},
+ getCurrentRoute: {}
+ });
// refine the test module by declaring the test component
TestBed.configureTestingModule({
imports: [
@@ -58,6 +64,7 @@ describe('LogInComponent', () => {
{ provide: NativeWindowService, useFactory: NativeWindowMockFactory },
// { provide: Router, useValue: new RouterStub() },
{ provide: ActivatedRoute, useValue: new ActivatedRouteStub() },
+ { provide: HardRedirectService, useValue: hardRedirectService },
provideMockStore({ initialState }),
LogInComponent
],
diff --git a/src/app/shared/log-in/log-in.component.ts b/src/app/shared/log-in/log-in.component.ts
index 32e10fef45..301eb1736b 100644
--- a/src/app/shared/log-in/log-in.component.ts
+++ b/src/app/shared/log-in/log-in.component.ts
@@ -1,13 +1,9 @@
-import { Component, Input, OnDestroy, OnInit } from '@angular/core';
-
+import { Component, Input, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
-import { filter, takeWhile, } from 'rxjs/operators';
import { select, Store } from '@ngrx/store';
-
import { AuthMethod } from '../../core/auth/models/auth.method';
import { getAuthenticationMethods, isAuthenticated, isAuthenticationLoading } from '../../core/auth/selectors';
import { CoreState } from '../../core/core.reducers';
-import { AuthService } from '../../core/auth/auth.service';
import { getForgotPasswordPath, getRegisterPath } from '../../app-routing.module';
/**
@@ -19,7 +15,7 @@ import { getForgotPasswordPath, getRegisterPath } from '../../app-routing.module
templateUrl: './log-in.component.html',
styleUrls: ['./log-in.component.scss']
})
-export class LogInComponent implements OnInit, OnDestroy {
+export class LogInComponent implements OnInit {
/**
* A boolean representing if LogInComponent is in a standalone page
@@ -45,14 +41,7 @@ export class LogInComponent implements OnInit, OnDestroy {
*/
public loading: Observable;
- /**
- * Component state.
- * @type {boolean}
- */
- private alive = true;
-
- constructor(private store: Store,
- private authService: AuthService,) {
+ constructor(private store: Store) {
}
ngOnInit(): void {
@@ -66,21 +55,6 @@ export class LogInComponent implements OnInit, OnDestroy {
// set isAuthenticated
this.isAuthenticated = this.store.pipe(select(isAuthenticated));
-
- // subscribe to success
- this.store.pipe(
- select(isAuthenticated),
- takeWhile(() => this.alive),
- filter((authenticated) => authenticated))
- .subscribe(() => {
- this.authService.redirectAfterLoginSuccess(this.isStandalonePage);
- }
- );
-
- }
-
- ngOnDestroy(): void {
- this.alive = false;
}
getRegisterPath() {
diff --git a/src/app/shared/log-in/methods/password/log-in-password.component.spec.ts b/src/app/shared/log-in/methods/password/log-in-password.component.spec.ts
index 68c939d1bc..cac1052238 100644
--- a/src/app/shared/log-in/methods/password/log-in-password.component.spec.ts
+++ b/src/app/shared/log-in/methods/password/log-in-password.component.spec.ts
@@ -15,6 +15,7 @@ import { AuthServiceStub } from '../../../testing/auth-service.stub';
import { AppState } from '../../../../app.reducer';
import { AuthMethod } from '../../../../core/auth/models/auth.method';
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
+import { HardRedirectService } from '../../../../core/services/hard-redirect.service';
describe('LogInPasswordComponent', () => {
@@ -29,8 +30,14 @@ describe('LogInPasswordComponent', () => {
loading: false,
};
+ let hardRedirectService: HardRedirectService;
+
beforeEach(() => {
user = EPersonMock;
+
+ hardRedirectService = jasmine.createSpyObj('hardRedirectService', {
+ getCurrentRoute: {}
+ });
});
beforeEach(async(() => {
@@ -47,7 +54,8 @@ describe('LogInPasswordComponent', () => {
],
providers: [
{ provide: AuthService, useClass: AuthServiceStub },
- { provide: 'authMethodProvider', useValue: new AuthMethod(AuthMethodType.Password) }
+ { provide: 'authMethodProvider', useValue: new AuthMethod(AuthMethodType.Password) },
+ { provide: HardRedirectService, useValue: hardRedirectService },
],
schemas: [
CUSTOM_ELEMENTS_SCHEMA
diff --git a/src/app/shared/log-in/methods/password/log-in-password.component.ts b/src/app/shared/log-in/methods/password/log-in-password.component.ts
index 8b0dd8cc04..1d144a280e 100644
--- a/src/app/shared/log-in/methods/password/log-in-password.component.ts
+++ b/src/app/shared/log-in/methods/password/log-in-password.component.ts
@@ -13,6 +13,8 @@ import { fadeOut } from '../../../animations/fade';
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
import { renderAuthMethodFor } from '../log-in.methods-decorator';
import { AuthMethod } from '../../../../core/auth/models/auth.method';
+import { AuthService } from '../../../../core/auth/auth.service';
+import { HardRedirectService } from '../../../../core/services/hard-redirect.service';
/**
* /users/sign-in
@@ -66,11 +68,15 @@ export class LogInPasswordComponent implements OnInit {
/**
* @constructor
* @param {AuthMethod} injectedAuthMethodModel
+ * @param {AuthService} authService
+ * @param {HardRedirectService} hardRedirectService
* @param {FormBuilder} formBuilder
* @param {Store} store
*/
constructor(
@Inject('authMethodProvider') public injectedAuthMethodModel: AuthMethod,
+ private authService: AuthService,
+ private hardRedirectService: HardRedirectService,
private formBuilder: FormBuilder,
private store: Store
) {
@@ -134,6 +140,8 @@ export class LogInPasswordComponent implements OnInit {
email.trim();
password.trim();
+ this.authService.setRedirectUrlIfNotSet(this.hardRedirectService.getCurrentRoute());
+
// dispatch AuthenticationAction
this.store.dispatch(new AuthenticateAction(email, password));
diff --git a/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.spec.ts b/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.spec.ts
index 7c1e782ee0..b029ec63f2 100644
--- a/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.spec.ts
+++ b/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.spec.ts
@@ -17,6 +17,7 @@ import { NativeWindowService } from '../../../../core/services/window.service';
import { RouterStub } from '../../../testing/router.stub';
import { ActivatedRouteStub } from '../../../testing/active-router.stub';
import { NativeWindowMockFactory } from '../../../mocks/mock-native-window-ref';
+import { HardRedirectService } from '../../../../core/services/hard-redirect.service';
describe('LogInShibbolethComponent', () => {
@@ -30,6 +31,7 @@ describe('LogInShibbolethComponent', () => {
let location;
let authState;
+ let hardRedirectService: HardRedirectService;
beforeEach(() => {
user = EPersonMock;
@@ -41,6 +43,10 @@ describe('LogInShibbolethComponent', () => {
loaded: false,
loading: false,
};
+
+ hardRedirectService = jasmine.createSpyObj('hardRedirectService', {
+ getCurrentRoute: {}
+ });
});
beforeEach(async(() => {
@@ -59,6 +65,7 @@ describe('LogInShibbolethComponent', () => {
{ provide: NativeWindowService, useFactory: NativeWindowMockFactory },
{ provide: Router, useValue: new RouterStub() },
{ provide: ActivatedRoute, useValue: new ActivatedRouteStub() },
+ { provide: HardRedirectService, useValue: hardRedirectService },
],
schemas: [
CUSTOM_ELEMENTS_SCHEMA
diff --git a/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.ts b/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.ts
index 6321e6119f..bb5791bd60 100644
--- a/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.ts
+++ b/src/app/shared/log-in/methods/shibboleth/log-in-shibboleth.component.ts
@@ -12,6 +12,8 @@ import { isAuthenticated, isAuthenticationLoading } from '../../../../core/auth/
import { RouteService } from '../../../../core/services/route.service';
import { NativeWindowRef, NativeWindowService } from '../../../../core/services/window.service';
import { isNotNull } from '../../../empty.util';
+import { AuthService } from '../../../../core/auth/auth.service';
+import { HardRedirectService } from '../../../../core/services/hard-redirect.service';
@Component({
selector: 'ds-log-in-shibboleth',
@@ -51,12 +53,16 @@ export class LogInShibbolethComponent implements OnInit {
* @param {AuthMethod} injectedAuthMethodModel
* @param {NativeWindowRef} _window
* @param {RouteService} route
+ * @param {AuthService} authService
+ * @param {HardRedirectService} hardRedirectService
* @param {Store} store
*/
constructor(
@Inject('authMethodProvider') public injectedAuthMethodModel: AuthMethod,
@Inject(NativeWindowService) protected _window: NativeWindowRef,
private route: RouteService,
+ private authService: AuthService,
+ private hardRedirectService: HardRedirectService,
private store: Store
) {
this.authMethod = injectedAuthMethodModel;
@@ -75,6 +81,7 @@ export class LogInShibbolethComponent implements OnInit {
}
redirectToShibboleth() {
+ this.authService.setRedirectUrlIfNotSet(this.hardRedirectService.getCurrentRoute())
let newLocationUrl = this.location;
const currentUrl = this._window.nativeWindow.location.href;
const myRegexp = /\?redirectUrl=(.*)/g;
diff --git a/src/app/shared/testing/auth-service.stub.ts b/src/app/shared/testing/auth-service.stub.ts
index 7e7e70a754..2f1e9e3bac 100644
--- a/src/app/shared/testing/auth-service.stub.ts
+++ b/src/app/shared/testing/auth-service.stub.ts
@@ -154,4 +154,12 @@ export class AuthServiceStub {
resetAuthenticationError() {
return;
}
+
+ setRedirectUrlIfNotSet(url: string) {
+ return;
+ }
+
+ redirectAfterLoginSuccess() {
+ return;
+ }
}
diff --git a/src/modules/app/browser-app.module.ts b/src/modules/app/browser-app.module.ts
index 44f00fbae4..7306e7db6c 100644
--- a/src/modules/app/browser-app.module.ts
+++ b/src/modules/app/browser-app.module.ts
@@ -40,7 +40,6 @@ export function locationProvider(): Location {
return window.location;
}
-
@NgModule({
bootstrap: [AppComponent],
imports: [