forked from hazza/dspace-angular
Refactored components' name and added missing tests
This commit is contained in:
@@ -7,7 +7,7 @@ import { type } from '../../shared/ngrx/type';
|
|||||||
// import models
|
// import models
|
||||||
import { EPerson } from '../eperson/models/eperson.model';
|
import { EPerson } from '../eperson/models/eperson.model';
|
||||||
import { AuthTokenInfo } from './models/auth-token-info.model';
|
import { AuthTokenInfo } from './models/auth-token-info.model';
|
||||||
import { AuthMethodModel } from './models/auth-method.model';
|
import { AuthMethod } from './models/auth.method';
|
||||||
import { AuthStatus } from './models/auth-status.model';
|
import { AuthStatus } from './models/auth-status.model';
|
||||||
|
|
||||||
export const AuthActionTypes = {
|
export const AuthActionTypes = {
|
||||||
@@ -340,9 +340,9 @@ export class RetrieveAuthMethodsAction implements Action {
|
|||||||
*/
|
*/
|
||||||
export class RetrieveAuthMethodsSuccessAction implements Action {
|
export class RetrieveAuthMethodsSuccessAction implements Action {
|
||||||
public type: string = AuthActionTypes.RETRIEVE_AUTH_METHODS_SUCCESS;
|
public type: string = AuthActionTypes.RETRIEVE_AUTH_METHODS_SUCCESS;
|
||||||
payload: AuthMethodModel[];
|
payload: AuthMethod[];
|
||||||
|
|
||||||
constructor(authMethods: AuthMethodModel[] ) {
|
constructor(authMethods: AuthMethod[] ) {
|
||||||
this.payload = authMethods;
|
this.payload = authMethods;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,13 +18,14 @@ import {
|
|||||||
LogOutErrorAction,
|
LogOutErrorAction,
|
||||||
LogOutSuccessAction,
|
LogOutSuccessAction,
|
||||||
RefreshTokenErrorAction,
|
RefreshTokenErrorAction,
|
||||||
RefreshTokenSuccessAction
|
RefreshTokenSuccessAction, RetrieveAuthMethodsAction, RetrieveAuthMethodsErrorAction, RetrieveAuthMethodsSuccessAction
|
||||||
} from './auth.actions';
|
} from './auth.actions';
|
||||||
import { AuthServiceStub } from '../../shared/testing/auth-service-stub';
|
import { authMethodsMock, AuthServiceStub } from '../../shared/testing/auth-service-stub';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
import { AuthState } from './auth.reducer';
|
import { AuthState } from './auth.reducer';
|
||||||
|
|
||||||
import { EPersonMock } from '../../shared/testing/eperson-mock';
|
import { EPersonMock } from '../../shared/testing/eperson-mock';
|
||||||
|
import { AuthStatus } from './models/auth-status.model';
|
||||||
|
|
||||||
describe('AuthEffects', () => {
|
describe('AuthEffects', () => {
|
||||||
let authEffects: AuthEffects;
|
let authEffects: AuthEffects;
|
||||||
@@ -153,6 +154,49 @@ describe('AuthEffects', () => {
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('checkTokenCookie$', () => {
|
||||||
|
|
||||||
|
describe('when check token succeeded', () => {
|
||||||
|
it('should return a AUTHENTICATED action in response to a CHECK_AUTHENTICATION_TOKEN_COOKIE action when authenticated is true', () => {
|
||||||
|
spyOn((authEffects as any).authService, 'checkAuthenticationCookie').and.returnValue(
|
||||||
|
observableOf(
|
||||||
|
{ authenticated: true,
|
||||||
|
token
|
||||||
|
})
|
||||||
|
);
|
||||||
|
actions = hot('--a-', {a: {type: AuthActionTypes.CHECK_AUTHENTICATION_TOKEN_COOKIE}});
|
||||||
|
|
||||||
|
const expected = cold('--b-', {b: new AuthenticatedAction(token)});
|
||||||
|
|
||||||
|
expect(authEffects.checkTokenCookie$).toBeObservable(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a RETRIEVE_AUTH_METHODS action in response to a CHECK_AUTHENTICATION_TOKEN_COOKIE action when authenticated is false', () => {
|
||||||
|
spyOn((authEffects as any).authService, 'checkAuthenticationCookie').and.returnValue(
|
||||||
|
observableOf(
|
||||||
|
{ authenticated: false })
|
||||||
|
);
|
||||||
|
actions = hot('--a-', {a: {type: AuthActionTypes.CHECK_AUTHENTICATION_TOKEN_COOKIE}});
|
||||||
|
|
||||||
|
const expected = cold('--b-', {b: new RetrieveAuthMethodsAction({ authenticated: false } as AuthStatus)});
|
||||||
|
|
||||||
|
expect(authEffects.checkTokenCookie$).toBeObservable(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when check token failed', () => {
|
||||||
|
it('should return a AUTHENTICATED_ERROR action in response to a CHECK_AUTHENTICATION_TOKEN_COOKIE action', () => {
|
||||||
|
spyOn((authEffects as any).authService, 'checkAuthenticationCookie').and.returnValue(observableThrow(new Error('Message Error test')));
|
||||||
|
|
||||||
|
actions = hot('--a-', {a: {type: AuthActionTypes.CHECK_AUTHENTICATION_TOKEN_COOKIE, payload: token}});
|
||||||
|
|
||||||
|
const expected = cold('--b-', {b: new AuthenticatedErrorAction(new Error('Message Error test'))});
|
||||||
|
|
||||||
|
expect(authEffects.checkTokenCookie$).toBeObservable(expected);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
describe('refreshToken$', () => {
|
describe('refreshToken$', () => {
|
||||||
|
|
||||||
describe('when refresh token succeeded', () => {
|
describe('when refresh token succeeded', () => {
|
||||||
@@ -204,4 +248,30 @@ describe('AuthEffects', () => {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('retrieveMethods$', () => {
|
||||||
|
|
||||||
|
describe('when retrieve authentication methods succeeded', () => {
|
||||||
|
it('should return a RETRIEVE_AUTH_METHODS_SUCCESS action in response to a RETRIEVE_AUTH_METHODS action', () => {
|
||||||
|
|
||||||
|
actions = hot('--a-', {a: {type: AuthActionTypes.RETRIEVE_AUTH_METHODS}});
|
||||||
|
|
||||||
|
const expected = cold('--b-', {b: new RetrieveAuthMethodsSuccessAction(authMethodsMock)});
|
||||||
|
|
||||||
|
expect(authEffects.retrieveMethods$).toBeObservable(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when retrieve authentication methods failed', () => {
|
||||||
|
it('should return a RETRIEVE_AUTH_METHODS_ERROR action in response to a RETRIEVE_AUTH_METHODS action', () => {
|
||||||
|
spyOn((authEffects as any).authService, 'retrieveAuthMethods').and.returnValue(observableThrow(''));
|
||||||
|
|
||||||
|
actions = hot('--a-', {a: {type: AuthActionTypes.RETRIEVE_AUTH_METHODS}});
|
||||||
|
|
||||||
|
const expected = cold('--b-', {b: new RetrieveAuthMethodsErrorAction()});
|
||||||
|
|
||||||
|
expect(authEffects.retrieveMethods$).toBeObservable(expected);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -2,9 +2,11 @@ import { Observable, of as observableOf } from 'rxjs';
|
|||||||
|
|
||||||
import { catchError, debounceTime, filter, map, switchMap, take, tap } from 'rxjs/operators';
|
import { catchError, debounceTime, filter, map, switchMap, take, tap } from 'rxjs/operators';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
// import @ngrx
|
// import @ngrx
|
||||||
import { Actions, Effect, ofType } from '@ngrx/effects';
|
import { Actions, Effect, ofType } from '@ngrx/effects';
|
||||||
import { Action, select, Store } from '@ngrx/store';
|
import { Action, select, Store } from '@ngrx/store';
|
||||||
|
|
||||||
// import services
|
// import services
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
// import actions
|
// import actions
|
||||||
@@ -35,7 +37,7 @@ import { AuthTokenInfo } from './models/auth-token-info.model';
|
|||||||
import { AppState } from '../../app.reducer';
|
import { AppState } from '../../app.reducer';
|
||||||
import { isAuthenticated } from './selectors';
|
import { isAuthenticated } from './selectors';
|
||||||
import { StoreActionTypes } from '../../store.actions';
|
import { StoreActionTypes } from '../../store.actions';
|
||||||
import { AuthMethodModel } from './models/auth-method.model';
|
import { AuthMethod } from './models/auth.method';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthEffects {
|
export class AuthEffects {
|
||||||
@@ -91,7 +93,7 @@ export class AuthEffects {
|
|||||||
);
|
);
|
||||||
|
|
||||||
@Effect()
|
@Effect()
|
||||||
public checkTokenError$: Observable<Action> = this.actions$.pipe(
|
public checkTokenCookie$: Observable<Action> = this.actions$.pipe(
|
||||||
ofType(AuthActionTypes.CHECK_AUTHENTICATION_TOKEN_COOKIE),
|
ofType(AuthActionTypes.CHECK_AUTHENTICATION_TOKEN_COOKIE),
|
||||||
switchMap(() => {
|
switchMap(() => {
|
||||||
return this.authService.checkAuthenticationCookie().pipe(
|
return this.authService.checkAuthenticationCookie().pipe(
|
||||||
@@ -195,7 +197,7 @@ export class AuthEffects {
|
|||||||
switchMap((action: RetrieveAuthMethodsAction) => {
|
switchMap((action: RetrieveAuthMethodsAction) => {
|
||||||
return this.authService.retrieveAuthMethods(action.payload)
|
return this.authService.retrieveAuthMethods(action.payload)
|
||||||
.pipe(
|
.pipe(
|
||||||
map((authMethodModels: AuthMethodModel[]) => new RetrieveAuthMethodsSuccessAction(authMethodModels)),
|
map((authMethodModels: AuthMethod[]) => new RetrieveAuthMethodsSuccessAction(authMethodModels)),
|
||||||
catchError((error) => observableOf(new RetrieveAuthMethodsErrorAction()))
|
catchError((error) => observableOf(new RetrieveAuthMethodsErrorAction()))
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@@ -22,8 +22,8 @@ import { isNotEmpty, isNotNull, isUndefined } from '../../shared/empty.util';
|
|||||||
import { RedirectWhenTokenExpiredAction, RefreshTokenAction } from './auth.actions';
|
import { RedirectWhenTokenExpiredAction, RefreshTokenAction } from './auth.actions';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { AuthMethodModel } from './models/auth-method.model';
|
import { AuthMethod } from './models/auth.method';
|
||||||
import { AuthMethodType } from '../../shared/log-in/methods/authMethods-type';
|
import { AuthMethodType } from './models/auth.method-type';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthInterceptor implements HttpInterceptor {
|
export class AuthInterceptor implements HttpInterceptor {
|
||||||
@@ -36,15 +36,30 @@ export class AuthInterceptor implements HttpInterceptor {
|
|||||||
constructor(private inj: Injector, private router: Router, private store: Store<AppState>) {
|
constructor(private inj: Injector, private router: Router, private store: Store<AppState>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if response status code is 401
|
||||||
|
*
|
||||||
|
* @param response
|
||||||
|
*/
|
||||||
private isUnauthorized(response: HttpResponseBase): boolean {
|
private isUnauthorized(response: HttpResponseBase): boolean {
|
||||||
// invalid_token The access token provided is expired, revoked, malformed, or invalid for other reasons
|
// invalid_token The access token provided is expired, revoked, malformed, or invalid for other reasons
|
||||||
return response.status === 401;
|
return response.status === 401;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if response status code is 200 or 204
|
||||||
|
*
|
||||||
|
* @param response
|
||||||
|
*/
|
||||||
private isSuccess(response: HttpResponseBase): boolean {
|
private isSuccess(response: HttpResponseBase): boolean {
|
||||||
return (response.status === 200 || response.status === 204);
|
return (response.status === 200 || response.status === 204);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if http request is to authn endpoint
|
||||||
|
*
|
||||||
|
* @param http
|
||||||
|
*/
|
||||||
private isAuthRequest(http: HttpRequest<any> | HttpResponseBase): boolean {
|
private isAuthRequest(http: HttpRequest<any> | HttpResponseBase): boolean {
|
||||||
return http && http.url
|
return http && http.url
|
||||||
&& (http.url.endsWith('/authn/login')
|
&& (http.url.endsWith('/authn/login')
|
||||||
@@ -52,29 +67,47 @@ export class AuthInterceptor implements HttpInterceptor {
|
|||||||
|| http.url.endsWith('/authn/status'));
|
|| http.url.endsWith('/authn/status'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if response is from a login request
|
||||||
|
*
|
||||||
|
* @param http
|
||||||
|
*/
|
||||||
private isLoginResponse(http: HttpRequest<any> | HttpResponseBase): boolean {
|
private isLoginResponse(http: HttpRequest<any> | HttpResponseBase): boolean {
|
||||||
return http.url && http.url.endsWith('/authn/login')
|
return http.url && http.url.endsWith('/authn/login')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if response is from a logout request
|
||||||
|
*
|
||||||
|
* @param http
|
||||||
|
*/
|
||||||
private isLogoutResponse(http: HttpRequest<any> | HttpResponseBase): boolean {
|
private isLogoutResponse(http: HttpRequest<any> | HttpResponseBase): boolean {
|
||||||
return http.url && http.url.endsWith('/authn/logout');
|
return http.url && http.url.endsWith('/authn/logout');
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseLocation(unparsedLocation: string): string {
|
/**
|
||||||
unparsedLocation = unparsedLocation.trim();
|
* Extract location url from the WWW-Authenticate header
|
||||||
unparsedLocation = unparsedLocation.replace('location="', '');
|
*
|
||||||
unparsedLocation = unparsedLocation.replace('"', '');
|
* @param header
|
||||||
|
*/
|
||||||
|
private parseLocation(header: string): string {
|
||||||
|
let location = header.trim();
|
||||||
|
location = location.replace('location="', '');
|
||||||
|
location = location.replace('"', '');
|
||||||
let re = /%3A%2F%2F/g;
|
let re = /%3A%2F%2F/g;
|
||||||
unparsedLocation = unparsedLocation.replace(re, '://');
|
location = location.replace(re, '://');
|
||||||
re = /%3A/g
|
re = /%3A/g;
|
||||||
unparsedLocation = unparsedLocation.replace(re, ':')
|
location = location.replace(re, ':');
|
||||||
const parsedLocation = unparsedLocation.trim(); // + '/shibboleth';
|
return location.trim();
|
||||||
|
|
||||||
return parsedLocation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private sortAuthMethods(authMethodModels: AuthMethodModel[]): AuthMethodModel[] {
|
/**
|
||||||
const sortedAuthMethodModels: AuthMethodModel[] = new Array<AuthMethodModel>();
|
* Sort authentication methods list
|
||||||
|
*
|
||||||
|
* @param authMethodModels
|
||||||
|
*/
|
||||||
|
private sortAuthMethods(authMethodModels: AuthMethod[]): AuthMethod[] {
|
||||||
|
const sortedAuthMethodModels: AuthMethod[] = [];
|
||||||
authMethodModels.forEach((method) => {
|
authMethodModels.forEach((method) => {
|
||||||
if (method.authMethodType === AuthMethodType.Password) {
|
if (method.authMethodType === AuthMethodType.Password) {
|
||||||
sortedAuthMethodModels.push(method);
|
sortedAuthMethodModels.push(method);
|
||||||
@@ -90,10 +123,14 @@ export class AuthInterceptor implements HttpInterceptor {
|
|||||||
return sortedAuthMethodModels;
|
return sortedAuthMethodModels;
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseAuthMethodsfromHeaders(headers: HttpHeaders): AuthMethodModel[] {
|
/**
|
||||||
let authMethodModels: AuthMethodModel[] = [];
|
* Extract authentication methods list from the WWW-Authenticate headers
|
||||||
|
*
|
||||||
|
* @param headers
|
||||||
|
*/
|
||||||
|
private parseAuthMethodsFromHeaders(headers: HttpHeaders): AuthMethod[] {
|
||||||
|
let authMethodModels: AuthMethod[] = [];
|
||||||
if (isNotEmpty(headers.get('www-authenticate'))) {
|
if (isNotEmpty(headers.get('www-authenticate'))) {
|
||||||
const parts: string[] = headers.get('www-authenticate').split(',');
|
|
||||||
// get the realms from the header - a realm is a single auth method
|
// get the realms from the header - a realm is a single auth method
|
||||||
const completeWWWauthenticateHeader = headers.get('www-authenticate');
|
const completeWWWauthenticateHeader = headers.get('www-authenticate');
|
||||||
const regex = /(\w+ (\w+=((".*?")|[^,]*)(, )?)*)/g;
|
const regex = /(\w+ (\w+=((".*?")|[^,]*)(, )?)*)/g;
|
||||||
@@ -105,15 +142,14 @@ export class AuthInterceptor implements HttpInterceptor {
|
|||||||
const splittedRealm = realms[j].split(', ');
|
const splittedRealm = realms[j].split(', ');
|
||||||
const methodName = splittedRealm[0].split(' ')[0].trim();
|
const methodName = splittedRealm[0].split(' ')[0].trim();
|
||||||
|
|
||||||
let authMethodModel: AuthMethodModel;
|
let authMethodModel: AuthMethod;
|
||||||
if (splittedRealm.length === 1) {
|
if (splittedRealm.length === 1) {
|
||||||
authMethodModel = new AuthMethodModel(methodName);
|
authMethodModel = new AuthMethod(methodName);
|
||||||
authMethodModels.push(authMethodModel);
|
authMethodModels.push(authMethodModel);
|
||||||
} else if (splittedRealm.length > 1) {
|
} else if (splittedRealm.length > 1) {
|
||||||
let location = splittedRealm[1];
|
let location = splittedRealm[1];
|
||||||
location = this.parseLocation(location);
|
location = this.parseLocation(location);
|
||||||
authMethodModel = new AuthMethodModel(methodName, location);
|
authMethodModel = new AuthMethod(methodName, location);
|
||||||
// console.log('location: ', location);
|
|
||||||
authMethodModels.push(authMethodModel);
|
authMethodModels.push(authMethodModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,17 +157,25 @@ export class AuthInterceptor implements HttpInterceptor {
|
|||||||
// make sure the email + password login component gets rendered first
|
// make sure the email + password login component gets rendered first
|
||||||
authMethodModels = this.sortAuthMethods(authMethodModels);
|
authMethodModels = this.sortAuthMethods(authMethodModels);
|
||||||
} else {
|
} else {
|
||||||
authMethodModels.push(new AuthMethodModel(AuthMethodType.Password));
|
authMethodModels.push(new AuthMethod(AuthMethodType.Password));
|
||||||
}
|
}
|
||||||
|
|
||||||
return authMethodModels;
|
return authMethodModels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate an AuthStatus object
|
||||||
|
*
|
||||||
|
* @param authenticated
|
||||||
|
* @param accessToken
|
||||||
|
* @param error
|
||||||
|
* @param httpHeaders
|
||||||
|
*/
|
||||||
private makeAuthStatusObject(authenticated: boolean, accessToken ?: string, error ?: string, httpHeaders ?: HttpHeaders): AuthStatus {
|
private makeAuthStatusObject(authenticated: boolean, accessToken ?: string, error ?: string, httpHeaders ?: HttpHeaders): AuthStatus {
|
||||||
const authStatus = new AuthStatus();
|
const authStatus = new AuthStatus();
|
||||||
// let authMethods: AuthMethodModel[];
|
// let authMethods: AuthMethodModel[];
|
||||||
if (httpHeaders) {
|
if (httpHeaders) {
|
||||||
authStatus.authMethods = this.parseAuthMethodsfromHeaders(httpHeaders);
|
authStatus.authMethods = this.parseAuthMethodsFromHeaders(httpHeaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
authStatus.id = null;
|
authStatus.id = null;
|
||||||
@@ -149,6 +193,11 @@ export class AuthInterceptor implements HttpInterceptor {
|
|||||||
return authStatus;
|
return authStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intercept method
|
||||||
|
* @param req
|
||||||
|
* @param next
|
||||||
|
*/
|
||||||
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
|
||||||
|
|
||||||
const authService = this.inj.get(AuthService);
|
const authService = this.inj.get(AuthService);
|
||||||
|
@@ -26,8 +26,8 @@ import {
|
|||||||
import { AuthTokenInfo } from './models/auth-token-info.model';
|
import { AuthTokenInfo } from './models/auth-token-info.model';
|
||||||
import { EPersonMock } from '../../shared/testing/eperson-mock';
|
import { EPersonMock } from '../../shared/testing/eperson-mock';
|
||||||
import { AuthStatus } from './models/auth-status.model';
|
import { AuthStatus } from './models/auth-status.model';
|
||||||
import { AuthMethodModel } from './models/auth-method.model';
|
import { AuthMethod } from './models/auth.method';
|
||||||
import { AuthMethodType } from '../../shared/log-in/methods/authMethods-type';
|
import { AuthMethodType } from './models/auth.method-type';
|
||||||
|
|
||||||
describe('authReducer', () => {
|
describe('authReducer', () => {
|
||||||
|
|
||||||
@@ -441,8 +441,8 @@ describe('authReducer', () => {
|
|||||||
authMethods: []
|
authMethods: []
|
||||||
};
|
};
|
||||||
const authMethods = [
|
const authMethods = [
|
||||||
new AuthMethodModel(AuthMethodType.Password),
|
new AuthMethod(AuthMethodType.Password),
|
||||||
new AuthMethodModel(AuthMethodType.Shibboleth, 'location')
|
new AuthMethod(AuthMethodType.Shibboleth, 'location')
|
||||||
];
|
];
|
||||||
const action = new RetrieveAuthMethodsSuccessAction(authMethods);
|
const action = new RetrieveAuthMethodsSuccessAction(authMethods);
|
||||||
const newState = authReducer(initialState, action);
|
const newState = authReducer(initialState, action);
|
||||||
|
@@ -8,14 +8,14 @@ import {
|
|||||||
LogOutErrorAction,
|
LogOutErrorAction,
|
||||||
RedirectWhenAuthenticationIsRequiredAction,
|
RedirectWhenAuthenticationIsRequiredAction,
|
||||||
RedirectWhenTokenExpiredAction,
|
RedirectWhenTokenExpiredAction,
|
||||||
RefreshTokenSuccessAction, RetrieveAuthMethodsSuccessAction,
|
RefreshTokenSuccessAction,
|
||||||
|
RetrieveAuthMethodsSuccessAction,
|
||||||
SetRedirectUrlAction
|
SetRedirectUrlAction
|
||||||
} from './auth.actions';
|
} from './auth.actions';
|
||||||
// import models
|
// import models
|
||||||
import { EPerson } from '../eperson/models/eperson.model';
|
import { EPerson } from '../eperson/models/eperson.model';
|
||||||
import { AuthTokenInfo } from './models/auth-token-info.model';
|
import { AuthTokenInfo } from './models/auth-token-info.model';
|
||||||
import { AuthMethodModel } from './models/auth-method.model';
|
import { AuthMethod } from './models/auth.method';
|
||||||
import { AuthMethodType } from '../../shared/log-in/methods/authMethods-type';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The auth state.
|
* The auth state.
|
||||||
@@ -51,7 +51,7 @@ export interface AuthState {
|
|||||||
user?: EPerson;
|
user?: EPerson;
|
||||||
|
|
||||||
// all authentication Methods enabled at the backend
|
// all authentication Methods enabled at the backend
|
||||||
authMethods?: AuthMethodModel[];
|
authMethods?: AuthMethod[];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,6 +25,8 @@ import { RemoteDataBuildService } from '../cache/builders/remote-data-build.serv
|
|||||||
import { getMockRemoteDataBuildService } from '../../shared/mocks/mock-remote-data-build.service';
|
import { getMockRemoteDataBuildService } from '../../shared/mocks/mock-remote-data-build.service';
|
||||||
import { routeServiceStub } from '../../shared/testing/route-service-stub';
|
import { routeServiceStub } from '../../shared/testing/route-service-stub';
|
||||||
import { RouteService } from '../services/route.service';
|
import { RouteService } from '../services/route.service';
|
||||||
|
import { authMethodsMock } from '../../shared/testing/auth-service-stub';
|
||||||
|
import { AuthMethod } from './models/auth.method';
|
||||||
|
|
||||||
describe('AuthService test', () => {
|
describe('AuthService test', () => {
|
||||||
|
|
||||||
@@ -128,6 +130,26 @@ describe('AuthService test', () => {
|
|||||||
expect(authService.logout.bind(null)).toThrow();
|
expect(authService.logout.bind(null)).toThrow();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return the authentication status object to check an Authentication Cookie', () => {
|
||||||
|
authService.checkAuthenticationCookie().subscribe((status: AuthStatus) => {
|
||||||
|
expect(status).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the authentication methods available', () => {
|
||||||
|
const authStatus = new AuthStatus();
|
||||||
|
|
||||||
|
authService.retrieveAuthMethods(authStatus).subscribe((authMethods: AuthMethod[]) => {
|
||||||
|
expect(authMethods).toBeDefined();
|
||||||
|
expect(authMethods.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
authStatus.authMethods = authMethodsMock;
|
||||||
|
authService.retrieveAuthMethods(authStatus).subscribe((authMethods: AuthMethod[]) => {
|
||||||
|
expect(authMethods).toBeDefined();
|
||||||
|
expect(authMethods.length).toBe(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('', () => {
|
describe('', () => {
|
||||||
|
@@ -27,9 +27,7 @@ import { NativeWindowRef, NativeWindowService } from '../services/window.service
|
|||||||
import { Base64EncodeUrl } from '../../shared/utils/encode-decode.util';
|
import { Base64EncodeUrl } from '../../shared/utils/encode-decode.util';
|
||||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||||
import { RouteService } from '../services/route.service';
|
import { RouteService } from '../services/route.service';
|
||||||
import { GlobalConfig } from '../../../config/global-config.interface';
|
import { AuthMethod } from './models/auth.method';
|
||||||
import { GLOBAL_CONFIG } from '../../../config';
|
|
||||||
import { AuthMethodModel } from './models/auth-method.model';
|
|
||||||
|
|
||||||
export const LOGIN_ROUTE = '/login';
|
export const LOGIN_ROUTE = '/login';
|
||||||
export const LOGOUT_ROUTE = '/logout';
|
export const LOGOUT_ROUTE = '/logout';
|
||||||
@@ -213,8 +211,8 @@ export class AuthService {
|
|||||||
* Retrieve authentication methods available
|
* Retrieve authentication methods available
|
||||||
* @returns {User}
|
* @returns {User}
|
||||||
*/
|
*/
|
||||||
public retrieveAuthMethods(status: AuthStatus): Observable<AuthMethodModel[]> {
|
public retrieveAuthMethods(status: AuthStatus): Observable<AuthMethod[]> {
|
||||||
let authMethods: AuthMethodModel[] = [];
|
let authMethods: AuthMethod[] = [];
|
||||||
if (isNotEmpty(status.authMethods)) {
|
if (isNotEmpty(status.authMethods)) {
|
||||||
authMethods = status.authMethods;
|
authMethods = status.authMethods;
|
||||||
}
|
}
|
||||||
@@ -384,7 +382,6 @@ export class AuthService {
|
|||||||
// For standalone login pages, use the previous route.
|
// For standalone login pages, use the previous route.
|
||||||
redirUrl = history[history.length - 2] || '';
|
redirUrl = history[history.length - 2] || '';
|
||||||
} else {
|
} else {
|
||||||
// console.log('isStandAlonePage: ', isStandalonePage);
|
|
||||||
redirUrl = history[history.length - 1] || '';
|
redirUrl = history[history.length - 1] || '';
|
||||||
}
|
}
|
||||||
this.navigateToRedirectUrl(redirUrl);
|
this.navigateToRedirectUrl(redirUrl);
|
||||||
|
@@ -5,7 +5,7 @@ import { RemoteData } from '../../data/remote-data';
|
|||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { CacheableObject } from '../../cache/object-cache.reducer';
|
import { CacheableObject } from '../../cache/object-cache.reducer';
|
||||||
import { ResourceType } from '../../shared/resource-type';
|
import { ResourceType } from '../../shared/resource-type';
|
||||||
import {AuthMethodModel} from './auth-method.model';
|
import { AuthMethod } from './auth.method';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object that represents the authenticated status of a user
|
* Object that represents the authenticated status of a user
|
||||||
@@ -56,6 +56,6 @@ export class AuthStatus implements CacheableObject {
|
|||||||
/**
|
/**
|
||||||
* All authentication methods enabled at the backend
|
* All authentication methods enabled at the backend
|
||||||
*/
|
*/
|
||||||
authMethods: AuthMethodModel[];
|
authMethods: AuthMethod[];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { AuthMethodType } from '../../../shared/log-in/methods/authMethods-type';
|
import { AuthMethodType } from './auth.method-type';
|
||||||
|
|
||||||
export class AuthMethodModel {
|
export class AuthMethod {
|
||||||
authMethodType: AuthMethodType;
|
authMethodType: AuthMethodType;
|
||||||
location?: string;
|
location?: string;
|
||||||
|
|
@@ -4,7 +4,6 @@ import { mapsTo, relationship } from '../../cache/builders/build-decorators';
|
|||||||
import { NormalizedObject } from '../../cache/models/normalized-object.model';
|
import { NormalizedObject } from '../../cache/models/normalized-object.model';
|
||||||
import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer';
|
import { IDToUUIDSerializer } from '../../cache/id-to-uuid-serializer';
|
||||||
import { EPerson } from '../../eperson/models/eperson.model';
|
import { EPerson } from '../../eperson/models/eperson.model';
|
||||||
import {AuthMethodModel} from './auth-method.model';
|
|
||||||
|
|
||||||
@mapsTo(AuthStatus)
|
@mapsTo(AuthStatus)
|
||||||
@inheritSerialization(NormalizedObject)
|
@inheritSerialization(NormalizedObject)
|
||||||
|
@@ -1,16 +1,16 @@
|
|||||||
import { filter, map, switchMap, take } from 'rxjs/operators';
|
import { filter, map, switchMap, take } from 'rxjs/operators';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpHeaders } from '@angular/common/http';
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { HttpHeaders } from '@angular/common/http';
|
|
||||||
import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service';
|
import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service';
|
||||||
import { AuthStatus } from './models/auth-status.model';
|
import { AuthStatus } from './models/auth-status.model';
|
||||||
import { isNotEmpty } from '../../shared/empty.util';
|
import { isNotEmpty } from '../../shared/empty.util';
|
||||||
import { AuthService } from './auth.service';
|
import { AuthService } from './auth.service';
|
||||||
import { AuthTokenInfo } from './models/auth-token-info.model';
|
import { AuthTokenInfo } from './models/auth-token-info.model';
|
||||||
import { CheckAuthenticationTokenAction } from './auth.actions';
|
|
||||||
import { EPerson } from '../eperson/models/eperson.model';
|
import { EPerson } from '../eperson/models/eperson.model';
|
||||||
import { AuthMethodModel } from './models/auth-method.model';
|
import { AuthMethod } from './models/auth.method';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The auth service.
|
* The auth service.
|
||||||
@@ -76,7 +76,7 @@ export class ServerAuthService extends AuthService {
|
|||||||
* Retrieve authentication methods available
|
* Retrieve authentication methods available
|
||||||
* @returns {User}
|
* @returns {User}
|
||||||
*/
|
*/
|
||||||
public retrieveAuthMethods(): Observable<AuthMethodModel[]> {
|
public retrieveAuthMethods(): Observable<AuthMethod[]> {
|
||||||
const options: HttpOptions = Object.create({});
|
const options: HttpOptions = Object.create({});
|
||||||
if (isNotEmpty(this.req.headers) && isNotEmpty(this.req.headers.referer)) {
|
if (isNotEmpty(this.req.headers) && isNotEmpty(this.req.headers.referer)) {
|
||||||
let headers = new HttpHeaders();
|
let headers = new HttpHeaders();
|
||||||
@@ -86,7 +86,7 @@ export class ServerAuthService extends AuthService {
|
|||||||
|
|
||||||
return this.authRequestService.postToEndpoint('login', {}, options).pipe(
|
return this.authRequestService.postToEndpoint('login', {}, options).pipe(
|
||||||
map((status: AuthStatus) => {
|
map((status: AuthStatus) => {
|
||||||
let authMethods: AuthMethodModel[];
|
let authMethods: AuthMethod[];
|
||||||
if (isNotEmpty(status.authMethods)) {
|
if (isNotEmpty(status.authMethods)) {
|
||||||
authMethods = status.authMethods;
|
authMethods = status.authMethods;
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,108 @@
|
|||||||
|
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
|
import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing';
|
||||||
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
|
||||||
|
import { StoreModule } from '@ngrx/store';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
import { LogInContainerComponent } from './log-in-container.component';
|
||||||
|
import { authReducer } from '../../../core/auth/auth.reducer';
|
||||||
|
import { SharedModule } from '../../shared.module';
|
||||||
|
import { createTestComponent } from '../../testing/utils';
|
||||||
|
import { AuthService } from '../../../core/auth/auth.service';
|
||||||
|
import { AuthMethod } from '../../../core/auth/models/auth.method';
|
||||||
|
import { AuthServiceStub } from '../../testing/auth-service-stub';
|
||||||
|
|
||||||
|
describe('LogInContainerComponent', () => {
|
||||||
|
|
||||||
|
let component: LogInContainerComponent;
|
||||||
|
let fixture: ComponentFixture<LogInContainerComponent>;
|
||||||
|
|
||||||
|
const authMethod = new AuthMethod('password');
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
// refine the test module by declaring the test component
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
FormsModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
StoreModule.forRoot(authReducer),
|
||||||
|
SharedModule,
|
||||||
|
TranslateModule.forRoot()
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
TestComponent
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{provide: AuthService, useClass: AuthServiceStub},
|
||||||
|
LogInContainerComponent
|
||||||
|
],
|
||||||
|
schemas: [
|
||||||
|
CUSTOM_ELEMENTS_SCHEMA
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('', () => {
|
||||||
|
let testComp: TestComponent;
|
||||||
|
let testFixture: ComponentFixture<TestComponent>;
|
||||||
|
|
||||||
|
// synchronous beforeEach
|
||||||
|
beforeEach(() => {
|
||||||
|
const html = `<ds-log-in-container [authMethod]="authMethod"> </ds-log-in-container>`;
|
||||||
|
|
||||||
|
testFixture = createTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
|
||||||
|
testComp = testFixture.componentInstance;
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
testFixture.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create LogInContainerComponent', inject([LogInContainerComponent], (app: LogInContainerComponent) => {
|
||||||
|
|
||||||
|
expect(app).toBeDefined();
|
||||||
|
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(LogInContainerComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
|
||||||
|
spyOn(component, 'getAuthMethodContent').and.callThrough();
|
||||||
|
component.authMethod = authMethod;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
fixture.destroy();
|
||||||
|
component = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should inject component properly', () => {
|
||||||
|
|
||||||
|
component.ngOnInit();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(component.getAuthMethodContent).toHaveBeenCalled();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// declare a test component
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-test-cmp',
|
||||||
|
template: ``
|
||||||
|
})
|
||||||
|
class TestComponent {
|
||||||
|
|
||||||
|
isStandalonePage = true;
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,51 @@
|
|||||||
|
import { Component, Injector, Input, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
import { rendersAuthMethodType } from '../methods/log-in.methods-decorator';
|
||||||
|
import { AuthMethod } from '../../../core/auth/models/auth.method';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component represents a component container for log-in methods available.
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-log-in-container',
|
||||||
|
templateUrl: './log-in-container.component.html',
|
||||||
|
styleUrls: ['./log-in-container.component.scss']
|
||||||
|
})
|
||||||
|
export class LogInContainerComponent implements OnInit {
|
||||||
|
|
||||||
|
@Input() authMethod: AuthMethod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injector to inject a section component with the @Input parameters
|
||||||
|
* @type {Injector}
|
||||||
|
*/
|
||||||
|
public objectInjector: Injector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize instance variables
|
||||||
|
*
|
||||||
|
* @param {Injector} injector
|
||||||
|
*/
|
||||||
|
constructor(private injector: Injector) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize all instance variables
|
||||||
|
*/
|
||||||
|
ngOnInit() {
|
||||||
|
this.objectInjector = Injector.create({
|
||||||
|
providers: [
|
||||||
|
{ provide: 'authMethodProvider', useFactory: () => (this.authMethod), deps: [] },
|
||||||
|
],
|
||||||
|
parent: this.injector
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the correct component based on the AuthMethod's type
|
||||||
|
*/
|
||||||
|
getAuthMethodContent(): string {
|
||||||
|
return rendersAuthMethodType(this.authMethod.authMethodType)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,52 +0,0 @@
|
|||||||
import { Component, Injector, Input, OnInit} from '@angular/core';
|
|
||||||
import { rendersAuthMethodType } from '../methods/authMethods-decorator';
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
import { CoreState } from '../../../core/core.reducers';
|
|
||||||
import { AuthMethodModel } from '../../../core/auth/models/auth-method.model';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This component represents a section that contains the submission license form.
|
|
||||||
*/
|
|
||||||
@Component({
|
|
||||||
selector: 'ds-login-container',
|
|
||||||
templateUrl: './login-container.component.html',
|
|
||||||
styleUrls: ['./login-container.component.scss']
|
|
||||||
})
|
|
||||||
export class LoginContainerComponent implements OnInit {
|
|
||||||
|
|
||||||
@Input() authMethodModel: AuthMethodModel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Injector to inject a section component with the @Input parameters
|
|
||||||
* @type {Injector}
|
|
||||||
*/
|
|
||||||
public objectInjector: Injector;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize instance variables
|
|
||||||
*
|
|
||||||
* @param {Injector} injector
|
|
||||||
*/
|
|
||||||
constructor(private injector: Injector, private store: Store<CoreState>) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize all instance variables
|
|
||||||
*/
|
|
||||||
ngOnInit() {
|
|
||||||
this.objectInjector = Injector.create({
|
|
||||||
providers: [
|
|
||||||
{provide: 'authMethodModelProvider', useFactory: () => (this.authMethodModel), deps: []},
|
|
||||||
],
|
|
||||||
parent: this.injector
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the correct component based on the AuthMethod's type
|
|
||||||
*/
|
|
||||||
getAuthMethodContent(): string {
|
|
||||||
return rendersAuthMethodType(this.authMethodModel.authMethodType)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,10 +1,10 @@
|
|||||||
<ds-loading *ngIf="(loading | async) || (isAuthenticated | async)" class="m-5"></ds-loading>
|
<ds-loading *ngIf="(loading | async) || (isAuthenticated | async)" class="m-5"></ds-loading>
|
||||||
<div *ngIf="!(loading | async) && !(isAuthenticated | async)" class="form-login px-4 py-3">
|
<div *ngIf="!(loading | async) && !(isAuthenticated | async)" class="px-4 py-3">
|
||||||
<ng-container *ngFor="let authMethodModel of (authMethodModels | async); let i = index">
|
<ng-container *ngFor="let authMethod of (authMethods | async); let i = index">
|
||||||
<div *ngIf="i === 1" class="text-center mt-2">
|
<div *ngIf="i === 1" class="text-center mt-2">
|
||||||
<span class="align-middle">{{"login.form.or-divider" | translate}}</span>
|
<span class="align-middle">{{"login.form.or-divider" | translate}}</span>
|
||||||
</div>
|
</div>
|
||||||
<ds-login-container [authMethodModel]="authMethodModel"></ds-login-container>
|
<ds-log-in-container [authMethod]="authMethod"></ds-log-in-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
|
@@ -1,35 +1,23 @@
|
|||||||
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing';
|
||||||
import { FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
||||||
|
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { Store, StoreModule } from '@ngrx/store';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
|
||||||
|
import { of as observableOf } from 'rxjs';
|
||||||
|
import { StoreModule } from '@ngrx/store';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { LogInComponent } from './log-in.component';
|
import { LogInComponent } from './log-in.component';
|
||||||
import { authReducer } from '../../core/auth/auth.reducer';
|
import { authReducer } from '../../core/auth/auth.reducer';
|
||||||
import { EPersonMock } from '../testing/eperson-mock';
|
|
||||||
import { EPerson } from '../../core/eperson/models/eperson.model';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
|
||||||
import { AuthService } from '../../core/auth/auth.service';
|
import { AuthService } from '../../core/auth/auth.service';
|
||||||
import { AuthServiceStub } from '../testing/auth-service-stub';
|
import { authMethodsMock, AuthServiceStub } from '../testing/auth-service-stub';
|
||||||
import { AppState } from '../../app.reducer';
|
import { createTestComponent } from '../testing/utils';
|
||||||
|
import { SharedModule } from '../shared.module';
|
||||||
|
|
||||||
describe('LogInComponent', () => {
|
describe('LogInComponent', () => {
|
||||||
|
|
||||||
let component: LogInComponent;
|
let component: LogInComponent;
|
||||||
let fixture: ComponentFixture<LogInComponent>;
|
let fixture: ComponentFixture<LogInComponent>;
|
||||||
let page: Page;
|
|
||||||
let user: EPerson;
|
|
||||||
|
|
||||||
const authState = {
|
|
||||||
authenticated: false,
|
|
||||||
loaded: false,
|
|
||||||
loading: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
user = EPersonMock;
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
// refine the test module by declaring the test component
|
// refine the test module by declaring the test component
|
||||||
@@ -38,13 +26,15 @@ describe('LogInComponent', () => {
|
|||||||
FormsModule,
|
FormsModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
StoreModule.forRoot(authReducer),
|
StoreModule.forRoot(authReducer),
|
||||||
|
SharedModule,
|
||||||
TranslateModule.forRoot()
|
TranslateModule.forRoot()
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
LogInComponent
|
TestComponent
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{provide: AuthService, useClass: AuthServiceStub}
|
{provide: AuthService, useClass: AuthServiceStub},
|
||||||
|
LogInComponent
|
||||||
],
|
],
|
||||||
schemas: [
|
schemas: [
|
||||||
CUSTOM_ELEMENTS_SCHEMA
|
CUSTOM_ELEMENTS_SCHEMA
|
||||||
@@ -54,75 +44,64 @@ describe('LogInComponent', () => {
|
|||||||
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(inject([Store], (store: Store<AppState>) => {
|
describe('', () => {
|
||||||
store
|
let testComp: TestComponent;
|
||||||
.subscribe((state) => {
|
let testFixture: ComponentFixture<TestComponent>;
|
||||||
(state as any).core = Object.create({});
|
|
||||||
(state as any).core.auth = authState;
|
// synchronous beforeEach
|
||||||
|
beforeEach(() => {
|
||||||
|
const html = `<ds-log-in [isStandalonePage]="isStandalonePage"> </ds-log-in>`;
|
||||||
|
|
||||||
|
testFixture = createTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
|
||||||
|
testComp = testFixture.componentInstance;
|
||||||
});
|
});
|
||||||
|
|
||||||
// create component and test fixture
|
afterEach(() => {
|
||||||
fixture = TestBed.createComponent(LogInComponent);
|
testFixture.destroy();
|
||||||
|
|
||||||
// get test component from the fixture
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
|
|
||||||
// create page
|
|
||||||
page = new Page(component, fixture);
|
|
||||||
|
|
||||||
// verify the fixture is stable (no pending tasks)
|
|
||||||
fixture.whenStable().then(() => {
|
|
||||||
page.addPageElements();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should create LogInComponent', inject([LogInComponent], (app: LogInComponent) => {
|
||||||
|
|
||||||
|
expect(app).toBeDefined();
|
||||||
|
|
||||||
}));
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(LogInComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
component.isAuthenticated = observableOf(false);
|
||||||
|
component.loading = observableOf(false);
|
||||||
|
|
||||||
/* it('should create a FormGroup comprised of FormControls', () => {
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(component.form instanceof FormGroup).toBe(true);
|
});
|
||||||
});*/
|
|
||||||
|
afterEach(() => {
|
||||||
|
fixture.destroy();
|
||||||
|
component = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render a log-in container component foe each auth method available', () => {
|
||||||
|
component.authMethods = observableOf(authMethodsMock);
|
||||||
|
|
||||||
/* it('should authenticate', () => {
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
// set FormControl values
|
const loginContainers = fixture.debugElement.queryAll(By.css('ds-log-in-container'));
|
||||||
component.form.controls.email.setValue('user');
|
expect(loginContainers.length).toBe(2);
|
||||||
component.form.controls.password.setValue('password');
|
|
||||||
|
|
||||||
// submit form
|
});
|
||||||
component.submit();
|
});
|
||||||
|
|
||||||
// verify Store.dispatch() is invoked
|
|
||||||
expect(page.navigateSpy.calls.any()).toBe(true, 'Store.dispatch not invoked');
|
|
||||||
});*/
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
// declare a test component
|
||||||
* I represent the DOM elements and attach spies.
|
@Component({
|
||||||
*
|
selector: 'ds-test-cmp',
|
||||||
* @class Page
|
template: ``
|
||||||
*/
|
})
|
||||||
class Page {
|
class TestComponent {
|
||||||
|
|
||||||
public emailInput: HTMLInputElement;
|
isStandalonePage = true;
|
||||||
public navigateSpy: jasmine.Spy;
|
|
||||||
public passwordInput: HTMLInputElement;
|
|
||||||
|
|
||||||
constructor(private component: LogInComponent, private fixture: ComponentFixture<LogInComponent>) {
|
|
||||||
// use injector to get services
|
|
||||||
const injector = fixture.debugElement.injector;
|
|
||||||
const store = injector.get(Store);
|
|
||||||
|
|
||||||
// add spies
|
|
||||||
this.navigateSpy = spyOn(store, 'dispatch');
|
|
||||||
}
|
|
||||||
|
|
||||||
public addPageElements() {
|
|
||||||
const emailInputSelector = 'input[formcontrolname=\'email\']';
|
|
||||||
this.emailInput = this.fixture.debugElement.query(By.css(emailInputSelector)).nativeElement;
|
|
||||||
|
|
||||||
const passwordInputSelector = 'input[formcontrolname=\'password\']';
|
|
||||||
this.passwordInput = this.fixture.debugElement.query(By.css(passwordInputSelector)).nativeElement;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,26 +1,37 @@
|
|||||||
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { AuthMethodModel } from '../../core/auth/models/auth-method.model';
|
import { filter, takeWhile, } from 'rxjs/operators';
|
||||||
import { select, Store } from '@ngrx/store';
|
import { select, Store } from '@ngrx/store';
|
||||||
|
|
||||||
|
import { AuthMethod } from '../../core/auth/models/auth.method';
|
||||||
import { getAuthenticationMethods, isAuthenticated, isAuthenticationLoading } from '../../core/auth/selectors';
|
import { getAuthenticationMethods, isAuthenticated, isAuthenticationLoading } from '../../core/auth/selectors';
|
||||||
import { CoreState } from '../../core/core.reducers';
|
import { CoreState } from '../../core/core.reducers';
|
||||||
import { filter, takeWhile, } from 'rxjs/operators';
|
|
||||||
import { AuthService } from '../../core/auth/auth.service';
|
import { AuthService } from '../../core/auth/auth.service';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* /users/sign-in
|
||||||
|
* @class LogInComponent
|
||||||
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-log-in',
|
selector: 'ds-log-in',
|
||||||
templateUrl: './log-in.component.html',
|
templateUrl: './log-in.component.html',
|
||||||
styleUrls: ['./log-in.component.scss']
|
styleUrls: ['./log-in.component.scss']
|
||||||
})
|
})
|
||||||
export class LogInComponent implements OnInit, OnDestroy {
|
export class LogInComponent implements OnInit, OnDestroy {
|
||||||
/**
|
|
||||||
* The authentication methods data
|
|
||||||
* @type {AuthMethodModel[]}
|
|
||||||
*/
|
|
||||||
@Input() authMethodModels: Observable<AuthMethodModel[]>;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing if LogInComponent is in a standalone page
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
@Input() isStandalonePage: boolean;
|
@Input() isStandalonePage: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of authentication methods available
|
||||||
|
* @type {AuthMethod[]}
|
||||||
|
*/
|
||||||
|
public authMethods: Observable<AuthMethod[]>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether user is authenticated.
|
* Whether user is authenticated.
|
||||||
* @type {Observable<string>}
|
* @type {Observable<string>}
|
||||||
@@ -45,9 +56,7 @@ export class LogInComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|
||||||
// this.store.dispatch(new SetIsStandalonePageInAuthMethodsAction(this.isStandalonePage));
|
this.authMethods = this.store.pipe(
|
||||||
|
|
||||||
this.authMethodModels = this.store.pipe(
|
|
||||||
select(getAuthenticationMethods),
|
select(getAuthenticationMethods),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { AuthMethodType } from './authMethods-type';
|
import { AuthMethodType } from '../../../core/auth/models/auth.method-type';
|
||||||
|
|
||||||
const authMethodsMap = new Map();
|
const authMethodsMap = new Map();
|
||||||
|
|
@@ -4,16 +4,17 @@ import { FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|||||||
|
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { Store, StoreModule } from '@ngrx/store';
|
import { Store, StoreModule } from '@ngrx/store';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { LogInPasswordComponent } from './log-in-password.component';
|
import { LogInPasswordComponent } from './log-in-password.component';
|
||||||
import { EPerson } from '../../../../core/eperson/models/eperson.model';
|
import { EPerson } from '../../../../core/eperson/models/eperson.model';
|
||||||
import { EPersonMock } from '../../../testing/eperson-mock';
|
import { EPersonMock } from '../../../testing/eperson-mock';
|
||||||
import { authReducer } from '../../../../core/auth/auth.reducer';
|
import { authReducer } from '../../../../core/auth/auth.reducer';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
|
||||||
import { AuthService } from '../../../../core/auth/auth.service';
|
import { AuthService } from '../../../../core/auth/auth.service';
|
||||||
import { AuthServiceStub } from '../../../testing/auth-service-stub';
|
import { AuthServiceStub } from '../../../testing/auth-service-stub';
|
||||||
import { AppState } from '../../../../app.reducer';
|
import { AppState } from '../../../../app.reducer';
|
||||||
import { AuthMethodModel } from '../../../../core/auth/models/auth-method.model';
|
import { AuthMethod } from '../../../../core/auth/models/auth.method';
|
||||||
import { AuthMethodType } from '../authMethods-type';
|
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
|
||||||
|
|
||||||
describe('LogInPasswordComponent', () => {
|
describe('LogInPasswordComponent', () => {
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ describe('LogInPasswordComponent', () => {
|
|||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: AuthService, useClass: AuthServiceStub },
|
{ provide: AuthService, useClass: AuthServiceStub },
|
||||||
{ provide: 'authMethodModelProvider', useValue: new AuthMethodModel(AuthMethodType.Password) }
|
{ provide: 'authMethodProvider', useValue: new AuthMethod(AuthMethodType.Password) }
|
||||||
],
|
],
|
||||||
schemas: [
|
schemas: [
|
||||||
CUSTOM_ELEMENTS_SCHEMA
|
CUSTOM_ELEMENTS_SCHEMA
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { map } from 'rxjs/operators';
|
import { map } from 'rxjs/operators';
|
||||||
import { Component, Inject, Input, OnInit } from '@angular/core';
|
import { Component, Inject, OnInit } from '@angular/core';
|
||||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
|
|
||||||
import { select, Store } from '@ngrx/store';
|
import { select, Store } from '@ngrx/store';
|
||||||
@@ -8,12 +8,11 @@ import { AuthenticateAction, ResetAuthenticationMessagesAction } from '../../../
|
|||||||
|
|
||||||
import { getAuthenticationError, getAuthenticationInfo, } from '../../../../core/auth/selectors';
|
import { getAuthenticationError, getAuthenticationInfo, } from '../../../../core/auth/selectors';
|
||||||
import { CoreState } from '../../../../core/core.reducers';
|
import { CoreState } from '../../../../core/core.reducers';
|
||||||
|
|
||||||
import { isNotEmpty } from '../../../empty.util';
|
import { isNotEmpty } from '../../../empty.util';
|
||||||
import { fadeOut } from '../../../animations/fade';
|
import { fadeOut } from '../../../animations/fade';
|
||||||
import { AuthMethodType } from '../authMethods-type';
|
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
|
||||||
import { renderAuthMethodFor } from '../authMethods-decorator';
|
import { renderAuthMethodFor } from '../log-in.methods-decorator';
|
||||||
import { AuthMethodModel } from '../../../../core/auth/models/auth-method.model';
|
import { AuthMethod } from '../../../../core/auth/models/auth.method';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /users/sign-in
|
* /users/sign-in
|
||||||
@@ -28,6 +27,12 @@ import { AuthMethodModel } from '../../../../core/auth/models/auth-method.model'
|
|||||||
@renderAuthMethodFor(AuthMethodType.Password)
|
@renderAuthMethodFor(AuthMethodType.Password)
|
||||||
export class LogInPasswordComponent implements OnInit {
|
export class LogInPasswordComponent implements OnInit {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The authentication method data.
|
||||||
|
* @type {AuthMethod}
|
||||||
|
*/
|
||||||
|
public authMethod: AuthMethod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The error if authentication fails.
|
* The error if authentication fails.
|
||||||
* @type {Observable<string>}
|
* @type {Observable<string>}
|
||||||
@@ -58,21 +63,18 @@ export class LogInPasswordComponent implements OnInit {
|
|||||||
*/
|
*/
|
||||||
public form: FormGroup;
|
public form: FormGroup;
|
||||||
|
|
||||||
@Input() authMethodModel: AuthMethodModel;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {AuthMethodModel} injectedAuthMethodModel
|
* @param {AuthMethod} injectedAuthMethodModel
|
||||||
* @param {FormBuilder} formBuilder
|
* @param {FormBuilder} formBuilder
|
||||||
* @param {Store<State>} store
|
* @param {Store<State>} store
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
@Inject('authMethodModelProvider') public injectedAuthMethodModel: AuthMethodModel,
|
@Inject('authMethodProvider') public injectedAuthMethodModel: AuthMethod,
|
||||||
/* private authService: AuthService,*/
|
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private store: Store<CoreState>
|
private store: Store<CoreState>
|
||||||
) {
|
) {
|
||||||
this.authMethodModel = injectedAuthMethodModel;
|
this.authMethod = injectedAuthMethodModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -118,15 +120,6 @@ export class LogInPasswordComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* To the registration page.
|
|
||||||
* @method register
|
|
||||||
*/
|
|
||||||
public register() {
|
|
||||||
// TODO enable after registration process is done
|
|
||||||
// this.router.navigate(['/register']);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submit the authentication form.
|
* Submit the authentication form.
|
||||||
* @method submit
|
* @method submit
|
||||||
|
@@ -0,0 +1,105 @@
|
|||||||
|
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
|
import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { Store, StoreModule } from '@ngrx/store';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
|
||||||
|
import { EPerson } from '../../../../core/eperson/models/eperson.model';
|
||||||
|
import { EPersonMock } from '../../../testing/eperson-mock';
|
||||||
|
import { authReducer } from '../../../../core/auth/auth.reducer';
|
||||||
|
import { AuthService } from '../../../../core/auth/auth.service';
|
||||||
|
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 { LogInShibbolethComponent } from './log-in-shibboleth.component';
|
||||||
|
|
||||||
|
describe('LogInShibbolethComponent', () => {
|
||||||
|
|
||||||
|
let component: LogInShibbolethComponent;
|
||||||
|
let fixture: ComponentFixture<LogInShibbolethComponent>;
|
||||||
|
let page: Page;
|
||||||
|
let user: EPerson;
|
||||||
|
|
||||||
|
const authState = {
|
||||||
|
authenticated: false,
|
||||||
|
loaded: false,
|
||||||
|
loading: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
user = EPersonMock;
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
// refine the test module by declaring the test component
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [
|
||||||
|
StoreModule.forRoot(authReducer),
|
||||||
|
TranslateModule.forRoot()
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
LogInShibbolethComponent
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: AuthService, useClass: AuthServiceStub },
|
||||||
|
{ provide: 'authMethodProvider',
|
||||||
|
useValue: new AuthMethod(AuthMethodType.Shibboleth, 'dspace.test/shibboleth')
|
||||||
|
}
|
||||||
|
],
|
||||||
|
schemas: [
|
||||||
|
CUSTOM_ELEMENTS_SCHEMA
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(inject([Store], (store: Store<AppState>) => {
|
||||||
|
store
|
||||||
|
.subscribe((state) => {
|
||||||
|
(state as any).core = Object.create({});
|
||||||
|
(state as any).core.auth = authState;
|
||||||
|
});
|
||||||
|
|
||||||
|
// create component and test fixture
|
||||||
|
fixture = TestBed.createComponent(LogInShibbolethComponent);
|
||||||
|
|
||||||
|
// get test component from the fixture
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
|
||||||
|
// create page
|
||||||
|
page = new Page(component, fixture);
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should display a link with properly href', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
const link = fixture.debugElement.query(By.css('a'));
|
||||||
|
expect(link.nativeElement.getAttribute('href')).toBe('dspace.test/shibboleth');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* I represent the DOM elements and attach spies.
|
||||||
|
*
|
||||||
|
* @class Page
|
||||||
|
*/
|
||||||
|
class Page {
|
||||||
|
|
||||||
|
public emailInput: HTMLInputElement;
|
||||||
|
public navigateSpy: jasmine.Spy;
|
||||||
|
public passwordInput: HTMLInputElement;
|
||||||
|
|
||||||
|
constructor(private component: LogInShibbolethComponent, private fixture: ComponentFixture<LogInShibbolethComponent>) {
|
||||||
|
// use injector to get services
|
||||||
|
const injector = fixture.debugElement.injector;
|
||||||
|
const store = injector.get(Store);
|
||||||
|
|
||||||
|
// add spies
|
||||||
|
this.navigateSpy = spyOn(store, 'dispatch');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,11 +1,11 @@
|
|||||||
import { Component, Inject, Input, OnInit, } from '@angular/core';
|
import { Component, Inject, OnInit, } from '@angular/core';
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { select, Store } from '@ngrx/store';
|
import { select, Store } from '@ngrx/store';
|
||||||
|
|
||||||
import { renderAuthMethodFor } from '../authMethods-decorator';
|
import { renderAuthMethodFor } from '../log-in.methods-decorator';
|
||||||
import { AuthMethodType } from '../authMethods-type';
|
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
|
||||||
import { AuthMethodModel } from '../../../../core/auth/models/auth-method.model';
|
import { AuthMethod } from '../../../../core/auth/models/auth.method';
|
||||||
|
|
||||||
import { CoreState } from '../../../../core/core.reducers';
|
import { CoreState } from '../../../../core/core.reducers';
|
||||||
import { isAuthenticated, isAuthenticationLoading } from '../../../../core/auth/selectors';
|
import { isAuthenticated, isAuthenticationLoading } from '../../../../core/auth/selectors';
|
||||||
@@ -19,7 +19,11 @@ import { isAuthenticated, isAuthenticationLoading } from '../../../../core/auth/
|
|||||||
@renderAuthMethodFor(AuthMethodType.Shibboleth)
|
@renderAuthMethodFor(AuthMethodType.Shibboleth)
|
||||||
export class LogInShibbolethComponent implements OnInit {
|
export class LogInShibbolethComponent implements OnInit {
|
||||||
|
|
||||||
@Input() authMethodModel: AuthMethodModel;
|
/**
|
||||||
|
* The authentication method data.
|
||||||
|
* @type {AuthMethod}
|
||||||
|
*/
|
||||||
|
public authMethod: AuthMethod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the authentication is loading.
|
* True if the authentication is loading.
|
||||||
@@ -41,12 +45,14 @@ export class LogInShibbolethComponent implements OnInit {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
|
* @param {AuthMethod} injectedAuthMethodModel
|
||||||
|
* @param {Store<State>} store
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
@Inject('authMethodModelProvider') public injectedAuthMethodModel: AuthMethodModel,
|
@Inject('authMethodProvider') public injectedAuthMethodModel: AuthMethod,
|
||||||
private store: Store<CoreState>
|
private store: Store<CoreState>
|
||||||
) {
|
) {
|
||||||
this.authMethodModel = injectedAuthMethodModel;
|
this.authMethod = injectedAuthMethodModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
@@ -171,9 +171,8 @@ import { PageWithSidebarComponent } from './sidebar/page-with-sidebar.component'
|
|||||||
import { SidebarDropdownComponent } from './sidebar/sidebar-dropdown.component';
|
import { SidebarDropdownComponent } from './sidebar/sidebar-dropdown.component';
|
||||||
import { SidebarFilterComponent } from './sidebar/filter/sidebar-filter.component';
|
import { SidebarFilterComponent } from './sidebar/filter/sidebar-filter.component';
|
||||||
import { SidebarFilterSelectedOptionComponent } from './sidebar/filter/sidebar-filter-selected-option.component';
|
import { SidebarFilterSelectedOptionComponent } from './sidebar/filter/sidebar-filter-selected-option.component';
|
||||||
import { MetadataRepresentationListComponent } from '../+item-page/simple/metadata-representation-list/metadata-representation-list.component';
|
|
||||||
import { SelectableListItemControlComponent } from './object-collection/shared/selectable-list-item-control/selectable-list-item-control.component';
|
import { SelectableListItemControlComponent } from './object-collection/shared/selectable-list-item-control/selectable-list-item-control.component';
|
||||||
import { LoginContainerComponent } from './log-in/container/login-container.component';
|
import { LogInContainerComponent } from './log-in/container/log-in-container.component';
|
||||||
import { LogInShibbolethComponent } from './log-in/methods/shibboleth/log-in-shibboleth.component';
|
import { LogInShibbolethComponent } from './log-in/methods/shibboleth/log-in-shibboleth.component';
|
||||||
import { LogInPasswordComponent } from './log-in/methods/password/log-in-password.component';
|
import { LogInPasswordComponent } from './log-in/methods/password/log-in-password.component';
|
||||||
import { LogInComponent } from './log-in/log-in.component';
|
import { LogInComponent } from './log-in/log-in.component';
|
||||||
@@ -336,7 +335,7 @@ const COMPONENTS = [
|
|||||||
SelectableListItemControlComponent,
|
SelectableListItemControlComponent,
|
||||||
LogInShibbolethComponent,
|
LogInShibbolethComponent,
|
||||||
LogInPasswordComponent,
|
LogInPasswordComponent,
|
||||||
LoginContainerComponent,
|
LogInContainerComponent,
|
||||||
ItemTypeBadgeComponent
|
ItemTypeBadgeComponent
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@@ -5,7 +5,6 @@ import { AuthTokenInfo } from '../../core/auth/models/auth-token-info.model';
|
|||||||
import { EPerson } from '../../core/eperson/models/eperson.model';
|
import { EPerson } from '../../core/eperson/models/eperson.model';
|
||||||
import { isNotEmpty } from '../empty.util';
|
import { isNotEmpty } from '../empty.util';
|
||||||
import { EPersonMock } from './eperson-mock';
|
import { EPersonMock } from './eperson-mock';
|
||||||
import { RemoteData } from '../../core/data/remote-data';
|
|
||||||
import { createSuccessfulRemoteDataObject$ } from './utils';
|
import { createSuccessfulRemoteDataObject$ } from './utils';
|
||||||
|
|
||||||
export class AuthRequestServiceStub {
|
export class AuthRequestServiceStub {
|
||||||
@@ -23,7 +22,7 @@ export class AuthRequestServiceStub {
|
|||||||
} else {
|
} else {
|
||||||
authStatusStub.authenticated = false;
|
authStatusStub.authenticated = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (isNotEmpty(options)) {
|
||||||
const token = (options.headers as any).lazyUpdate[1].value;
|
const token = (options.headers as any).lazyUpdate[1].value;
|
||||||
if (this.validateToken(token)) {
|
if (this.validateToken(token)) {
|
||||||
authStatusStub.authenticated = true;
|
authStatusStub.authenticated = true;
|
||||||
@@ -32,6 +31,8 @@ export class AuthRequestServiceStub {
|
|||||||
} else {
|
} else {
|
||||||
authStatusStub.authenticated = false;
|
authStatusStub.authenticated = false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
authStatusStub.authenticated = false;
|
||||||
}
|
}
|
||||||
return observableOf(authStatusStub);
|
return observableOf(authStatusStub);
|
||||||
}
|
}
|
||||||
|
@@ -3,8 +3,13 @@ import { AuthStatus } from '../../core/auth/models/auth-status.model';
|
|||||||
import { AuthTokenInfo } from '../../core/auth/models/auth-token-info.model';
|
import { AuthTokenInfo } from '../../core/auth/models/auth-token-info.model';
|
||||||
import { EPersonMock } from './eperson-mock';
|
import { EPersonMock } from './eperson-mock';
|
||||||
import { EPerson } from '../../core/eperson/models/eperson.model';
|
import { EPerson } from '../../core/eperson/models/eperson.model';
|
||||||
import { RemoteData } from '../../core/data/remote-data';
|
|
||||||
import { createSuccessfulRemoteDataObject$ } from './utils';
|
import { createSuccessfulRemoteDataObject$ } from './utils';
|
||||||
|
import { AuthMethod } from '../../core/auth/models/auth.method';
|
||||||
|
|
||||||
|
export const authMethodsMock = [
|
||||||
|
new AuthMethod('password'),
|
||||||
|
new AuthMethod('shibboleth', 'dspace.test/shibboleth')
|
||||||
|
];
|
||||||
|
|
||||||
export class AuthServiceStub {
|
export class AuthServiceStub {
|
||||||
|
|
||||||
@@ -103,4 +108,12 @@ export class AuthServiceStub {
|
|||||||
isAuthenticated() {
|
isAuthenticated() {
|
||||||
return observableOf(true);
|
return observableOf(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkAuthenticationCookie() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
retrieveAuthMethods(status: AuthStatus) {
|
||||||
|
return observableOf(authMethodsMock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user