mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-08 10:34:15 +00:00
Finalized auth module
This commit is contained in:
@@ -1,15 +0,0 @@
|
|||||||
.login-container {
|
|
||||||
height: 100%;
|
|
||||||
display: -ms-flexbox;
|
|
||||||
display: -webkit-box;
|
|
||||||
display: flex;
|
|
||||||
-ms-flex-align: center;
|
|
||||||
-ms-flex-pack: center;
|
|
||||||
-webkit-box-align: center;
|
|
||||||
align-items: center;
|
|
||||||
-webkit-box-pack: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding-top: 40px;
|
|
||||||
padding-bottom: 40px;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
}
|
|
||||||
|
@@ -25,7 +25,8 @@ export const AuthActionTypes = {
|
|||||||
LOG_OUT_SUCCESS: type('dspace/auth/LOG_OUT_SUCCESS'),
|
LOG_OUT_SUCCESS: type('dspace/auth/LOG_OUT_SUCCESS'),
|
||||||
REGISTRATION: type('dspace/auth/REGISTRATION'),
|
REGISTRATION: type('dspace/auth/REGISTRATION'),
|
||||||
REGISTRATION_ERROR: type('dspace/auth/REGISTRATION_ERROR'),
|
REGISTRATION_ERROR: type('dspace/auth/REGISTRATION_ERROR'),
|
||||||
REGISTRATION_SUCCESS: type('dspace/auth/REGISTRATION_SUCCESS')
|
REGISTRATION_SUCCESS: type('dspace/auth/REGISTRATION_SUCCESS'),
|
||||||
|
SET_REDIRECT_URL: type('dspace/auth/SET_REDIRECT_URL'),
|
||||||
};
|
};
|
||||||
|
|
||||||
/* tslint:disable:max-classes-per-file */
|
/* tslint:disable:max-classes-per-file */
|
||||||
@@ -251,6 +252,20 @@ export class ResetAuthenticationMessagesAction implements Action {
|
|||||||
public type: string = AuthActionTypes.RESET_MESSAGES;
|
public type: string = AuthActionTypes.RESET_MESSAGES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the redirect url.
|
||||||
|
* @class SetRedirectUrlAction
|
||||||
|
* @implements {Action}
|
||||||
|
*/
|
||||||
|
export class SetRedirectUrlAction implements Action {
|
||||||
|
public type: string = AuthActionTypes.SET_REDIRECT_URL;
|
||||||
|
payload: string;
|
||||||
|
|
||||||
|
constructor(url: string) {
|
||||||
|
this.payload = url ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* tslint:enable:max-classes-per-file */
|
/* tslint:enable:max-classes-per-file */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
import {
|
import {
|
||||||
AuthActions, AuthActionTypes, AuthenticatedSuccessAction, AuthenticationErrorAction,
|
AuthActions, AuthActionTypes, AuthenticatedSuccessAction, AuthenticationErrorAction,
|
||||||
AuthenticationSuccessAction, LogOutErrorAction, RedirectWhenAuthenticationIsRequiredAction,
|
AuthenticationSuccessAction, LogOutErrorAction, RedirectWhenAuthenticationIsRequiredAction,
|
||||||
RedirectWhenTokenExpiredAction
|
RedirectWhenTokenExpiredAction, SetRedirectUrlAction
|
||||||
} from './auth.actions';
|
} from './auth.actions';
|
||||||
|
|
||||||
// import models
|
// import models
|
||||||
@@ -29,6 +29,9 @@ export interface AuthState {
|
|||||||
// info message
|
// info message
|
||||||
info?: string;
|
info?: string;
|
||||||
|
|
||||||
|
// redirect url after login
|
||||||
|
redirectUrl?: string;
|
||||||
|
|
||||||
// the authenticated user
|
// the authenticated user
|
||||||
user?: Eperson;
|
user?: Eperson;
|
||||||
}
|
}
|
||||||
@@ -39,7 +42,7 @@ export interface AuthState {
|
|||||||
const initialState: AuthState = {
|
const initialState: AuthState = {
|
||||||
authenticated: false,
|
authenticated: false,
|
||||||
loaded: false,
|
loaded: false,
|
||||||
loading: false
|
loading: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -137,13 +140,18 @@ export function authReducer(state: any = initialState, action: AuthActions): Aut
|
|||||||
|
|
||||||
case AuthActionTypes.RESET_MESSAGES:
|
case AuthActionTypes.RESET_MESSAGES:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
authenticated: false,
|
authenticated: state.authenticated,
|
||||||
error: undefined,
|
error: undefined,
|
||||||
loaded: false,
|
loaded: state.loaded,
|
||||||
loading: false,
|
loading: state.loading,
|
||||||
info: undefined,
|
info: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
case AuthActionTypes.SET_REDIRECT_URL:
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
redirectUrl: (action as SetRedirectUrlAction).payload,
|
||||||
|
});
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
@@ -155,7 +163,7 @@ export function authReducer(state: any = initialState, action: AuthActions): Aut
|
|||||||
* @param {State} state
|
* @param {State} state
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export const isAuthenticated = (state: AuthState) => state.authenticated;
|
export const _isAuthenticated = (state: AuthState) => state.authenticated;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the authenticated has loaded.
|
* Returns true if the authenticated has loaded.
|
||||||
@@ -163,7 +171,7 @@ export const isAuthenticated = (state: AuthState) => state.authenticated;
|
|||||||
* @param {State} state
|
* @param {State} state
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export const isAuthenticatedLoaded = (state: AuthState) => state.loaded;
|
export const _isAuthenticatedLoaded = (state: AuthState) => state.loaded;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the users state
|
* Return the users state
|
||||||
@@ -171,23 +179,23 @@ export const isAuthenticatedLoaded = (state: AuthState) => state.loaded;
|
|||||||
* @param {State} state
|
* @param {State} state
|
||||||
* @returns {User}
|
* @returns {User}
|
||||||
*/
|
*/
|
||||||
export const getAuthenticatedUser = (state: AuthState) => state.user;
|
export const _getAuthenticatedUser = (state: AuthState) => state.user;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the authentication error.
|
* Returns the authentication error.
|
||||||
* @function getAuthenticationError
|
* @function getAuthenticationError
|
||||||
* @param {State} state
|
* @param {State} state
|
||||||
* @returns {String}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export const getAuthenticationError = (state: AuthState) => state.error;
|
export const _getAuthenticationError = (state: AuthState) => state.error;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the authentication info message.
|
* Returns the authentication info message.
|
||||||
* @function getAuthenticationInfo
|
* @function getAuthenticationInfo
|
||||||
* @param {State} state
|
* @param {State} state
|
||||||
* @returns {String}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export const getAuthenticationInfo = (state: AuthState) => state.info;
|
export const _getAuthenticationInfo = (state: AuthState) => state.info;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if request is in progress.
|
* Returns true if request is in progress.
|
||||||
@@ -195,20 +203,28 @@ export const getAuthenticationInfo = (state: AuthState) => state.info;
|
|||||||
* @param {State} state
|
* @param {State} state
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export const isLoading = (state: AuthState) => state.loading;
|
export const _isLoading = (state: AuthState) => state.loading;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sign out error.
|
* Returns the sign out error.
|
||||||
* @function getLogOutError
|
* @function getLogOutError
|
||||||
* @param {State} state
|
* @param {State} state
|
||||||
* @returns {Error}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export const getLogOutError = (state: AuthState) => state.error;
|
export const _getLogOutError = (state: AuthState) => state.error;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sign up error.
|
* Returns the sign up error.
|
||||||
* @function getRegistrationError
|
* @function getRegistrationError
|
||||||
* @param {State} state
|
* @param {State} state
|
||||||
* @returns {Error}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export const getRegistrationError = (state: AuthState) => state.error;
|
export const _getRegistrationError = (state: AuthState) => state.error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the redirect url.
|
||||||
|
* @function getRedirectUrl
|
||||||
|
* @param {State} state
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export const _getRedirectUrl = (state: AuthState) => state.redirectUrl;
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import { filter, map, withLatestFrom } from 'rxjs/operators';
|
||||||
|
|
||||||
import { Eperson } from '../eperson/models/eperson.model';
|
import { Eperson } from '../eperson/models/eperson.model';
|
||||||
import { AuthRequestService } from './auth-request.service';
|
import { AuthRequestService } from './auth-request.service';
|
||||||
@@ -10,10 +11,10 @@ import { AuthStatus } from './models/auth-status.model';
|
|||||||
import { AuthTokenInfo, TOKENITEM } from './models/auth-token-info.model';
|
import { AuthTokenInfo, TOKENITEM } from './models/auth-token-info.model';
|
||||||
import { isNotEmpty, isNotNull, isNotUndefined } from '../../shared/empty.util';
|
import { isNotEmpty, isNotNull, isNotUndefined } from '../../shared/empty.util';
|
||||||
import { CookieService } from '../../shared/services/cookie.service';
|
import { CookieService } from '../../shared/services/cookie.service';
|
||||||
import { isAuthenticated } from './selectors';
|
import { getRedirectUrl, isAuthenticated } from './selectors';
|
||||||
import { AppState, routerStateSelector } from '../../app.reducer';
|
import { AppState, routerStateSelector } from '../../app.reducer';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { ResetAuthenticationMessagesAction } from './auth.actions';
|
import { ResetAuthenticationMessagesAction, SetRedirectUrlAction } from './auth.actions';
|
||||||
import { RouterReducerState } from '@ngrx/router-store';
|
import { RouterReducerState } from '@ngrx/router-store';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
@@ -30,12 +31,6 @@ export class AuthService {
|
|||||||
*/
|
*/
|
||||||
private _authenticated: boolean;
|
private _authenticated: boolean;
|
||||||
|
|
||||||
/**
|
|
||||||
* The url to redirect after login
|
|
||||||
* @type string
|
|
||||||
*/
|
|
||||||
private _redirectUrl: string;
|
|
||||||
|
|
||||||
constructor(private authRequestService: AuthRequestService,
|
constructor(private authRequestService: AuthRequestService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private storage: CookieService,
|
private storage: CookieService,
|
||||||
@@ -46,16 +41,18 @@ export class AuthService {
|
|||||||
|
|
||||||
// If current route is different from the one setted in authentication guard
|
// If current route is different from the one setted in authentication guard
|
||||||
// and is not the login route, clear redirect url and messages
|
// and is not the login route, clear redirect url and messages
|
||||||
this.store.select(routerStateSelector)
|
const routeUrlObs = this.store.select(routerStateSelector)
|
||||||
.filter((routerState: RouterReducerState) => isNotUndefined(routerState))
|
.filter((routerState: RouterReducerState) => isNotUndefined(routerState) && isNotUndefined(routerState.state) )
|
||||||
.filter((routerState: RouterReducerState) =>
|
.filter((routerState: RouterReducerState) => (routerState.state.url !== LOGIN_ROUTE))
|
||||||
(routerState.state.url !== LOGIN_ROUTE)
|
.map((routerState: RouterReducerState) => routerState.state.url);
|
||||||
&& isNotEmpty(this._redirectUrl)
|
const redirectUrlObs = this.getRedirectUrl();
|
||||||
&& (routerState.state.url !== this._redirectUrl))
|
routeUrlObs.pipe(
|
||||||
.distinctUntilChanged()
|
withLatestFrom(redirectUrlObs),
|
||||||
|
map(([routeUrl, redirectUrl]) => [routeUrl, redirectUrl])
|
||||||
|
).filter(([routeUrl, redirectUrl]) => isNotEmpty(redirectUrl) && (routeUrl !== redirectUrl))
|
||||||
.subscribe(() => {
|
.subscribe(() => {
|
||||||
this._redirectUrl = '';
|
this.setRedirectUrl('');
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,7 +132,7 @@ export class AuthService {
|
|||||||
// Normally you would do an HTTP request to POST the user
|
// Normally you would do an HTTP request to POST the user
|
||||||
// details and then return the new user object
|
// details and then return the new user object
|
||||||
// but, let's just return the new user for this example.
|
// but, let's just return the new user for this example.
|
||||||
this._authenticated = true;
|
// this._authenticated = true;
|
||||||
return Observable.of(user);
|
return Observable.of(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,14 +207,18 @@ export class AuthService {
|
|||||||
* Redirect to the route navigated before the login
|
* Redirect to the route navigated before the login
|
||||||
*/
|
*/
|
||||||
public redirectToPreviousUrl() {
|
public redirectToPreviousUrl() {
|
||||||
if (isNotEmpty(this._redirectUrl)) {
|
this.getRedirectUrl()
|
||||||
const url = this._redirectUrl;
|
.first()
|
||||||
|
.subscribe((redirectUrl) => {
|
||||||
|
if (isNotEmpty(redirectUrl)) {
|
||||||
// Clear url
|
// Clear url
|
||||||
this._redirectUrl = null;
|
this.setRedirectUrl(undefined);
|
||||||
this.router.navigate([url]);
|
this.router.navigate([decodeURI(redirectUrl)]);
|
||||||
} else {
|
} else {
|
||||||
this.router.navigate(['/']);
|
this.router.navigate(['/']);
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -227,7 +228,7 @@ export class AuthService {
|
|||||||
this.store.select(routerStateSelector)
|
this.store.select(routerStateSelector)
|
||||||
.take(1)
|
.take(1)
|
||||||
.subscribe((router) => {
|
.subscribe((router) => {
|
||||||
// TODO Chack a way to hard refresh the same route
|
// TODO Check a way to hard refresh the same route
|
||||||
// this.router.navigate([router.state.url], { replaceUrl: true });
|
// this.router.navigate([router.state.url], { replaceUrl: true });
|
||||||
this.router.navigate(['/']);
|
this.router.navigate(['/']);
|
||||||
})
|
})
|
||||||
@@ -236,14 +237,14 @@ export class AuthService {
|
|||||||
/**
|
/**
|
||||||
* Get redirect url
|
* Get redirect url
|
||||||
*/
|
*/
|
||||||
get redirectUrl(): string {
|
getRedirectUrl(): Observable<string> {
|
||||||
return this._redirectUrl;
|
return this.store.select(getRedirectUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set redirect url
|
* Set redirect url
|
||||||
*/
|
*/
|
||||||
set redirectUrl(value: string) {
|
setRedirectUrl(value: string) {
|
||||||
this._redirectUrl = value;
|
this.store.dispatch(new SetRedirectUrlAction(encodeURI(value)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -59,9 +59,9 @@ export class AuthenticatedGuard implements CanActivate, CanLoad {
|
|||||||
// .filter(() => isEmpty(this.router.routerState.snapshot.url) || this.router.routerState.snapshot.url === url)
|
// .filter(() => isEmpty(this.router.routerState.snapshot.url) || this.router.routerState.snapshot.url === url)
|
||||||
.take(1)
|
.take(1)
|
||||||
.subscribe((authenticated) => {
|
.subscribe((authenticated) => {
|
||||||
console.log('handleAuth', url, this.router.routerState.snapshot.url);
|
|
||||||
if (!authenticated) {
|
if (!authenticated) {
|
||||||
this.authService.redirectUrl = url;
|
console.log('set redirect ', url);
|
||||||
|
this.authService.setRedirectUrl(url);
|
||||||
this.store.dispatch(new RedirectWhenAuthenticationIsRequiredAction('Login required'));
|
this.store.dispatch(new RedirectWhenAuthenticationIsRequiredAction('Login required'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -27,7 +27,7 @@ export const getAuthState = (state: any) => state.core.auth;
|
|||||||
* @param {any} props
|
* @param {any} props
|
||||||
* @return {User}
|
* @return {User}
|
||||||
*/
|
*/
|
||||||
export const getAuthenticatedUser = createSelector(getAuthState, auth.getAuthenticatedUser);
|
export const getAuthenticatedUser = createSelector(getAuthState, auth._getAuthenticatedUser);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the authentication error.
|
* Returns the authentication error.
|
||||||
@@ -36,7 +36,7 @@ export const getAuthenticatedUser = createSelector(getAuthState, auth.getAuthent
|
|||||||
* @param {any} props
|
* @param {any} props
|
||||||
* @return {Error}
|
* @return {Error}
|
||||||
*/
|
*/
|
||||||
export const getAuthenticationError = createSelector(getAuthState, auth.getAuthenticationError);
|
export const getAuthenticationError = createSelector(getAuthState, auth._getAuthenticationError);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the authentication info message.
|
* Returns the authentication info message.
|
||||||
@@ -45,7 +45,7 @@ export const getAuthenticationError = createSelector(getAuthState, auth.getAuthe
|
|||||||
* @param {any} props
|
* @param {any} props
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
export const getAuthenticationInfo = createSelector(getAuthState, auth.getAuthenticationInfo);
|
export const getAuthenticationInfo = createSelector(getAuthState, auth._getAuthenticationInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the user is authenticated
|
* Returns true if the user is authenticated
|
||||||
@@ -54,7 +54,7 @@ export const getAuthenticationInfo = createSelector(getAuthState, auth.getAuthen
|
|||||||
* @param {any} props
|
* @param {any} props
|
||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
export const isAuthenticated = createSelector(getAuthState, auth.isAuthenticated);
|
export const isAuthenticated = createSelector(getAuthState, auth._isAuthenticated);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the user is authenticated
|
* Returns true if the user is authenticated
|
||||||
@@ -63,7 +63,7 @@ export const isAuthenticated = createSelector(getAuthState, auth.isAuthenticated
|
|||||||
* @param {any} props
|
* @param {any} props
|
||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
export const isAuthenticatedLoaded = createSelector(getAuthState, auth.isAuthenticatedLoaded);
|
export const isAuthenticatedLoaded = createSelector(getAuthState, auth._isAuthenticatedLoaded);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the authentication request is loading.
|
* Returns true if the authentication request is loading.
|
||||||
@@ -72,7 +72,7 @@ export const isAuthenticatedLoaded = createSelector(getAuthState, auth.isAuthent
|
|||||||
* @param {any} props
|
* @param {any} props
|
||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
export const isAuthenticationLoading = createSelector(getAuthState, auth.isLoading);
|
export const isAuthenticationLoading = createSelector(getAuthState, auth._isLoading);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the log out error.
|
* Returns the log out error.
|
||||||
@@ -81,7 +81,7 @@ export const isAuthenticationLoading = createSelector(getAuthState, auth.isLoadi
|
|||||||
* @param {any} props
|
* @param {any} props
|
||||||
* @return {Error}
|
* @return {Error}
|
||||||
*/
|
*/
|
||||||
export const getLogOutError = createSelector(getAuthState, auth.getLogOutError);
|
export const getLogOutError = createSelector(getAuthState, auth._getLogOutError);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the registration error.
|
* Returns the registration error.
|
||||||
@@ -90,4 +90,13 @@ export const getLogOutError = createSelector(getAuthState, auth.getLogOutError);
|
|||||||
* @param {any} props
|
* @param {any} props
|
||||||
* @return {Error}
|
* @return {Error}
|
||||||
*/
|
*/
|
||||||
export const getRegistrationError = createSelector(getAuthState, auth.getRegistrationError);
|
export const getRegistrationError = createSelector(getAuthState, auth._getRegistrationError);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the redirect url..
|
||||||
|
* @function getRedirectUrl
|
||||||
|
* @param {AuthState} state
|
||||||
|
* @param {any} props
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
export const getRedirectUrl = createSelector(getAuthState, auth._getRedirectUrl);
|
||||||
|
@@ -1,11 +1,9 @@
|
|||||||
|
|
||||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||||
import { Observable } from 'rxjs/Observable';
|
import { Observable } from 'rxjs/Observable';
|
||||||
import { RouterReducerState } from '@ngrx/router-store';
|
import { RouterReducerState } from '@ngrx/router-store';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
|
|
||||||
import { fadeInOut, fadeOut } from '../animations/fade';
|
import { fadeInOut, fadeOut } from '../animations/fade';
|
||||||
import { CoreState } from '../../core/core.reducers';
|
|
||||||
import { HostWindowService } from '../host-window.service';
|
import { HostWindowService } from '../host-window.service';
|
||||||
import { AppState, routerStateSelector } from '../../app.reducer';
|
import { AppState, routerStateSelector } from '../../app.reducer';
|
||||||
import { hasValue, isNotUndefined } from '../empty.util';
|
import { hasValue, isNotUndefined } from '../empty.util';
|
||||||
@@ -32,8 +30,7 @@ export class AuthNavMenuComponent implements OnDestroy, OnInit {
|
|||||||
|
|
||||||
protected subs: Subscription[] = [];
|
protected subs: Subscription[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(private store: Store<AppState>,
|
||||||
private store: Store<AppState>,
|
|
||||||
public windowService: HostWindowService) {
|
public windowService: HostWindowService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +41,7 @@ export class AuthNavMenuComponent implements OnDestroy, OnInit {
|
|||||||
this.user = this.store.select(getAuthenticatedUser);
|
this.user = this.store.select(getAuthenticatedUser);
|
||||||
|
|
||||||
this.subs.push(this.store.select(routerStateSelector)
|
this.subs.push(this.store.select(routerStateSelector)
|
||||||
.filter((router: RouterReducerState) => isNotUndefined(router))
|
.filter((router: RouterReducerState) => isNotUndefined(router) && isNotUndefined(router.state))
|
||||||
.subscribe((router: RouterReducerState) => {
|
.subscribe((router: RouterReducerState) => {
|
||||||
this.showAuth = router.state.url !== '/login';
|
this.showAuth = router.state.url !== '/login';
|
||||||
}));
|
}));
|
||||||
|
@@ -8,8 +8,7 @@
|
|||||||
formControlName="email"
|
formControlName="email"
|
||||||
placeholder="{{'login.form.email' | translate}}"
|
placeholder="{{'login.form.email' | translate}}"
|
||||||
required
|
required
|
||||||
type="email"
|
type="email">
|
||||||
(input)="resetErrorOrMessage($event)">
|
|
||||||
<label for="inputPassword" class="sr-only">{{"login.form.password" | translate}}</label>
|
<label for="inputPassword" class="sr-only">{{"login.form.password" | translate}}</label>
|
||||||
<input id="inputPassword"
|
<input id="inputPassword"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
@@ -17,9 +16,8 @@
|
|||||||
placeholder="{{'login.form.password' | translate}}"
|
placeholder="{{'login.form.password' | translate}}"
|
||||||
formControlName="password"
|
formControlName="password"
|
||||||
required
|
required
|
||||||
type="password"
|
type="password">
|
||||||
(input)="resetErrorOrMessage($event)">
|
<div *ngIf="platform.isBrowser && (error | async) && hasError" class="alert alert-danger" role="alert" @fadeOut>{{ error | async }}</div>
|
||||||
<div *ngIf="(error | async) && hasError" class="alert alert-danger" role="alert" @fadeOut>{{ error | async }}</div>
|
|
||||||
<div *ngIf="(message | async) && hasMessage" class="alert alert-info" role="alert" @fadeOut>{{ message | async }}</div>
|
<div *ngIf="(message | async) && hasMessage" class="alert alert-info" role="alert" @fadeOut>{{ message | async }}</div>
|
||||||
<button class="btn btn-lg btn-primary btn-block mt-3" type="submit" [disabled]="!form.valid">{{"login.form.submit" | translate}}</button>
|
<button class="btn btn-lg btn-primary btn-block mt-3" type="submit" [disabled]="!form.valid">{{"login.form.submit" | translate}}</button>
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
|
@@ -1,25 +1,25 @@
|
|||||||
/* tslint:disable:no-unused-variable */
|
/* tslint:disable:no-unused-variable */
|
||||||
import { CUSTOM_ELEMENTS_SCHEMA, DebugElement } from "@angular/core";
|
/*import { CUSTOM_ELEMENTS_SCHEMA, DebugElement } from '@angular/core';
|
||||||
import { ComponentFixture, TestBed, async } from "@angular/core/testing";
|
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
|
||||||
import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule } from "@angular/forms";
|
import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { MaterialModule } from "@angular/material";
|
import { MaterialModule } from '@angular/material';
|
||||||
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 { go } from "@ngrx/router-store";
|
import { go } from '@ngrx/router-store';
|
||||||
|
|
||||||
// reducers
|
// reducers
|
||||||
import { reducer } from "../../app.reducers";
|
import { reducer } from '../../app.reducers';
|
||||||
|
|
||||||
// models
|
// models
|
||||||
import { User } from "../../core/models/user";
|
import { User } from '../../core/models/user';
|
||||||
|
|
||||||
// services
|
// services
|
||||||
import { MOCK_USER } from "../../core/services/user.service";
|
import { MOCK_USER } from '../../core/services/user.service';
|
||||||
|
|
||||||
// this component to test
|
// this component to test
|
||||||
import { LogInComponent } from "./log-in.component";
|
import { LogInComponent } from './log-in.component';
|
||||||
|
|
||||||
describe("LogInComponent", () => {
|
describe('LogInComponent', () => {
|
||||||
|
|
||||||
let component: LogInComponent;
|
let component: LogInComponent;
|
||||||
let fixture: ComponentFixture<LogInComponent>;
|
let fixture: ComponentFixture<LogInComponent>;
|
||||||
@@ -65,23 +65,23 @@ describe("LogInComponent", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should create a FormGroup comprised of FormControls", () => {
|
it('should create a FormGroup comprised of FormControls', () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(component.form instanceof FormGroup).toBe(true);
|
expect(component.form instanceof FormGroup).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should authenticate", () => {
|
it('should authenticate', () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
// set FormControl values
|
// set FormControl values
|
||||||
component.form.controls["email"].setValue(user.email);
|
component.form.controls['email'].setValue(user.email);
|
||||||
component.form.controls["password"].setValue(user.password);
|
component.form.controls['password'].setValue(user.password);
|
||||||
|
|
||||||
// submit form
|
// submit form
|
||||||
component.submit();
|
component.submit();
|
||||||
|
|
||||||
// verify Store.dispatch() is invoked
|
// verify Store.dispatch() is invoked
|
||||||
expect(page.navigateSpy.calls.any()).toBe(true, "Store.dispatch not invoked");
|
expect(page.navigateSpy.calls.any()).toBe(true, 'Store.dispatch not invoked');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -90,6 +90,7 @@ describe("LogInComponent", () => {
|
|||||||
*
|
*
|
||||||
* @class Page
|
* @class Page
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
class Page {
|
class Page {
|
||||||
|
|
||||||
public emailInput: HTMLInputElement;
|
public emailInput: HTMLInputElement;
|
||||||
@@ -102,15 +103,16 @@ class Page {
|
|||||||
const store = injector.get(Store);
|
const store = injector.get(Store);
|
||||||
|
|
||||||
// add spies
|
// add spies
|
||||||
this.navigateSpy = spyOn(store, "dispatch");
|
this.navigateSpy = spyOn(store, 'dispatch');
|
||||||
}
|
}
|
||||||
|
|
||||||
public addPageElements() {
|
public addPageElements() {
|
||||||
const emailInputSelector = "input[formcontrolname=\"email\"]";
|
const emailInputSelector = 'input[formcontrolname=\'email\']';
|
||||||
// console.log(this.fixture.debugElement.query(By.css(emailInputSelector)));
|
// console.log(this.fixture.debugElement.query(By.css(emailInputSelector)));
|
||||||
this.emailInput = this.fixture.debugElement.query(By.css(emailInputSelector)).nativeElement;
|
this.emailInput = this.fixture.debugElement.query(By.css(emailInputSelector)).nativeElement;
|
||||||
|
|
||||||
const passwordInputSelector = "input[formcontrolname=\"password\"]";
|
const passwordInputSelector = 'input[formcontrolname=\'password\']';
|
||||||
this.passwordInput = this.fixture.debugElement.query(By.css(passwordInputSelector)).nativeElement;
|
this.passwordInput = this.fixture.debugElement.query(By.css(passwordInputSelector)).nativeElement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
@@ -23,6 +23,7 @@ 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 { AuthService } from '../../core/auth/auth.service';
|
import { AuthService } from '../../core/auth/auth.service';
|
||||||
|
import { PlatformService } from '../services/platform.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /users/sign-in
|
* /users/sign-in
|
||||||
@@ -87,6 +88,7 @@ export class LogInComponent implements OnDestroy, OnInit {
|
|||||||
constructor(
|
constructor(
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
|
private platform: PlatformService,
|
||||||
private store: Store<CoreState>
|
private store: Store<CoreState>
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
@@ -160,6 +162,7 @@ export class LogInComponent implements OnDestroy, OnInit {
|
|||||||
* @method submit
|
* @method submit
|
||||||
*/
|
*/
|
||||||
public submit() {
|
public submit() {
|
||||||
|
this.resetErrorOrMessage();
|
||||||
// get email and password values
|
// get email and password values
|
||||||
const email: string = this.form.get('email').value;
|
const email: string = this.form.get('email').value;
|
||||||
const password: string = this.form.get('password').value;
|
const password: string = this.form.get('password').value;
|
||||||
|
@@ -1,19 +1,19 @@
|
|||||||
/* tslint:disable:no-unused-variable */
|
/* tslint:disable:no-unused-variable */
|
||||||
import { DebugElement, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
|
/*import { DebugElement, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||||
import { async, ComponentFixture, TestBed } from "@angular/core/testing";
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { By } from "@angular/platform-browser";
|
import { By } from '@angular/platform-browser';
|
||||||
import { Router } from "@angular/router";
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
// import ngrx
|
// import ngrx
|
||||||
import { Store, StoreModule } from "@ngrx/store";
|
import { Store, StoreModule } from '@ngrx/store';
|
||||||
|
|
||||||
// reducers
|
// reducers
|
||||||
import { reducer } from "../../app.reducers";
|
import { reducer } from '../../app.reducers';
|
||||||
|
|
||||||
// test this component
|
// test this component
|
||||||
import { SignOutComponent } from "./log-out.component";
|
import { SignOutComponent } from './log-out.component';
|
||||||
|
|
||||||
describe("Component: Signout", () => {
|
describe('Component: Signout', () => {
|
||||||
let component: SignOutComponent;
|
let component: SignOutComponent;
|
||||||
let fixture: ComponentFixture<SignOutComponent>;
|
let fixture: ComponentFixture<SignOutComponent>;
|
||||||
|
|
||||||
@@ -39,7 +39,8 @@ describe("Component: Signout", () => {
|
|||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it("should create an instance", () => {
|
it('should create an instance', () => {
|
||||||
expect(component).toBeTruthy();
|
expect(component).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
|
@@ -3,6 +3,8 @@ export const ROUTES: string[] = [
|
|||||||
'items/:id',
|
'items/:id',
|
||||||
'collections/:id',
|
'collections/:id',
|
||||||
'communities/:id',
|
'communities/:id',
|
||||||
|
'login',
|
||||||
|
'logout',
|
||||||
'search',
|
'search',
|
||||||
'**'
|
'**'
|
||||||
];
|
];
|
||||||
|
Reference in New Issue
Block a user