| } | } | ||||
| }, | }, | ||||
| "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" | ||||
| }, | }, |
| "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", |
| { | |||||
| "/api/v1": { | |||||
| "target": "http://svr2021:8080", | |||||
| "secure": false, | |||||
| "pathRewrite": {"^/api/v1" : "/api/v1"} | |||||
| } | |||||
| } |
| 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(); | ||||
| } | } | ||||
| 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 { } |
| 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(); | |||||
| } | |||||
| }) | |||||
| ); | |||||
| } | |||||
| } |
| 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']); | ||||
| } | } |
| <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> Pending | <bkp-divider><kendo-icon [name]="'sum'"> </kendo-icon> 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> | ||||
| 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(); | |||||
| } | |||||
| } | } |
| <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> Daily summary | |||||
| <kendo-icon [name]="'ascx'" > </kendo-icon> 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> |
| 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 { | ||||
| } | } | ||||
| } | } |
| // 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; | |||||
| } | |||||
| } | |||||
| } | } |
| 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); | |||||
| } | |||||
| ); | |||||
| } | |||||
| } | } |