| @@ -11242,9 +11242,9 @@ | |||
| } | |||
| }, | |||
| "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": { | |||
| "tslib": "^1.9.0" | |||
| }, | |||
| @@ -3,7 +3,7 @@ | |||
| "version": "0.0.0", | |||
| "scripts": { | |||
| "ng": "ng", | |||
| "start": "ng serve", | |||
| "start": "ng serve --proxy-config proxy.conf.json", | |||
| "build": "ng build", | |||
| "test": "ng test", | |||
| "lint": "ng lint", | |||
| @@ -49,10 +49,10 @@ | |||
| "@progress/kendo-svg-icons": "^0.0.3", | |||
| "@progress/kendo-theme-default": "latest", | |||
| "bootstrap": "^3.4.1", | |||
| "rxjs": "~6.6.0", | |||
| "hammerjs": "^2.0.0", | |||
| "rxjs": "^6.6.6", | |||
| "tslib": "^2.0.0", | |||
| "zone.js": "~0.10.2", | |||
| "hammerjs": "^2.0.0" | |||
| "zone.js": "~0.10.2" | |||
| }, | |||
| "devDependencies": { | |||
| "@angular-devkit/build-angular": "~0.1002.0", | |||
| @@ -0,0 +1,7 @@ | |||
| { | |||
| "/api/v1": { | |||
| "target": "http://svr2021:8080", | |||
| "secure": false, | |||
| "pathRewrite": {"^/api/v1" : "/api/v1"} | |||
| } | |||
| } | |||
| @@ -5,7 +5,7 @@ import { LoanEditComponent } from './loan-edit/loan-edit.component'; | |||
| import { mainMenuItems } from './main-menu-items'; | |||
| import { AuthService } from './service/auth.service'; | |||
| import { MenuService } from './service/menu.service'; | |||
| import {apiv1LoginResponse} from './models/api-v1-login-response'; | |||
| import {apiV1LoginResponse} from './models/api-v1-login-response'; | |||
| @Component({ | |||
| selector: 'app-root', | |||
| @@ -17,8 +17,8 @@ export class AppComponent implements OnInit , OnDestroy { | |||
| title = 'SFM broker'; | |||
| public login = false; | |||
| 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; | |||
| @@ -49,16 +49,18 @@ export class AppComponent implements OnInit , OnDestroy { | |||
| } | |||
| // tslint:disable-next-line:typedef | |||
| ngOnInit (){ | |||
| ngOnInit() { | |||
| this.loginSub = this.authService.loginSuccess.subscribe( | |||
| (rsp: apiv1LoginResponse) => { | |||
| (rsp: apiV1LoginResponse) => { | |||
| this.login = rsp.login; | |||
| } | |||
| ); | |||
| this.authService.AutoLogin(); | |||
| } | |||
| // tslint:disable-next-line:typedef | |||
| ngOnDestroy (){ | |||
| ngOnDestroy() { | |||
| this.loginSub.unsubscribe(); | |||
| } | |||
| @@ -0,0 +1 @@ | |||
| @@ -5,7 +5,7 @@ import { CommonModule } from '@angular/common'; | |||
| import { BrowserModule } from '@angular/platform-browser'; | |||
| import { FormsModule, ReactiveFormsModule } from '@angular/forms'; | |||
| import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; | |||
| import { HttpClientModule} from '@angular/common/http'; | |||
| import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http'; | |||
| //Kendo | |||
| import { MenuModule, ContextMenuModule } from '@progress/kendo-angular-menu'; | |||
| import { IconsModule } from '@progress/kendo-angular-icons'; | |||
| @@ -43,6 +43,7 @@ import { ExcelExportModule } from '@progress/kendo-angular-excel-export'; | |||
| import { RatingComponent } from './transaction-list/rating.component'; | |||
| import { TransDetailsComponent } from './trans-details/trans-details.component'; | |||
| import { TransTailsComponent } from './trans-details/trans-tails/trans-tails.component'; | |||
| import {AuthHttpInterceptor} from './auth/auth-http-interceptor.service'; | |||
| @@ -90,7 +91,16 @@ import { TransTailsComponent } from './trans-details/trans-tails/trans-tails.com | |||
| DropDownsModule, | |||
| ExcelExportModule | |||
| ], | |||
| providers: [MenuService, AuthGuard, AuthService], | |||
| providers: [ | |||
| MenuService, | |||
| AuthGuard, | |||
| AuthService, | |||
| { | |||
| provide: HTTP_INTERCEPTORS, | |||
| useClass: AuthHttpInterceptor, | |||
| multi: true | |||
| } | |||
| ], | |||
| bootstrap: [AppComponent] | |||
| }) | |||
| export class AppModule { } | |||
| @@ -0,0 +1,39 @@ | |||
| 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,7 +4,7 @@ import { Router } from '@angular/router'; | |||
| import { NotificationService } from '@progress/kendo-angular-notification'; | |||
| import { Subscription } from 'rxjs'; | |||
| import { AuthService } from '../service/auth.service'; | |||
| import {apiv1LoginResponse} from '../models/api-v1-login-response'; | |||
| import {apiV1LoginResponse} from '../models/api-v1-login-response'; | |||
| @Component({ | |||
| selector: 'app-auth', | |||
| @@ -25,7 +25,7 @@ export class AuthComponent implements OnInit, OnDestroy{ | |||
| ngOnInit(): void { | |||
| this.loginSub = this.authService.loginSuccess.subscribe( | |||
| responseData => { | |||
| console.log(responseData); | |||
| // console.log(responseData); | |||
| this.onLogin(responseData); | |||
| } | |||
| ); | |||
| @@ -42,9 +42,9 @@ export class AuthComponent implements OnInit, OnDestroy{ | |||
| this.authService.login(this.userForm.value.email, this.userForm.value.password); | |||
| } | |||
| public onLogin(rsp: apiv1LoginResponse) { | |||
| public onLogin(rsp: apiV1LoginResponse) { | |||
| this.loading = false; | |||
| console.log ('found login ' , rsp ); | |||
| // console.log ('found login ' , rsp ); | |||
| if (rsp.login) { | |||
| this.router.navigate(['/dashboard']); | |||
| } | |||
| @@ -3,7 +3,7 @@ | |||
| <kendo-menu> | |||
| <kendo-menu-item text="My Web Site" icon="folder"> | |||
| <kendo-menu-item text="images" icon="folder"> | |||
| <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="my-photo.png" icon="image"></kendo-menu-item> | |||
| @@ -23,11 +23,13 @@ | |||
| </kendo-menu> | |||
| <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-shadow-bottom></bkp-divider-shadow-bottom> | |||
| <bkp-divider><kendo-icon [name]="'sum'"> </kendo-icon> Pending | |||
| Payments</bkp-divider> | |||
| <kendo-chart> | |||
| <kendo-chart-title text="Units sold"></kendo-chart-title> | |||
| @@ -49,7 +51,7 @@ | |||
| <kendo-chart-series-item type="area" [data]="[56, 140, 195, 46, 123, 78, 95]"> | |||
| </kendo-chart-series-item> | |||
| </kendo-chart-series> | |||
| </kendo-chart> | |||
| </kendo-chart> | |||
| <hr> | |||
| @@ -2,6 +2,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; | |||
| import { Subscription } from 'rxjs'; | |||
| import { sampleProducts } from '../models/sample_product'; | |||
| import { MenuService } from '../service/menu.service'; | |||
| import {AuthService} from '../service/auth.service'; | |||
| @Component({ | |||
| selector: 'app-canvas', | |||
| @@ -14,9 +15,9 @@ export class CanvasComponent implements OnInit, OnDestroy { | |||
| private menutItemSub: Subscription; | |||
| constructor(private menuService: MenuService) { } | |||
| constructor(private authService: AuthService, private menuService: MenuService) { } | |||
| ngOnInit(): void { | |||
| this.menutItemSub = this.menuService.itemClicked.subscribe( | |||
| @@ -26,8 +27,12 @@ export class CanvasComponent implements OnInit, OnDestroy { | |||
| ); | |||
| } | |||
| ngOnDestroy(): void{ | |||
| this.menutItemSub.unsubscribe(); | |||
| this.menutItemSub.unsubscribe(); | |||
| } | |||
| onButtonClick(){ | |||
| console.log("ok"); | |||
| this.authService.anyhttp(); | |||
| } | |||
| } | |||
| @@ -1,9 +1,10 @@ | |||
| <div class="container outer"> | |||
| <div class="container inner"> | |||
| <bkp-divider-shadow-bottom></bkp-divider-shadow-bottom> | |||
| <bkp-divider-shadow-bottom></bkp-divider-shadow-bottom> | |||
| <bkp-divider> | |||
| <kendo-icon [name]="'ascx'" > </kendo-icon> Daily summary | |||
| <kendo-icon [name]="'ascx'" > </kendo-icon> Daily summary | |||
| </bkp-divider> | |||
| <div class="row"> | |||
| <div class="col-sm-6"> | |||
| <kendo-chart> | |||
| @@ -96,7 +97,7 @@ | |||
| </kendo-grid> | |||
| </div> | |||
| </div> | |||
| <bkp-divider-shadow-bottom></bkp-divider-shadow-bottom> | |||
| <bkp-divider-shadow-bottom></bkp-divider-shadow-bottom> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -1,5 +1,6 @@ | |||
| import { Component, OnInit } from '@angular/core'; | |||
| import { sampleProducts } from '../models/sample_product'; | |||
| import {AuthService} from '../service/auth.service'; | |||
| @@ -11,10 +12,11 @@ import { sampleProducts } from '../models/sample_product'; | |||
| export class DashboardComponent implements OnInit { | |||
| public gridData: any[] = sampleProducts; | |||
| constructor() { } | |||
| constructor(private authService: AuthService) { } | |||
| ngOnInit(): void { | |||
| } | |||
| } | |||
| @@ -1,8 +1,37 @@ | |||
| // 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; | |||
| } | |||
| } | |||
| } | |||
| @@ -1,35 +1,59 @@ | |||
| import { EventEmitter, Injectable } from '@angular/core'; | |||
| import {EventEmitter, Injectable, OnDestroy, OnInit} from '@angular/core'; | |||
| 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() | |||
| 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 | |||
| isAuthenticated() { | |||
| return this.loggedIn; | |||
| return this.loggedIn.login; | |||
| } | |||
| // tslint:disable-next-line:typedef | |||
| 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 => { | |||
| 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 => { | |||
| 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); | |||
| } | |||
| ); | |||
| @@ -51,9 +75,20 @@ export class AuthService { | |||
| // tslint:disable-next-line:typedef | |||
| 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); | |||
| } | |||
| ); | |||
| } | |||
| } | |||