Просмотр исходного кода

added http response interceptor and redirect to login whenever there is a logout happened.

tags/2.037
Patrick Sun 4 лет назад
Родитель
Сommit
0cd57d2e2e
14 измененных файлов: 185 добавлений и 52 удалений
  1. +3
    -3
      package-lock.json
  2. +4
    -4
      package.json
  3. +7
    -0
      proxy.conf.json
  4. +8
    -6
      src/app/app.component.ts
  5. +1
    -0
      src/app/app.config.ts
  6. +12
    -2
      src/app/app.module.ts
  7. +39
    -0
      src/app/auth/auth-http-interceptor.service.ts
  8. +4
    -4
      src/app/auth/auth.component.ts
  9. +5
    -3
      src/app/canvas/canvas.component.html
  10. +8
    -3
      src/app/canvas/canvas.component.ts
  11. +6
    -5
      src/app/dashboard/dashboard.component.html
  12. +4
    -2
      src/app/dashboard/dashboard.component.ts
  13. +32
    -3
      src/app/models/api-v1-login-response.ts
  14. +52
    -17
      src/app/service/auth.service.ts

+ 3
- 3
package-lock.json Просмотреть файл

} }
}, },
"rxjs": { "rxjs": {
"version": "6.6.3",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz",
"integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==",
"version": "6.6.6",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.6.tgz",
"integrity": "sha512-/oTwee4N4iWzAMAL9xdGKjkEHmIwupR3oXbQjCKywF1BeFohswF3vZdogbmEF6pZkOsXTzWkrZszrWpQTByYVg==",
"requires": { "requires": {
"tslib": "^1.9.0" "tslib": "^1.9.0"
}, },

+ 4
- 4
package.json Просмотреть файл

"version": "0.0.0", "version": "0.0.0",
"scripts": { "scripts": {
"ng": "ng", "ng": "ng",
"start": "ng serve",
"start": "ng serve --proxy-config proxy.conf.json",
"build": "ng build", "build": "ng build",
"test": "ng test", "test": "ng test",
"lint": "ng lint", "lint": "ng lint",
"@progress/kendo-svg-icons": "^0.0.3", "@progress/kendo-svg-icons": "^0.0.3",
"@progress/kendo-theme-default": "latest", "@progress/kendo-theme-default": "latest",
"bootstrap": "^3.4.1", "bootstrap": "^3.4.1",
"rxjs": "~6.6.0",
"hammerjs": "^2.0.0",
"rxjs": "^6.6.6",
"tslib": "^2.0.0", "tslib": "^2.0.0",
"zone.js": "~0.10.2",
"hammerjs": "^2.0.0"
"zone.js": "~0.10.2"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "~0.1002.0", "@angular-devkit/build-angular": "~0.1002.0",

+ 7
- 0
proxy.conf.json Просмотреть файл

{
"/api/v1": {
"target": "http://svr2021:8080",
"secure": false,
"pathRewrite": {"^/api/v1" : "/api/v1"}
}
}

+ 8
- 6
src/app/app.component.ts Просмотреть файл

import { mainMenuItems } from './main-menu-items'; import { mainMenuItems } from './main-menu-items';
import { AuthService } from './service/auth.service'; import { AuthService } from './service/auth.service';
import { MenuService } from './service/menu.service'; import { MenuService } from './service/menu.service';
import {apiv1LoginResponse} from './models/api-v1-login-response';
import {apiV1LoginResponse} from './models/api-v1-login-response';


@Component({ @Component({
selector: 'app-root', selector: 'app-root',
title = 'SFM broker'; title = 'SFM broker';
public login = false; public login = false;
public items: any[] = mainMenuItems; public items: any[] = mainMenuItems;
kendokaAvatar = "./assets/img/avatar.png"
@ViewChild('loanEditComponent', {static: true}) loanEdit: LoanEditComponent;
kendokaAvatar = './assets/img/avatar.png';
@ViewChild('loanEditComponent', {static: true}) loanEdit: LoanEditComponent;


private loginSub: Subscription; private loginSub: Subscription;


} }


// tslint:disable-next-line:typedef // tslint:disable-next-line:typedef
ngOnInit (){
ngOnInit() {
this.loginSub = this.authService.loginSuccess.subscribe( this.loginSub = this.authService.loginSuccess.subscribe(
(rsp: apiv1LoginResponse) => {
(rsp: apiV1LoginResponse) => {
this.login = rsp.login; this.login = rsp.login;
} }
); );

this.authService.AutoLogin();
} }


// tslint:disable-next-line:typedef // tslint:disable-next-line:typedef
ngOnDestroy (){
ngOnDestroy() {
this.loginSub.unsubscribe(); this.loginSub.unsubscribe();
} }



+ 1
- 0
src/app/app.config.ts Просмотреть файл



+ 12
- 2
src/app/app.module.ts Просмотреть файл

import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HttpClientModule} from '@angular/common/http';
import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';
//Kendo //Kendo
import { MenuModule, ContextMenuModule } from '@progress/kendo-angular-menu'; import { MenuModule, ContextMenuModule } from '@progress/kendo-angular-menu';
import { IconsModule } from '@progress/kendo-angular-icons'; import { IconsModule } from '@progress/kendo-angular-icons';
import { RatingComponent } from './transaction-list/rating.component'; import { RatingComponent } from './transaction-list/rating.component';
import { TransDetailsComponent } from './trans-details/trans-details.component'; import { TransDetailsComponent } from './trans-details/trans-details.component';
import { TransTailsComponent } from './trans-details/trans-tails/trans-tails.component'; import { TransTailsComponent } from './trans-details/trans-tails/trans-tails.component';
import {AuthHttpInterceptor} from './auth/auth-http-interceptor.service';






DropDownsModule, DropDownsModule,
ExcelExportModule ExcelExportModule
], ],
providers: [MenuService, AuthGuard, AuthService],
providers: [
MenuService,
AuthGuard,
AuthService,
{
provide: HTTP_INTERCEPTORS,
useClass: AuthHttpInterceptor,
multi: true
}
],
bootstrap: [AppComponent] bootstrap: [AppComponent]
}) })
export class AppModule { } export class AppModule { }

+ 39
- 0
src/app/auth/auth-http-interceptor.service.ts Просмотреть файл

import {Injectable} from '@angular/core';
import {HttpEvent, HttpEventType, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Observable} from 'rxjs';
import {AuthService} from '../service/auth.service';
import {tap} from 'rxjs/operators';


@Injectable()
export class AuthHttpInterceptor implements HttpInterceptor {

constructor(private auth: AuthService) {
}

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let h = req.headers;
if (this.auth.loggedIn.hasValidSession()) {
h = h.set('Biukop-Session', this.auth.loggedIn.session);
}

if (this.auth.loggedIn.hasValidMachineId()) {
h = h.set('Biukop-Mid', this.auth.loggedIn.machineId);
}

const authReq = req.clone({
headers: h,
withCredentials: true
});
return next.handle(authReq).pipe(
tap(event => {
console.log(event);
if (event.type === HttpEventType.Response){
console.log('Response received');
console.log(event.body);
this.auth.logout();
}
})
);
}
}

+ 4
- 4
src/app/auth/auth.component.ts Просмотреть файл

import { NotificationService } from '@progress/kendo-angular-notification'; import { NotificationService } from '@progress/kendo-angular-notification';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { AuthService } from '../service/auth.service'; import { AuthService } from '../service/auth.service';
import {apiv1LoginResponse} from '../models/api-v1-login-response';
import {apiV1LoginResponse} from '../models/api-v1-login-response';


@Component({ @Component({
selector: 'app-auth', selector: 'app-auth',
ngOnInit(): void { ngOnInit(): void {
this.loginSub = this.authService.loginSuccess.subscribe( this.loginSub = this.authService.loginSuccess.subscribe(
responseData => { responseData => {
console.log(responseData);
// console.log(responseData);
this.onLogin(responseData); this.onLogin(responseData);
} }
); );
this.authService.login(this.userForm.value.email, this.userForm.value.password); this.authService.login(this.userForm.value.email, this.userForm.value.password);
} }


public onLogin(rsp: apiv1LoginResponse) {
public onLogin(rsp: apiV1LoginResponse) {
this.loading = false; this.loading = false;
console.log ('found login ' , rsp );
// console.log ('found login ' , rsp );
if (rsp.login) { if (rsp.login) {
this.router.navigate(['/dashboard']); this.router.navigate(['/dashboard']);
} }

+ 5
- 3
src/app/canvas/canvas.component.html Просмотреть файл

<kendo-menu> <kendo-menu>
<kendo-menu-item text="My Web Site" icon="folder"> <kendo-menu-item text="My Web Site" icon="folder">
<kendo-menu-item text="images" icon="folder"> <kendo-menu-item text="images" icon="folder">
<kendo-menu-item text="logo.png" icon="image"></kendo-menu-item> <kendo-menu-item text="logo.png" icon="image"></kendo-menu-item>
<kendo-menu-item text="body-back.png" icon="image"></kendo-menu-item> <kendo-menu-item text="body-back.png" icon="image"></kendo-menu-item>
<kendo-menu-item text="my-photo.png" icon="image"></kendo-menu-item> <kendo-menu-item text="my-photo.png" icon="image"></kendo-menu-item>
</kendo-menu> </kendo-menu>
<kendo-icon [name]="'photo-camera'" [size]="'medium'"></kendo-icon> <kendo-icon [name]="'photo-camera'" [size]="'medium'"></kendo-icon>


<button kendoButton (click)="onButtonClick()">Default</button>

<bkp-divider-text>some text</bkp-divider-text> <bkp-divider-text>some text</bkp-divider-text>
<bkp-divider-shadow-bottom></bkp-divider-shadow-bottom> <bkp-divider-shadow-bottom></bkp-divider-shadow-bottom>
<bkp-divider><kendo-icon [name]="'sum'"> </kendo-icon> &nbsp; Pending <bkp-divider><kendo-icon [name]="'sum'"> </kendo-icon> &nbsp; Pending
Payments</bkp-divider> Payments</bkp-divider>
<kendo-chart> <kendo-chart>
<kendo-chart-title text="Units sold"></kendo-chart-title> <kendo-chart-title text="Units sold"></kendo-chart-title>


<kendo-chart-series-item type="area" [data]="[56, 140, 195, 46, 123, 78, 95]"> <kendo-chart-series-item type="area" [data]="[56, 140, 195, 46, 123, 78, 95]">
</kendo-chart-series-item> </kendo-chart-series-item>
</kendo-chart-series> </kendo-chart-series>
</kendo-chart>
</kendo-chart>


<hr> <hr>



+ 8
- 3
src/app/canvas/canvas.component.ts Просмотреть файл

import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { sampleProducts } from '../models/sample_product'; import { sampleProducts } from '../models/sample_product';
import { MenuService } from '../service/menu.service'; import { MenuService } from '../service/menu.service';
import {AuthService} from '../service/auth.service';


@Component({ @Component({
selector: 'app-canvas', selector: 'app-canvas',


private menutItemSub: Subscription; private menutItemSub: Subscription;




constructor(private menuService: MenuService) { }

constructor(private authService: AuthService, private menuService: MenuService) { }


ngOnInit(): void { ngOnInit(): void {
this.menutItemSub = this.menuService.itemClicked.subscribe( this.menutItemSub = this.menuService.itemClicked.subscribe(
); );
} }
ngOnDestroy(): void{ ngOnDestroy(): void{
this.menutItemSub.unsubscribe();
this.menutItemSub.unsubscribe();
} }


onButtonClick(){
console.log("ok");
this.authService.anyhttp();
}


} }

+ 6
- 5
src/app/dashboard/dashboard.component.html Просмотреть файл

<div class="container outer"> <div class="container outer">
<div class="container inner"> <div class="container inner">
<bkp-divider-shadow-bottom></bkp-divider-shadow-bottom>
<bkp-divider-shadow-bottom></bkp-divider-shadow-bottom>
<bkp-divider> <bkp-divider>
<kendo-icon [name]="'ascx'" > </kendo-icon> &nbsp; Daily summary
<kendo-icon [name]="'ascx'" > </kendo-icon> &nbsp; Daily summary
</bkp-divider> </bkp-divider>

<div class="row"> <div class="row">
<div class="col-sm-6"> <div class="col-sm-6">
<kendo-chart> <kendo-chart>
</kendo-grid> </kendo-grid>
</div> </div>
</div> </div>
<bkp-divider-shadow-bottom></bkp-divider-shadow-bottom>
<bkp-divider-shadow-bottom></bkp-divider-shadow-bottom>
</div> </div>
</div>
</div>

+ 4
- 2
src/app/dashboard/dashboard.component.ts Просмотреть файл

import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { sampleProducts } from '../models/sample_product'; import { sampleProducts } from '../models/sample_product';
import {AuthService} from '../service/auth.service';






export class DashboardComponent implements OnInit { export class DashboardComponent implements OnInit {


public gridData: any[] = sampleProducts; public gridData: any[] = sampleProducts;
constructor() { }
constructor(private authService: AuthService) { }


ngOnInit(): void { ngOnInit(): void {
} }



} }

+ 32
- 3
src/app/models/api-v1-login-response.ts Просмотреть файл





// tslint:disable-next-line:class-name // tslint:disable-next-line:class-name
export class apiv1LoginResponse {
id?: string;
login: boolean;
export class apiV1LoginResponse {



// tslint:disable-next-line:typedef
constructor(
public login: boolean,
public machineId: string,
public session: string,
public sessionExpire: number // unix timestamp
) {
this.login = login;
this.machineId = machineId;
this.session = session;
this.sessionExpire = sessionExpire;
}

// tslint:disable-next-line:typedef
public hasValidSession(): boolean {
if (this.session === undefined || this.session === '') {
return false;
}else{
return true;
}
}

// tslint:disable-next-line:typedef
public hasValidMachineId(): boolean {
if (this.machineId === undefined || this.machineId === '') {
return false;
}else{
return true;
}
}
} }

+ 52
- 17
src/app/service/auth.service.ts Просмотреть файл

import { EventEmitter, Injectable } from '@angular/core';
import {EventEmitter, Injectable, OnDestroy, OnInit} from '@angular/core';
import { NotificationService } from '@progress/kendo-angular-notification'; import { NotificationService } from '@progress/kendo-angular-notification';
import {HttpClient} from '@angular/common/http';
import {apiv1LoginResponse} from '../models/api-v1-login-response';
import {HttpClient, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {apiV1LoginResponse} from '../models/api-v1-login-response';
import {Observable} from 'rxjs';
import {AppComponent} from '../app.component';
import {Router} from '@angular/router';


@Injectable() @Injectable()
export class AuthService { export class AuthService {
private loggedIn = false;
loginSuccess = new EventEmitter <apiv1LoginResponse>();


constructor( private http: HttpClient) {
public loggedIn = new apiV1LoginResponse(false, '','',0 );
loginSuccess = new EventEmitter <apiV1LoginResponse>();

constructor( private http: HttpClient ,
private router: Router) {
}


// tslint:disable-next-line:typedef
public AutoLogin() {
const sfm: apiV1LoginResponse = JSON.parse(localStorage.getItem('sfm'));
if (!sfm) {
console.log('no auto login');
return;
}
this.loggedIn = new apiV1LoginResponse(
sfm.login,
sfm.machineId,
sfm.session,
sfm.sessionExpire
);
} }


// tslint:disable-next-line:typedef // tslint:disable-next-line:typedef
isAuthenticated() { isAuthenticated() {
return this.loggedIn;
return this.loggedIn.login;
} }


// tslint:disable-next-line:typedef // tslint:disable-next-line:typedef
login(email: string, password: string) { login(email: string, password: string) {


this.http.post<apiv1LoginResponse>('http://svr2021:8080/api/v1/login', {u: email, p: password}).subscribe(
this.http.post<apiV1LoginResponse>('https://svr2021.lawipac.com:8080/api/v1/login', {u: email, p: password}).subscribe(
responseData => { responseData => {
this.loggedIn = responseData.login;
this.loginSuccess.emit(responseData);
this.loggedIn.session = responseData['Biukop-Session'];
this.loggedIn.login = responseData.login;
this.loggedIn.machineId = responseData['Biukop-Mid'];
this.loggedIn.sessionExpire = responseData.sessionExpire;
localStorage.setItem('sfm', JSON.stringify(this.loggedIn));
this.loginSuccess.emit(responseData);
}, },
error => { error => {
const fail = {
login: false
};
console.log(error);
this.loginSuccess.emit(fail);
const fail = new apiV1LoginResponse(false,'','',0);
this.loggedIn = fail;
console.log('login error', error);
this.loginSuccess.emit(this.loggedIn);
} }


); );


// tslint:disable-next-line:typedef // tslint:disable-next-line:typedef
logout() { logout() {
this.loggedIn = false;
}
console.log('trying to log out');
this.loggedIn = new apiV1LoginResponse(false,'','',0);
localStorage.removeItem('sfm');
this.loginSuccess.emit(this.loggedIn);
this.router.navigate(['/login']);


}


anyhttp(){
this.http.get('https://svr2021.lawipac.com:8080/api/v1/').subscribe(
response => {
console.log(response);
}
);
}


} }

Загрузка…
Отмена
Сохранить