mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
fixed auth module
This commit is contained in:
@@ -17,6 +17,9 @@ import { MetadataService } from './core/metadata/metadata.service';
|
||||
import { HostWindowResizeAction } from './shared/host-window.actions';
|
||||
import { HostWindowState } from './shared/host-window.reducer';
|
||||
import { NativeWindowRef, NativeWindowService } from './shared/services/window.service';
|
||||
import { CheckAuthenticationTokenAction } from './core/auth/auth.actions';
|
||||
import { isAuthenticated } from './core/auth/selectors';
|
||||
import { PlatformService } from './shared/services/platform.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-app',
|
||||
@@ -32,7 +35,8 @@ export class AppComponent implements OnInit {
|
||||
@Inject(NativeWindowService) private _window: NativeWindowRef,
|
||||
private translate: TranslateService,
|
||||
private store: Store<HostWindowState>,
|
||||
private metadata: MetadataService
|
||||
private metadata: MetadataService,
|
||||
private platformService: PlatformService
|
||||
) {
|
||||
// this language will be used as a fallback when a translation isn't found in the current language
|
||||
translate.setDefaultLang('en');
|
||||
@@ -51,6 +55,12 @@ export class AppComponent implements OnInit {
|
||||
const color: string = this.config.production ? 'red' : 'green';
|
||||
console.info(`Environment: %c${env}`, `color: ${color}; font-weight: bold;`);
|
||||
this.dispatchWindowSize(this._window.nativeWindow.innerWidth, this._window.nativeWindow.innerHeight);
|
||||
if (this.platformService.isServer) {
|
||||
this.store.select(isAuthenticated)
|
||||
.take(1)
|
||||
.filter((authenticated) => !authenticated)
|
||||
.subscribe((authenticated) => this.store.dispatch(new CheckAuthenticationTokenAction()));
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('window:resize', ['$event'])
|
||||
|
@@ -31,6 +31,7 @@ export class AuthRequestService extends HALEndpointService {
|
||||
protected fetchRequest(request: RestRequest): Observable<any> {
|
||||
const [successResponse, errorResponse] = this.responseCache.get(request.href)
|
||||
.map((entry: ResponseCacheEntry) => entry.response)
|
||||
.do(() => this.responseCache.remove(request.href))
|
||||
.partition((response: RestResponse) => response.isSuccessful);
|
||||
return Observable.merge(
|
||||
errorResponse.flatMap((response: ErrorResponse) =>
|
||||
|
@@ -36,10 +36,10 @@ export class AuthResponseParsingService extends BaseResponseParsingService imple
|
||||
}
|
||||
|
||||
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
||||
if (isNotEmpty(data.payload) && isNotEmpty(data.payload._links) && data.statusCode === '200') {
|
||||
if (isNotEmpty(data.payload) && isNotEmpty(data.payload._links) && (data.statusCode === '200' || data.statusCode === 'OK')) {
|
||||
const response = this.process<AuthStatus,AuthType>(data.payload, request.href);
|
||||
return new AuthStatusResponse(response[Object.keys(response)[0]][0], data.statusCode);
|
||||
} else if (isEmpty(data.payload) && isNotEmpty(data.headers.get('authorization')) && data.statusCode === '200') {
|
||||
} else if (isEmpty(data.payload) && isNotEmpty(data.headers.get('authorization')) && (data.statusCode === '200' || data.statusCode === 'OK')) {
|
||||
return new AuthSuccessResponse(new AuthTokenInfo(data.headers.get('authorization')), data.statusCode);
|
||||
} else {
|
||||
return new AuthStatusResponse(data.payload as AuthStatus, data.statusCode);
|
||||
|
@@ -1,34 +0,0 @@
|
||||
import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
|
||||
import { isPlatformBrowser } from '@angular/common';
|
||||
|
||||
/**
|
||||
* The auth service.
|
||||
*/
|
||||
@Injectable()
|
||||
export class AuthStorageService {
|
||||
|
||||
constructor(@Inject(PLATFORM_ID) private platformId: string) {}
|
||||
|
||||
public get(key: string): any {
|
||||
let item = null;
|
||||
if (isPlatformBrowser(this.platformId)) {
|
||||
item = JSON.parse(localStorage.getItem(key));
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public store(key: string, item: any) {
|
||||
if (isPlatformBrowser(this.platformId)) {
|
||||
localStorage.setItem(key, JSON.stringify(item));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public remove(key: string) {
|
||||
if (isPlatformBrowser(this.platformId)) {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@@ -15,6 +15,8 @@ export const AuthActionTypes = {
|
||||
AUTHENTICATED: type('dspace/auth/AUTHENTICATED'),
|
||||
AUTHENTICATED_ERROR: type('dspace/auth/AUTHENTICATED_ERROR'),
|
||||
AUTHENTICATED_SUCCESS: type('dspace/auth/AUTHENTICATED_SUCCESS'),
|
||||
CHECK_AUTHENTICATION_TOKEN: type('dspace/auth/CHECK_AUTHENTICATION_TOKEN'),
|
||||
CHECK_AUTHENTICATION_TOKEN_ERROR: type('dspace/auth/CHECK_AUTHENTICATION_TOKEN_ERROR'),
|
||||
RESET_ERROR: type('dspace/auth/RESET_ERROR'),
|
||||
LOG_OUT: type('dspace/auth/LOG_OUT'),
|
||||
LOG_OUT_ERROR: type('dspace/auth/LOG_OUT_ERROR'),
|
||||
@@ -116,6 +118,24 @@ export class AuthenticationSuccessAction implements Action {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if token is already present upon initial load.
|
||||
* @class CheckAuthenticationTokenAction
|
||||
* @implements {Action}
|
||||
*/
|
||||
export class CheckAuthenticationTokenAction implements Action {
|
||||
public type: string = AuthActionTypes.CHECK_AUTHENTICATION_TOKEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check Authentication Token Error.
|
||||
* @class CheckAuthenticationTokenErrorAction
|
||||
* @implements {Action}
|
||||
*/
|
||||
export class CheckAuthenticationTokenErrorAction implements Action {
|
||||
public type: string = AuthActionTypes.CHECK_AUTHENTICATION_TOKEN_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset error.
|
||||
* @class ResetAuthenticationErrorAction
|
||||
@@ -215,6 +235,8 @@ export type AuthActions
|
||||
| AuthenticatedSuccessAction
|
||||
| AuthenticationErrorAction
|
||||
| AuthenticationSuccessAction
|
||||
| CheckAuthenticationTokenAction
|
||||
| CheckAuthenticationTokenErrorAction
|
||||
| RegistrationAction
|
||||
| RegistrationErrorAction
|
||||
| RegistrationSuccessAction;
|
||||
|
@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
|
||||
|
||||
// import @ngrx
|
||||
import { Effect, Actions } from '@ngrx/effects';
|
||||
import { Action } from '@ngrx/store';
|
||||
import { Action, Store } from '@ngrx/store';
|
||||
|
||||
// import rxjs
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
AuthenticatedErrorAction,
|
||||
AuthenticatedSuccessAction,
|
||||
AuthenticationErrorAction,
|
||||
AuthenticationSuccessAction, LogOutAction,
|
||||
AuthenticationSuccessAction, CheckAuthenticationTokenAction, CheckAuthenticationTokenErrorAction, LogOutAction,
|
||||
LogOutErrorAction,
|
||||
LogOutSuccessAction, RegistrationAction,
|
||||
RegistrationErrorAction,
|
||||
@@ -24,6 +24,10 @@ import {
|
||||
} from './auth.actions';
|
||||
import { Eperson } from '../eperson/models/eperson.model';
|
||||
import { AuthStatus } from './models/auth-status.model';
|
||||
import { AuthTokenInfo } from './models/auth-token-info.model';
|
||||
import { AppState } from '../../app.reducer';
|
||||
import { isAuthenticated } from './selectors';
|
||||
import { StoreActionTypes } from '../../store.actions';
|
||||
|
||||
@Injectable()
|
||||
export class AuthEffects {
|
||||
@@ -46,12 +50,7 @@ export class AuthEffects {
|
||||
public authenticateSuccess: Observable<Action> = this.actions$
|
||||
.ofType(AuthActionTypes.AUTHENTICATE_SUCCESS)
|
||||
.do((action: AuthenticationSuccessAction) => this.authService.storeToken(action.payload))
|
||||
.map((action: AuthenticationSuccessAction) => new AuthenticatedAction(action.payload))
|
||||
|
||||
@Effect({dispatch: false})
|
||||
public logOutSuccess: Observable<Action> = this.actions$
|
||||
.ofType(AuthActionTypes.LOG_OUT_SUCCESS)
|
||||
.do((action: LogOutSuccessAction) => this.authService.removeToken());
|
||||
.map((action: AuthenticationSuccessAction) => new AuthenticatedAction(action.payload));
|
||||
|
||||
@Effect()
|
||||
public authenticated: Observable<Action> = this.actions$
|
||||
@@ -62,6 +61,20 @@ export class AuthEffects {
|
||||
.catch((error) => Observable.of(new AuthenticatedErrorAction(error)));
|
||||
});
|
||||
|
||||
@Effect({dispatch: false})
|
||||
public authenticatedError: Observable<Action> = this.actions$
|
||||
.ofType(AuthActionTypes.AUTHENTICATED_ERROR)
|
||||
.do((action: LogOutSuccessAction) => this.authService.removeToken());
|
||||
|
||||
@Effect()
|
||||
public checkToken: Observable<Action> = this.actions$
|
||||
.ofType(AuthActionTypes.CHECK_AUTHENTICATION_TOKEN)
|
||||
.switchMap(() => {
|
||||
return this.authService.checkAuthenticationToken()
|
||||
.map((token: AuthTokenInfo) => new AuthenticatedAction(token))
|
||||
.catch((error) => Observable.of(new CheckAuthenticationTokenErrorAction()));
|
||||
});
|
||||
|
||||
@Effect()
|
||||
public createUser: Observable<Action> = this.actions$
|
||||
.ofType(AuthActionTypes.REGISTRATION)
|
||||
@@ -72,21 +85,41 @@ export class AuthEffects {
|
||||
.catch((error) => Observable.of(new RegistrationErrorAction(error)));
|
||||
});
|
||||
|
||||
/**
|
||||
* When the store is rehydrated in the browser,
|
||||
* clear a possible invalid token
|
||||
*/
|
||||
@Effect({dispatch: false})
|
||||
public clearInvalidTokenOnRehydrate = this.actions$
|
||||
.ofType(StoreActionTypes.REHYDRATE)
|
||||
.switchMap(() => {
|
||||
return this.store.select(isAuthenticated)
|
||||
.take(1)
|
||||
.filter((authenticated) => !authenticated)
|
||||
.do(() => this.authService.removeToken());
|
||||
});
|
||||
|
||||
@Effect()
|
||||
public signOut: Observable<Action> = this.actions$
|
||||
public logOut: Observable<Action> = this.actions$
|
||||
.ofType(AuthActionTypes.LOG_OUT)
|
||||
.switchMap((action: LogOutAction) => {
|
||||
return this.authService.signout()
|
||||
.switchMap(() => {
|
||||
return this.authService.logout()
|
||||
.map((value) => new LogOutSuccessAction())
|
||||
.catch((error) => Observable.of(new LogOutErrorAction(error)));
|
||||
});
|
||||
|
||||
@Effect({dispatch: false})
|
||||
public logOutSuccess: Observable<Action> = this.actions$
|
||||
.ofType(AuthActionTypes.LOG_OUT_SUCCESS)
|
||||
.do((action: LogOutSuccessAction) => this.authService.removeToken());
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {Actions} actions$
|
||||
* @param {AuthService} authService
|
||||
*/
|
||||
constructor(private actions$: Actions,
|
||||
private authService: AuthService) {
|
||||
private authService: AuthService,
|
||||
private store: Store<AppState>) {
|
||||
}
|
||||
}
|
||||
|
@@ -23,6 +23,10 @@ export class AuthInterceptor implements HttpInterceptor {
|
||||
return status === 401 || status === 403;
|
||||
}
|
||||
|
||||
private isAuthRequest(url: string): boolean {
|
||||
return url.endsWith('/authn/login') || url.endsWith('/authn/logout') || url.endsWith('/authn/status');
|
||||
}
|
||||
|
||||
private isLoginResponse(url: string): boolean {
|
||||
return url.endsWith('/authn/login');
|
||||
}
|
||||
@@ -40,7 +44,7 @@ export class AuthInterceptor implements HttpInterceptor {
|
||||
authStatus.token = new AuthTokenInfo(accessToken);
|
||||
} else {
|
||||
authStatus.authenticated = false;
|
||||
authStatus.error = JSON.parse(error);
|
||||
authStatus.error = isNotEmpty(error) ? JSON.parse(error) : null;
|
||||
}
|
||||
return authStatus;
|
||||
}
|
||||
@@ -53,11 +57,11 @@ export class AuthInterceptor implements HttpInterceptor {
|
||||
const Authorization = authService.getAuthHeader();
|
||||
|
||||
let authReq;
|
||||
if (isNotEmpty(Authorization)) {
|
||||
if (!this.isAuthRequest(req.url) && isNotEmpty(Authorization)) {
|
||||
// Clone the request to add the new header.
|
||||
authReq = req.clone({headers: req.headers.set('authorization', Authorization)});
|
||||
} else {
|
||||
authReq = req.clone();
|
||||
authReq = req;
|
||||
}
|
||||
|
||||
// Pass on the cloned request instead of the original request.
|
||||
@@ -67,6 +71,7 @@ export class AuthInterceptor implements HttpInterceptor {
|
||||
let authRes: HttpResponse<any>;
|
||||
if (this.isLoginResponse(response.url)) {
|
||||
const token = response.headers.get('authorization');
|
||||
const expires = response.headers.get('expires');
|
||||
authRes = response.clone({body: this.makeAuthStatusObject(true, token)});
|
||||
} else {
|
||||
authRes = response.clone({body: this.makeAuthStatusObject(false)});
|
||||
|
@@ -6,7 +6,6 @@ import {
|
||||
|
||||
// import models
|
||||
import { Eperson } from '../eperson/models/eperson.model';
|
||||
import { AuthTokenInfo } from './models/auth-token-info.model';
|
||||
|
||||
/**
|
||||
* The auth state.
|
||||
@@ -26,9 +25,6 @@ export interface AuthState {
|
||||
// true when loading
|
||||
loading: boolean;
|
||||
|
||||
// access token
|
||||
token?: AuthTokenInfo;
|
||||
|
||||
// the authenticated user
|
||||
user?: Eperson;
|
||||
}
|
||||
@@ -61,7 +57,8 @@ export function authReducer(state: any = initialState, action: AuthActions): Aut
|
||||
return Object.assign({}, state, {
|
||||
authenticated: false,
|
||||
error: (action as AuthenticationErrorAction).payload.message,
|
||||
loaded: true
|
||||
loaded: true,
|
||||
loading: false
|
||||
});
|
||||
|
||||
case AuthActionTypes.AUTHENTICATED_SUCCESS:
|
||||
@@ -82,15 +79,16 @@ export function authReducer(state: any = initialState, action: AuthActions): Aut
|
||||
});
|
||||
|
||||
case AuthActionTypes.AUTHENTICATE_SUCCESS:
|
||||
const token: AuthTokenInfo = (action as AuthenticationSuccessAction).payload;
|
||||
|
||||
// verify token is not null
|
||||
if (token === null) {
|
||||
return state;
|
||||
}
|
||||
|
||||
case AuthActionTypes.CHECK_AUTHENTICATION_TOKEN:
|
||||
return Object.assign({}, state, {
|
||||
token: token
|
||||
loading: true
|
||||
});
|
||||
|
||||
case AuthActionTypes.CHECK_AUTHENTICATION_TOKEN_ERROR:
|
||||
return Object.assign({}, state, {
|
||||
loading: false
|
||||
});
|
||||
|
||||
case AuthActionTypes.REGISTRATION_SUCCESS:
|
||||
@@ -117,8 +115,7 @@ export function authReducer(state: any = initialState, action: AuthActions): Aut
|
||||
error: undefined,
|
||||
loaded: false,
|
||||
loading: false,
|
||||
user: undefined,
|
||||
token: undefined
|
||||
user: undefined
|
||||
});
|
||||
|
||||
case AuthActionTypes.REGISTRATION:
|
||||
|
@@ -7,34 +7,9 @@ import { AuthRequestService } from './auth-request.service';
|
||||
import { HttpHeaders } from '@angular/common/http';
|
||||
import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service';
|
||||
import { AuthStatus } from './models/auth-status.model';
|
||||
import { AuthTokenInfo } from './models/auth-token-info.model';
|
||||
import { AuthTokenInfo, TOKENITEM } from './models/auth-token-info.model';
|
||||
import { isNotEmpty, isNotNull } from '../../shared/empty.util';
|
||||
import { AuthStorageService } from './auth-storage.service';
|
||||
|
||||
export const MOCK_USER = new Eperson();
|
||||
MOCK_USER.id = '92a59227-ccf7-46da-9776-86c3fc64147f';
|
||||
MOCK_USER.uuid = '92a59227-ccf7-46da-9776-86c3fc64147f';
|
||||
MOCK_USER.name = 'andrea.bollini@4science.it';
|
||||
MOCK_USER.email = 'andrea.bollini@4science.it';
|
||||
MOCK_USER.metadata = [
|
||||
{
|
||||
key: 'eperson.firstname',
|
||||
value: 'Andrea',
|
||||
language: null
|
||||
},
|
||||
{
|
||||
key: 'eperson.lastname',
|
||||
value: 'Bollini',
|
||||
language: null
|
||||
},
|
||||
{
|
||||
key: 'eperson.language',
|
||||
value: 'en',
|
||||
language: null
|
||||
}
|
||||
];
|
||||
|
||||
export const TOKENITEM = 'dsAuthInfo';
|
||||
import { CookieService } from '../../shared/services/cookie.service';
|
||||
|
||||
/**
|
||||
* The auth service.
|
||||
@@ -54,7 +29,7 @@ export class AuthService {
|
||||
*/
|
||||
private _redirectUrl: string;
|
||||
|
||||
constructor(private authRequestService: AuthRequestService, private storage: AuthStorageService) {
|
||||
constructor(private authRequestService: AuthRequestService, private storage: CookieService) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,7 +51,7 @@ export class AuthService {
|
||||
let headers = new HttpHeaders();
|
||||
headers = headers.append('Content-Type', 'application/x-www-form-urlencoded');
|
||||
options.headers = headers;
|
||||
options.responseType = 'text';
|
||||
// options.responseType = 'text';
|
||||
return this.authRequestService.postToEndpoint('login', body, options)
|
||||
.map((status: AuthStatus) => {
|
||||
if (status.authenticated) {
|
||||
@@ -101,9 +76,7 @@ export class AuthService {
|
||||
* @returns {User}
|
||||
*/
|
||||
public authenticatedUser(token: AuthTokenInfo): Observable<Eperson> {
|
||||
// Normally you would do an HTTP request to determine if
|
||||
// the user has an existing auth session on the server
|
||||
// but, let's just return the mock user for this example.
|
||||
// Determine if the user has an existing auth session on the server
|
||||
const options: HttpOptions = Object.create({});
|
||||
let headers = new HttpHeaders();
|
||||
headers = headers.append('Accept', 'application/json');
|
||||
@@ -121,6 +94,14 @@ export class AuthService {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if token is present into storage
|
||||
*/
|
||||
public checkAuthenticationToken(): Observable<AuthTokenInfo> {
|
||||
const token = this.getToken();
|
||||
return isNotEmpty(token) ? Observable.of(token) : Observable.throw(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new user
|
||||
* @returns {User}
|
||||
@@ -137,7 +118,7 @@ export class AuthService {
|
||||
* End session
|
||||
* @returns {Observable<boolean>}
|
||||
*/
|
||||
public signout(): Observable<boolean> {
|
||||
public logout(): Observable<boolean> {
|
||||
// Normally you would do an HTTP request sign end the session
|
||||
// but, let's just return an observable of true.
|
||||
let headers = new HttpHeaders();
|
||||
@@ -168,11 +149,12 @@ export class AuthService {
|
||||
|
||||
public storeToken(token: AuthTokenInfo) {
|
||||
// Save authentication token info
|
||||
return this.storage.store(TOKENITEM, JSON.stringify(token));
|
||||
return this.storage.set(TOKENITEM, token);
|
||||
}
|
||||
|
||||
public removeToken() {
|
||||
// Remove authentication token info
|
||||
console.log('REMOVE!!!!');
|
||||
return this.storage.remove(TOKENITEM);
|
||||
}
|
||||
|
||||
|
@@ -1,3 +1,5 @@
|
||||
export const TOKENITEM = 'dsAuthInfo';
|
||||
|
||||
export class AuthTokenInfo {
|
||||
public accessToken: string;
|
||||
public expires?: number;
|
||||
|
5
src/app/core/cache/response-cache.service.ts
vendored
5
src/app/core/cache/response-cache.service.ts
vendored
@@ -65,6 +65,11 @@ export class ResponseCacheService {
|
||||
return result;
|
||||
}
|
||||
|
||||
remove(key: string): void {
|
||||
if (this.has(key)) {
|
||||
this.store.dispatch(new ResponseCacheRemoveAction(key));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Check whether a ResponseCacheEntry should still be cached
|
||||
*
|
||||
|
@@ -44,7 +44,8 @@ import { AuthRequestService } from './auth/auth-request.service';
|
||||
import { AuthResponseParsingService } from './auth/auth-response-parsing.service';
|
||||
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { AuthInterceptor } from './auth/auth.interceptor';
|
||||
import { AuthStorageService } from './auth/auth-storage.service';
|
||||
import { CookieService } from '../shared/services/cookie.service';
|
||||
import { PlatformService } from '../shared/services/platform.service';
|
||||
|
||||
const IMPORTS = [
|
||||
CommonModule,
|
||||
@@ -66,9 +67,9 @@ const PROVIDERS = [
|
||||
AuthRequestService,
|
||||
AuthResponseParsingService,
|
||||
AuthService,
|
||||
AuthStorageService,
|
||||
CommunityDataService,
|
||||
CollectionDataService,
|
||||
CookieService,
|
||||
DSOResponseParsingService,
|
||||
DSpaceRESTv2Service,
|
||||
HostWindowService,
|
||||
@@ -76,6 +77,7 @@ const PROVIDERS = [
|
||||
MetadataService,
|
||||
ObjectCacheService,
|
||||
PaginationComponentOptions,
|
||||
PlatformService,
|
||||
RemoteDataBuildService,
|
||||
RequestService,
|
||||
ResponseCacheService,
|
||||
@@ -90,7 +92,7 @@ const PROVIDERS = [
|
||||
SubmissionSectionsConfigService,
|
||||
UUIDService,
|
||||
{ provide: NativeWindowService, useFactory: NativeWindowFactory },
|
||||
// register TokenInterceptor as HttpInterceptor
|
||||
// register AuthInterceptor as HttpInterceptor
|
||||
{
|
||||
provide: HTTP_INTERCEPTORS,
|
||||
useClass: AuthInterceptor,
|
||||
|
@@ -35,18 +35,17 @@ export class AuthNavMenuComponent implements OnDestroy, OnInit {
|
||||
protected subs: Subscription[] = [];
|
||||
|
||||
constructor(
|
||||
private appStore: Store<AppState>,
|
||||
private coreStore: Store<CoreState>,
|
||||
private store: Store<AppState>,
|
||||
public windowService: HostWindowService) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
// set loading
|
||||
this.isAuthenticated = this.coreStore.select(isAuthenticated);
|
||||
this.isAuthenticated = this.store.select(isAuthenticated);
|
||||
|
||||
this.user = this.appStore.select(getAuthenticatedUser);
|
||||
this.user = this.store.select(getAuthenticatedUser);
|
||||
|
||||
this.subs.push(this.appStore.select(routerStateSelector)
|
||||
this.subs.push(this.store.select(routerStateSelector)
|
||||
.filter((router: RouterReducerState) => isNotUndefined(router))
|
||||
.subscribe((router: RouterReducerState) => {
|
||||
this.showAuth = router.state.url !== '/login';
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import { HttpClient, HttpClientModule } from '@angular/common/http';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserModule, makeStateKey, TransferState } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { REQUEST } from '@nguniversal/express-engine/tokens';
|
||||
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
||||
@@ -15,10 +16,16 @@ import { AppModule } from '../../app/app.module';
|
||||
import { DSpaceBrowserTransferStateModule } from '../transfer-state/dspace-browser-transfer-state.module';
|
||||
import { DSpaceTransferState } from '../transfer-state/dspace-transfer-state.service';
|
||||
|
||||
export const REQ_KEY = makeStateKey<string>('req');
|
||||
|
||||
export function createTranslateLoader(http: HttpClient) {
|
||||
return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
|
||||
}
|
||||
|
||||
export function getRequest(transferState: TransferState): any {
|
||||
return transferState.get<any>(REQ_KEY, {})
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
bootstrap: [AppComponent],
|
||||
imports: [
|
||||
@@ -45,6 +52,13 @@ export function createTranslateLoader(http: HttpClient) {
|
||||
}),
|
||||
AppModule
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: REQUEST,
|
||||
useFactory: getRequest,
|
||||
deps: [TransferState]
|
||||
}
|
||||
]
|
||||
})
|
||||
export class BrowserAppModule {
|
||||
constructor(
|
||||
|
Reference in New Issue
Block a user