mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-08 02:24:11 +00:00
Removed use of platform service and created different service for SSR and CSR
This commit is contained in:
@@ -1,22 +1,13 @@
|
|||||||
import {
|
import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing';
|
||||||
async,
|
|
||||||
ComponentFixture,
|
|
||||||
inject,
|
|
||||||
TestBed
|
|
||||||
} from '@angular/core/testing';
|
|
||||||
|
|
||||||
import {
|
import { CUSTOM_ELEMENTS_SCHEMA, DebugElement } from '@angular/core';
|
||||||
CUSTOM_ELEMENTS_SCHEMA,
|
|
||||||
DebugElement
|
|
||||||
} from '@angular/core';
|
|
||||||
|
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
|
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
|
|
||||||
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
|
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||||
import { Store, StoreModule } from '@ngrx/store';
|
import { Store, StoreModule } from '@ngrx/store';
|
||||||
|
|
||||||
// Load the implementations that should be tested
|
// Load the implementations that should be tested
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
@@ -25,13 +16,11 @@ import { HostWindowResizeAction } from './shared/host-window.actions';
|
|||||||
|
|
||||||
import { MetadataService } from './core/metadata/metadata.service';
|
import { MetadataService } from './core/metadata/metadata.service';
|
||||||
|
|
||||||
import { GLOBAL_CONFIG, ENV_CONFIG } from '../config';
|
import { ENV_CONFIG, GLOBAL_CONFIG } from '../config';
|
||||||
import { NativeWindowRef, NativeWindowService } from './shared/services/window.service';
|
import { NativeWindowRef, NativeWindowService } from './shared/services/window.service';
|
||||||
|
|
||||||
import { MockTranslateLoader } from './shared/mocks/mock-translate-loader';
|
import { MockTranslateLoader } from './shared/mocks/mock-translate-loader';
|
||||||
import { MockMetadataService } from './shared/mocks/mock-metadata-service';
|
import { MockMetadataService } from './shared/mocks/mock-metadata-service';
|
||||||
import { PlatformServiceStub } from './shared/testing/platform-service-stub';
|
|
||||||
import { PlatformService } from './shared/services/platform.service';
|
|
||||||
|
|
||||||
let comp: AppComponent;
|
let comp: AppComponent;
|
||||||
let fixture: ComponentFixture<AppComponent>;
|
let fixture: ComponentFixture<AppComponent>;
|
||||||
@@ -55,10 +44,9 @@ describe('App component', () => {
|
|||||||
],
|
],
|
||||||
declarations: [AppComponent], // declare the test component
|
declarations: [AppComponent], // declare the test component
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: GLOBAL_CONFIG, useValue: ENV_CONFIG },
|
{provide: GLOBAL_CONFIG, useValue: ENV_CONFIG},
|
||||||
{ provide: NativeWindowService, useValue: new NativeWindowRef() },
|
{provide: NativeWindowService, useValue: new NativeWindowRef()},
|
||||||
{ provide: MetadataService, useValue: new MockMetadataService() },
|
{provide: MetadataService, useValue: new MockMetadataService()},
|
||||||
{ provide: PlatformService, useValue: new PlatformServiceStub() },
|
|
||||||
AppComponent
|
AppComponent
|
||||||
],
|
],
|
||||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||||
|
@@ -1,11 +1,4 @@
|
|||||||
import {
|
import { ChangeDetectionStrategy, Component, HostListener, Inject, OnInit, ViewEncapsulation } from '@angular/core';
|
||||||
ChangeDetectionStrategy,
|
|
||||||
Component,
|
|
||||||
HostListener,
|
|
||||||
Inject,
|
|
||||||
OnInit,
|
|
||||||
ViewEncapsulation
|
|
||||||
} from '@angular/core';
|
|
||||||
|
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
|
|
||||||
@@ -17,9 +10,8 @@ import { MetadataService } from './core/metadata/metadata.service';
|
|||||||
import { HostWindowResizeAction } from './shared/host-window.actions';
|
import { HostWindowResizeAction } from './shared/host-window.actions';
|
||||||
import { HostWindowState } from './shared/host-window.reducer';
|
import { HostWindowState } from './shared/host-window.reducer';
|
||||||
import { NativeWindowRef, NativeWindowService } from './shared/services/window.service';
|
import { NativeWindowRef, NativeWindowService } from './shared/services/window.service';
|
||||||
import { CheckAuthenticationTokenAction } from './core/auth/auth.actions';
|
|
||||||
import { isAuthenticated } from './core/auth/selectors';
|
import { isAuthenticated } from './core/auth/selectors';
|
||||||
import { PlatformService } from './shared/services/platform.service';
|
import { AuthService } from './core/auth/auth.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-app',
|
selector: 'ds-app',
|
||||||
@@ -36,7 +28,7 @@ export class AppComponent implements OnInit {
|
|||||||
private translate: TranslateService,
|
private translate: TranslateService,
|
||||||
private store: Store<HostWindowState>,
|
private store: Store<HostWindowState>,
|
||||||
private metadata: MetadataService,
|
private metadata: MetadataService,
|
||||||
private platformService: PlatformService
|
private authService: AuthService
|
||||||
) {
|
) {
|
||||||
// this language will be used as a fallback when a translation isn't found in the current language
|
// this language will be used as a fallback when a translation isn't found in the current language
|
||||||
translate.setDefaultLang('en');
|
translate.setDefaultLang('en');
|
||||||
@@ -55,12 +47,13 @@ export class AppComponent implements OnInit {
|
|||||||
const color: string = this.config.production ? 'red' : 'green';
|
const color: string = this.config.production ? 'red' : 'green';
|
||||||
console.info(`Environment: %c${env}`, `color: ${color}; font-weight: bold;`);
|
console.info(`Environment: %c${env}`, `color: ${color}; font-weight: bold;`);
|
||||||
this.dispatchWindowSize(this._window.nativeWindow.innerWidth, this._window.nativeWindow.innerHeight);
|
this.dispatchWindowSize(this._window.nativeWindow.innerWidth, this._window.nativeWindow.innerHeight);
|
||||||
if (this.platformService.isServer) {
|
|
||||||
this.store.select(isAuthenticated)
|
// Whether is not authenticathed try to retrieve a possible stored auth token
|
||||||
.take(1)
|
this.store.select(isAuthenticated)
|
||||||
.filter((authenticated) => !authenticated)
|
.take(1)
|
||||||
.subscribe((authenticated) => this.store.dispatch(new CheckAuthenticationTokenAction()));
|
.filter((authenticated) => !authenticated)
|
||||||
}
|
.subscribe((authenticated) => this.authService.checksAuthenticationToken());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('window:resize', ['$event'])
|
@HostListener('window:resize', ['$event'])
|
||||||
|
@@ -71,7 +71,7 @@ export class AuthEffects {
|
|||||||
public checkToken: Observable<Action> = this.actions$
|
public checkToken: Observable<Action> = this.actions$
|
||||||
.ofType(AuthActionTypes.CHECK_AUTHENTICATION_TOKEN)
|
.ofType(AuthActionTypes.CHECK_AUTHENTICATION_TOKEN)
|
||||||
.switchMap(() => {
|
.switchMap(() => {
|
||||||
return this.authService.checkAuthenticationToken()
|
return this.authService.hasValidAuthenticationToken()
|
||||||
.map((token: AuthTokenInfo) => new AuthenticatedAction(token))
|
.map((token: AuthTokenInfo) => new AuthenticatedAction(token))
|
||||||
.catch((error) => Observable.of(new CheckAuthenticationTokenErrorAction()));
|
.catch((error) => Observable.of(new CheckAuthenticationTokenErrorAction()));
|
||||||
});
|
});
|
||||||
|
@@ -15,11 +15,15 @@ import { CookieService } from '../../shared/services/cookie.service';
|
|||||||
import { getAuthenticationToken, getRedirectUrl, isAuthenticated, isTokenRefreshing } from './selectors';
|
import { getAuthenticationToken, getRedirectUrl, isAuthenticated, isTokenRefreshing } 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, SetRedirectUrlAction } from './auth.actions';
|
import {
|
||||||
|
CheckAuthenticationTokenAction,
|
||||||
|
ResetAuthenticationMessagesAction,
|
||||||
|
SetRedirectUrlAction
|
||||||
|
} from './auth.actions';
|
||||||
import { RouterReducerState } from '@ngrx/router-store';
|
import { RouterReducerState } from '@ngrx/router-store';
|
||||||
import { CookieAttributes } from 'js-cookie';
|
import { CookieAttributes } from 'js-cookie';
|
||||||
import { NativeWindowRef, NativeWindowService } from '../../shared/services/window.service';
|
import { NativeWindowRef, NativeWindowService } from '../../shared/services/window.service';
|
||||||
import { PlatformService } from '../../shared/services/platform.service';
|
import { REQUEST } from '@nguniversal/express-engine/tokens';
|
||||||
|
|
||||||
export const LOGIN_ROUTE = '/login';
|
export const LOGIN_ROUTE = '/login';
|
||||||
|
|
||||||
@@ -35,14 +39,14 @@ export class AuthService {
|
|||||||
* True if authenticated
|
* True if authenticated
|
||||||
* @type boolean
|
* @type boolean
|
||||||
*/
|
*/
|
||||||
private _authenticated: boolean;
|
protected _authenticated: boolean;
|
||||||
|
|
||||||
constructor(@Inject(NativeWindowService) private _window: NativeWindowRef,
|
constructor(@Inject(REQUEST) protected req: any,
|
||||||
private authRequestService: AuthRequestService,
|
@Inject(NativeWindowService) protected _window: NativeWindowRef,
|
||||||
private platform: PlatformService,
|
protected authRequestService: AuthRequestService,
|
||||||
private router: Router,
|
protected router: Router,
|
||||||
private storage: CookieService,
|
protected storage: CookieService,
|
||||||
private store: Store<AppState>) {
|
protected store: Store<AppState>) {
|
||||||
this.store.select(isAuthenticated)
|
this.store.select(isAuthenticated)
|
||||||
.startWith(false)
|
.startWith(false)
|
||||||
.subscribe((authenticated: boolean) => this._authenticated = authenticated);
|
.subscribe((authenticated: boolean) => this._authenticated = authenticated);
|
||||||
@@ -130,10 +134,17 @@ export class AuthService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if token is present into browser storage and is valid. (NB Check is done only on SSR)
|
||||||
|
*/
|
||||||
|
public checksAuthenticationToken() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if token is present into storage and is not expired
|
* Checks if token is present into storage and is not expired
|
||||||
*/
|
*/
|
||||||
public checkAuthenticationToken(): Observable<AuthTokenInfo> {
|
public hasValidAuthenticationToken(): Observable<AuthTokenInfo> {
|
||||||
return this.store.select(getAuthenticationToken)
|
return this.store.select(getAuthenticationToken)
|
||||||
.take(1)
|
.take(1)
|
||||||
.map((authTokenInfo: AuthTokenInfo) => {
|
.map((authTokenInfo: AuthTokenInfo) => {
|
||||||
@@ -317,10 +328,9 @@ export class AuthService {
|
|||||||
this.getRedirectUrl()
|
this.getRedirectUrl()
|
||||||
.first()
|
.first()
|
||||||
.subscribe((redirectUrl) => {
|
.subscribe((redirectUrl) => {
|
||||||
|
console.log('Browser');
|
||||||
if (isNotEmpty(redirectUrl)) {
|
if (isNotEmpty(redirectUrl)) {
|
||||||
if (this.platform.isBrowser) {
|
this.clearRedirectUrl();
|
||||||
this.clearRedirectUrl();
|
|
||||||
}
|
|
||||||
|
|
||||||
// override the route reuse strategy
|
// override the route reuse strategy
|
||||||
this.router.routeReuseStrategy.shouldReuseRoute = () => {
|
this.router.routeReuseStrategy.shouldReuseRoute = () => {
|
||||||
|
77
src/app/core/auth/server-auth.service.ts
Normal file
77
src/app/core/auth/server-auth.service.ts
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import { HttpHeaders } from '@angular/common/http';
|
||||||
|
import { HttpOptions } from '../dspace-rest-v2/dspace-rest-v2.service';
|
||||||
|
import { AuthStatus } from './models/auth-status.model';
|
||||||
|
import { isNotEmpty } from '../../shared/empty.util';
|
||||||
|
import { AuthService } from './auth.service';
|
||||||
|
import { AuthTokenInfo } from './models/auth-token-info.model';
|
||||||
|
import { CheckAuthenticationTokenAction } from './auth.actions';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The auth service.
|
||||||
|
*/
|
||||||
|
@Injectable()
|
||||||
|
export class ServerAuthService extends AuthService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate the user
|
||||||
|
*
|
||||||
|
* @param {string} user The user name
|
||||||
|
* @param {string} password The user's password
|
||||||
|
* @returns {Observable<User>} The authenticated user observable.
|
||||||
|
*/
|
||||||
|
public authenticate(user: string, password: string): Observable<AuthStatus> {
|
||||||
|
// Attempt authenticating the user using the supplied credentials.
|
||||||
|
const body = encodeURI(`password=${password}&user=${user}`);
|
||||||
|
const options: HttpOptions = Object.create({});
|
||||||
|
let headers = new HttpHeaders();
|
||||||
|
|
||||||
|
// NB this could be use to avoid the problem with the authentication is case the UI is rendered by Angular Universal.
|
||||||
|
const clientIp = this.req.connection.remoteAddress;
|
||||||
|
|
||||||
|
headers = headers.append('Content-Type', 'application/x-www-form-urlencoded');
|
||||||
|
options.headers = headers;
|
||||||
|
return this.authRequestService.postToEndpoint('login', body, options)
|
||||||
|
.map((status: AuthStatus) => {
|
||||||
|
if (status.authenticated) {
|
||||||
|
return status;
|
||||||
|
} else {
|
||||||
|
throw(new Error('Invalid email or password'));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if token is present into browser storage and is valid. (NB Check is done only on SSR)
|
||||||
|
*/
|
||||||
|
public checksAuthenticationToken() {
|
||||||
|
this.store.dispatch(new CheckAuthenticationTokenAction())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirect to the route navigated before the login
|
||||||
|
*/
|
||||||
|
public redirectToPreviousUrl() {
|
||||||
|
this.getRedirectUrl()
|
||||||
|
.first()
|
||||||
|
.subscribe((redirectUrl) => {
|
||||||
|
console.log('server side');
|
||||||
|
if (isNotEmpty(redirectUrl)) {
|
||||||
|
// override the route reuse strategy
|
||||||
|
this.router.routeReuseStrategy.shouldReuseRoute = () => {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
this.router.navigated = false;
|
||||||
|
const url = decodeURIComponent(redirectUrl);
|
||||||
|
this.router.navigateByUrl(url);
|
||||||
|
} else {
|
||||||
|
this.router.navigate(['/']);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -38,13 +38,11 @@ import { SubmissionDefinitionsConfigService } from './config/submission-definiti
|
|||||||
import { SubmissionFormsConfigService } from './config/submission-forms-config.service';
|
import { SubmissionFormsConfigService } from './config/submission-forms-config.service';
|
||||||
import { SubmissionSectionsConfigService } from './config/submission-sections-config.service';
|
import { SubmissionSectionsConfigService } from './config/submission-sections-config.service';
|
||||||
import { UUIDService } from './shared/uuid.service';
|
import { UUIDService } from './shared/uuid.service';
|
||||||
import { AuthService } from './auth/auth.service';
|
|
||||||
import { AuthenticatedGuard } from './auth/authenticated.guard';
|
import { AuthenticatedGuard } from './auth/authenticated.guard';
|
||||||
import { AuthRequestService } from './auth/auth-request.service';
|
import { AuthRequestService } from './auth/auth-request.service';
|
||||||
import { AuthResponseParsingService } from './auth/auth-response-parsing.service';
|
import { AuthResponseParsingService } from './auth/auth-response-parsing.service';
|
||||||
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||||
import { AuthInterceptor } from './auth/auth.interceptor';
|
import { AuthInterceptor } from './auth/auth.interceptor';
|
||||||
import { CookieService } from '../shared/services/cookie.service';
|
|
||||||
import { PlatformService } from '../shared/services/platform.service';
|
import { PlatformService } from '../shared/services/platform.service';
|
||||||
|
|
||||||
const IMPORTS = [
|
const IMPORTS = [
|
||||||
@@ -66,10 +64,8 @@ const PROVIDERS = [
|
|||||||
AuthenticatedGuard,
|
AuthenticatedGuard,
|
||||||
AuthRequestService,
|
AuthRequestService,
|
||||||
AuthResponseParsingService,
|
AuthResponseParsingService,
|
||||||
AuthService,
|
|
||||||
CommunityDataService,
|
CommunityDataService,
|
||||||
CollectionDataService,
|
CollectionDataService,
|
||||||
CookieService,
|
|
||||||
DSOResponseParsingService,
|
DSOResponseParsingService,
|
||||||
DSpaceRESTv2Service,
|
DSpaceRESTv2Service,
|
||||||
HostWindowService,
|
HostWindowService,
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<ds-loading *ngIf="(loading | async)" class="m-5"></ds-loading>
|
<ds-loading *ngIf="(loading | async) || (isAuthenticated | async)" class="m-5"></ds-loading>
|
||||||
<form *ngIf="!(loading | async)" class="form-login px-4 py-3" (ngSubmit)="submit()" [formGroup]="form" novalidate>
|
<form *ngIf="!(loading | async) && !(isAuthenticated | async)" class="form-login px-4 py-3" (ngSubmit)="submit()" [formGroup]="form" novalidate>
|
||||||
<label for="inputEmail" class="sr-only">{{"login.form.email" | translate}}</label>
|
<label for="inputEmail" class="sr-only">{{"login.form.email" | translate}}</label>
|
||||||
<input id="inputEmail"
|
<input id="inputEmail"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
@@ -12,12 +12,12 @@
|
|||||||
<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"
|
||||||
class="form-control form-control-lg position-relative"
|
class="form-control form-control-lg position-relative mb-3"
|
||||||
placeholder="{{'login.form.password' | translate}}"
|
placeholder="{{'login.form.password' | translate}}"
|
||||||
formControlName="password"
|
formControlName="password"
|
||||||
required
|
required
|
||||||
type="password">
|
type="password">
|
||||||
<div *ngIf="platform.isBrowser && (error | async) && hasError" class="alert alert-danger" role="alert" @fadeOut>{{ (error | async) | translate }}</div>
|
<div *ngIf="(error | async) && hasError" class="alert alert-danger" role="alert" @fadeOut>{{ (error | async) | translate }}</div>
|
||||||
<div *ngIf="(message | async) && hasMessage" class="alert alert-info" role="alert" @fadeOut>{{ (message | async) | translate }}</div>
|
<div *ngIf="(message | async) && hasMessage" class="alert alert-info" role="alert" @fadeOut>{{ (message | async) | translate }}</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>
|
||||||
|
@@ -9,7 +9,8 @@ import 'rxjs/add/operator/takeWhile';
|
|||||||
import { AuthenticateAction, ResetAuthenticationMessagesAction } from '../../core/auth/auth.actions';
|
import { AuthenticateAction, ResetAuthenticationMessagesAction } from '../../core/auth/auth.actions';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getAuthenticationError, getAuthenticationInfo,
|
getAuthenticationError,
|
||||||
|
getAuthenticationInfo,
|
||||||
isAuthenticated,
|
isAuthenticated,
|
||||||
isAuthenticationLoading,
|
isAuthenticationLoading,
|
||||||
} from '../../core/auth/selectors';
|
} from '../../core/auth/selectors';
|
||||||
@@ -18,7 +19,6 @@ 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
|
||||||
@@ -56,6 +56,12 @@ export class LogInComponent implements OnDestroy, OnInit {
|
|||||||
*/
|
*/
|
||||||
public hasMessage = false;
|
public hasMessage = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether user is authenticated.
|
||||||
|
* @type {Observable<string>}
|
||||||
|
*/
|
||||||
|
public isAuthenticated: Observable<boolean>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the authentication is loading.
|
* True if the authentication is loading.
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
@@ -83,15 +89,18 @@ 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>
|
||||||
) { }
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lifecycle hook that is called after data-bound properties of a directive are initialized.
|
* Lifecycle hook that is called after data-bound properties of a directive are initialized.
|
||||||
* @method ngOnInit
|
* @method ngOnInit
|
||||||
*/
|
*/
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
|
// set isAuthenticated
|
||||||
|
this.isAuthenticated = this.store.select(isAuthenticated);
|
||||||
|
|
||||||
// set formGroup
|
// set formGroup
|
||||||
this.form = this.formBuilder.group({
|
this.form = this.formBuilder.group({
|
||||||
email: ['', Validators.required],
|
email: ['', Validators.required],
|
||||||
@@ -144,7 +153,7 @@ export class LogInComponent implements OnDestroy, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To to the registration page.
|
* To the registration page.
|
||||||
* @method register
|
* @method register
|
||||||
*/
|
*/
|
||||||
public register() {
|
public register() {
|
||||||
|
25
src/app/shared/services/client-cookie.service.ts
Normal file
25
src/app/shared/services/client-cookie.service.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { Injectable } from '@angular/core'
|
||||||
|
import { CookieAttributes, getJSON, remove, set } from 'js-cookie'
|
||||||
|
import { CookieService, ICookieService } from './cookie.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ClientCookieService extends CookieService implements ICookieService {
|
||||||
|
|
||||||
|
public set(name: string, value: any, options?: CookieAttributes): void {
|
||||||
|
set(name, value, options);
|
||||||
|
this.updateSource()
|
||||||
|
}
|
||||||
|
|
||||||
|
public remove(name: string, options?: CookieAttributes): void {
|
||||||
|
remove(name, options);
|
||||||
|
this.updateSource()
|
||||||
|
}
|
||||||
|
|
||||||
|
public get(name: string): any {
|
||||||
|
return getJSON(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
public getAll(): any {
|
||||||
|
return getJSON()
|
||||||
|
}
|
||||||
|
}
|
@@ -1,4 +1,3 @@
|
|||||||
import { PlatformService } from './platform.service'
|
|
||||||
import { CookieService, ICookieService } from './cookie.service'
|
import { CookieService, ICookieService } from './cookie.service'
|
||||||
import { async, TestBed } from '@angular/core/testing'
|
import { async, TestBed } from '@angular/core/testing'
|
||||||
import { REQUEST } from '@nguniversal/express-engine/tokens'
|
import { REQUEST } from '@nguniversal/express-engine/tokens'
|
||||||
@@ -10,8 +9,7 @@ describe(CookieService.name, () => {
|
|||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [
|
providers: [
|
||||||
CookieService,
|
CookieService,
|
||||||
PlatformService,
|
{provide: REQUEST, useValue: {}}
|
||||||
{ provide: REQUEST, useValue: {} }
|
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
|
@@ -1,62 +1,40 @@
|
|||||||
import { REQUEST } from '@nguniversal/express-engine/tokens'
|
|
||||||
import { PlatformService } from './platform.service'
|
|
||||||
import { Inject, Injectable } from '@angular/core'
|
import { Inject, Injectable } from '@angular/core'
|
||||||
|
|
||||||
|
import { REQUEST } from '@nguniversal/express-engine/tokens'
|
||||||
|
|
||||||
import { Subject } from 'rxjs/Subject'
|
import { Subject } from 'rxjs/Subject'
|
||||||
import { Observable } from 'rxjs/Observable'
|
import { Observable } from 'rxjs/Observable'
|
||||||
import { CookieAttributes, getJSON, remove, set } from 'js-cookie'
|
import { CookieAttributes } from 'js-cookie'
|
||||||
|
|
||||||
export interface ICookieService {
|
export interface ICookieService {
|
||||||
readonly cookies$: Observable<{ readonly [key: string]: any }>
|
readonly cookies$: Observable<{ readonly [key: string]: any }>
|
||||||
|
|
||||||
getAll(): any
|
getAll(): any
|
||||||
|
|
||||||
get(name: string): any
|
get(name: string): any
|
||||||
|
|
||||||
set(name: string, value: any, options?: CookieAttributes): void
|
set(name: string, value: any, options?: CookieAttributes): void
|
||||||
|
|
||||||
remove(name: string, options?: CookieAttributes): void
|
remove(name: string, options?: CookieAttributes): void
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CookieService implements ICookieService {
|
export abstract class CookieService implements ICookieService {
|
||||||
private readonly cookieSource = new Subject<{ readonly [key: string]: any }>();
|
protected readonly cookieSource = new Subject<{ readonly [key: string]: any }>();
|
||||||
public readonly cookies$ = this.cookieSource.asObservable();
|
public readonly cookies$ = this.cookieSource.asObservable();
|
||||||
|
|
||||||
constructor(private platformService: PlatformService, @Inject(REQUEST) private req: any) { }
|
constructor(@Inject(REQUEST) protected req: any) {
|
||||||
|
|
||||||
public set(name: string, value: any, options?: CookieAttributes): void {
|
|
||||||
if (this.platformService.isBrowser) {
|
|
||||||
set(name, value, options);
|
|
||||||
this.updateSource()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public remove(name: string, options?: CookieAttributes): void {
|
public abstract set(name: string, value: any, options?: CookieAttributes): void
|
||||||
if (this.platformService.isBrowser) {
|
|
||||||
remove(name, options);
|
|
||||||
this.updateSource()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public get(name: string): any {
|
public abstract remove(name: string, options?: CookieAttributes): void
|
||||||
if (this.platformService.isBrowser) {
|
|
||||||
return getJSON(name)
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
return JSON.parse(this.req.cookies[name])
|
|
||||||
} catch (err) {
|
|
||||||
return this.req ? this.req.cookies[name] : undefined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public getAll(): any {
|
public abstract get(name: string): any
|
||||||
if (this.platformService.isBrowser) {
|
|
||||||
return getJSON()
|
|
||||||
} else {
|
|
||||||
if (this.req) {
|
|
||||||
return this.req.cookies
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private updateSource() {
|
public abstract getAll(): any
|
||||||
this.cookieSource.next(this.getAll())
|
|
||||||
|
protected updateSource() {
|
||||||
|
this.cookieSource.next(this.getAll());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
30
src/app/shared/services/server-cookie.service.ts
Normal file
30
src/app/shared/services/server-cookie.service.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import { Injectable } from '@angular/core'
|
||||||
|
import { CookieAttributes } from 'js-cookie'
|
||||||
|
import { CookieService, ICookieService } from './cookie.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ServerCookieService extends CookieService implements ICookieService {
|
||||||
|
|
||||||
|
public set(name: string, value: any, options?: CookieAttributes): void {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
public remove(name: string, options?: CookieAttributes): void {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
public get(name: string): any {
|
||||||
|
console.log(this.req.connection.remoteAddress);
|
||||||
|
try {
|
||||||
|
return JSON.parse(this.req.cookies[name])
|
||||||
|
} catch (err) {
|
||||||
|
return this.req ? this.req.cookies[name] : undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getAll(): any {
|
||||||
|
if (this.req) {
|
||||||
|
return this.req.cookies
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -15,6 +15,10 @@ import { AppComponent } from '../../app/app.component';
|
|||||||
import { AppModule } from '../../app/app.module';
|
import { AppModule } from '../../app/app.module';
|
||||||
import { DSpaceBrowserTransferStateModule } from '../transfer-state/dspace-browser-transfer-state.module';
|
import { DSpaceBrowserTransferStateModule } from '../transfer-state/dspace-browser-transfer-state.module';
|
||||||
import { DSpaceTransferState } from '../transfer-state/dspace-transfer-state.service';
|
import { DSpaceTransferState } from '../transfer-state/dspace-transfer-state.service';
|
||||||
|
import { ClientCookieService } from '../../app/shared/services/client-cookie.service';
|
||||||
|
import { CookieService } from '../../app/shared/services/cookie.service';
|
||||||
|
import { ServerAuthService } from '../../app/core/auth/server-auth.service';
|
||||||
|
import { AuthService } from '../../app/core/auth/auth.service';
|
||||||
|
|
||||||
export const REQ_KEY = makeStateKey<string>('req');
|
export const REQ_KEY = makeStateKey<string>('req');
|
||||||
|
|
||||||
@@ -57,6 +61,14 @@ export function getRequest(transferState: TransferState): any {
|
|||||||
provide: REQUEST,
|
provide: REQUEST,
|
||||||
useFactory: getRequest,
|
useFactory: getRequest,
|
||||||
deps: [TransferState]
|
deps: [TransferState]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: AuthService,
|
||||||
|
useClass: AuthService
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: CookieService,
|
||||||
|
useClass: ClientCookieService
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
@@ -15,6 +15,10 @@ import { DSpaceServerTransferStateModule } from '../transfer-state/dspace-server
|
|||||||
import { DSpaceTransferState } from '../transfer-state/dspace-transfer-state.service';
|
import { DSpaceTransferState } from '../transfer-state/dspace-transfer-state.service';
|
||||||
|
|
||||||
import { TranslateUniversalLoader } from '../translate-universal-loader';
|
import { TranslateUniversalLoader } from '../translate-universal-loader';
|
||||||
|
import { CookieService } from '../../app/shared/services/cookie.service';
|
||||||
|
import { ServerCookieService } from '../../app/shared/services/server-cookie.service';
|
||||||
|
import { AuthService } from '../../app/core/auth/auth.service';
|
||||||
|
import { ServerAuthService } from '../../app/core/auth/server-auth.service';
|
||||||
|
|
||||||
export function createTranslateLoader() {
|
export function createTranslateLoader() {
|
||||||
return new TranslateUniversalLoader('dist/assets/i18n/', '.json');
|
return new TranslateUniversalLoader('dist/assets/i18n/', '.json');
|
||||||
@@ -42,6 +46,14 @@ export function createTranslateLoader() {
|
|||||||
AppModule
|
AppModule
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
|
{
|
||||||
|
provide: AuthService,
|
||||||
|
useClass: ServerAuthService
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: CookieService,
|
||||||
|
useClass: ServerCookieService
|
||||||
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class ServerAppModule {
|
export class ServerAppModule {
|
||||||
|
Reference in New Issue
Block a user