| import { MenuService } from './service/menu.service'; | import { MenuService } from './service/menu.service'; | ||||
| import {WebSocketService} from './websocket'; | import {WebSocketService} from './websocket'; | ||||
| import {AppConfig} from './app.config'; | |||||
| import {Title} from '@angular/platform-browser'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-root', | selector: 'app-root', | ||||
| encapsulation: ViewEncapsulation.None | encapsulation: ViewEncapsulation.None | ||||
| }) | }) | ||||
| export class AppComponent implements OnInit , OnDestroy { | export class AppComponent implements OnInit , OnDestroy { | ||||
| title = 'SFM broker'; | |||||
| private menutItemSub: Subscription; | |||||
| title = 'SFM Advanced Loan management'; | |||||
| private menuItemSub: Subscription; | |||||
| @ViewChild('loanEditComponent', {static: true}) loanEdit: LoanEditComponent; | @ViewChild('loanEditComponent', {static: true}) loanEdit: LoanEditComponent; | ||||
| constructor(private menuService: MenuService, private authService: AuthService, private wsService: WebSocketService){ | |||||
| wsService.createObservableSocket(this.authService.apiWsUrl) | |||||
| .subscribe(m => { | |||||
| console.log('websocket server send this :', m); | |||||
| }); | |||||
| webSocketSubscription: Subscription; | |||||
| wsLoginSub: Subscription; | |||||
| constructor(private menuService: MenuService, | |||||
| private authService: AuthService, | |||||
| private config: AppConfig, | |||||
| private wsService: WebSocketService, | |||||
| private titleService: Title){ | |||||
| this.webSocketSubscription = wsService.subscribe(m => { | |||||
| console.log('websocket server send this :', m); | |||||
| }); | |||||
| this.wsLoginSub = this.wsService.LoginEvent.subscribe( m => { | |||||
| console.log('login event ', m); | |||||
| }); | |||||
| this.titleService.setTitle(this.title); | |||||
| } | } | ||||
| // tslint:disable-next-line:typedef | // tslint:disable-next-line:typedef | ||||
| } | } | ||||
| listenToMenuEvent(): void { | listenToMenuEvent(): void { | ||||
| this.menutItemSub = this.menuService.itemClicked.subscribe( | |||||
| this.menuItemSub = this.menuService.itemClicked.subscribe( | |||||
| (item:any) =>{ | (item:any) =>{ | ||||
| // console.log("emit on select : " + item.text); | // console.log("emit on select : " + item.text); | ||||
| if ( item.popup === 'loanEdit'){ | if ( item.popup === 'loanEdit'){ | ||||
| } | } | ||||
| // tslint:disable-next-line:typedef | |||||
| ngOnDestroy() { | |||||
| ngOnDestroy(): void { | |||||
| this.webSocketSubscription.unsubscribe(); | |||||
| this.wsLoginSub.unsubscribe(); | |||||
| } | } | ||||
| } | } |
| export class AppConfigModel { | export class AppConfigModel { | ||||
| Server = 'https://c5016.biukop.com.au:8080/api/v1/'; | Server = 'https://c5016.biukop.com.au:8080/api/v1/'; | ||||
| Socket = 'ws://c5016.biukop.com.au:8080/api/v1/'; | Socket = 'ws://c5016.biukop.com.au:8080/api/v1/'; | ||||
| SessionStorageKey = 'sk'; | |||||
| Version = 2021; | |||||
| } | } |
| static config: AppConfigModel; | static config: AppConfigModel; | ||||
| static debugConfig: AppConfigModel = { | static debugConfig: AppConfigModel = { | ||||
| Server: 'https://svr2021.lawipac.com:8080/api/v1/', | Server: 'https://svr2021.lawipac.com:8080/api/v1/', | ||||
| Socket: 'wss://svr2021.lawipac.com:8080/api/v1/ws' | |||||
| Socket: 'wss://svr2021.lawipac.com:8080/api/v1/ws', | |||||
| SessionStorageKey: 'sk', | |||||
| Version: 2021 | |||||
| }; | }; | ||||
| static productionConfig: AppConfigModel = { | static productionConfig: AppConfigModel = { | ||||
| Server: 'https://c5016.biukop.com.au:8080/api/v1/', | Server: 'https://c5016.biukop.com.au:8080/api/v1/', | ||||
| Socket: 'wss://c5016.biukop.com.au:8080/api/v1/ws' | |||||
| Socket: 'wss://c5016.biukop.com.au:8080/api/v1/ws', | |||||
| SessionStorageKey : 'sk', | |||||
| Version: 2021 | |||||
| }; | }; | ||||
| constructor(private http: HttpClient) {} | constructor(private http: HttpClient) {} | ||||
| return AppConfig.config.Socket; | return AppConfig.config.Socket; | ||||
| } | } | ||||
| public get storageKey(): string{ | |||||
| return AppConfig.config.SessionStorageKey; | |||||
| } | |||||
| public getUrl(key: string): string{ | public getUrl(key: string): string{ | ||||
| const s = this.apiUrl + key; | const s = this.apiUrl + key; | ||||
| const kvPair: {key: string, value: string}[] = [ | const kvPair: {key: string, value: string}[] = [ |
| import { RewardSelectComponent } from './reward-select/reward-select.component'; | import { RewardSelectComponent } from './reward-select/reward-select.component'; | ||||
| import { RewardsAllComponent } from './rewards-all/rewards-all.component'; | import { RewardsAllComponent } from './rewards-all/rewards-all.component'; | ||||
| import { SinglePayoutRewardsListComponent } from './single-payout-rewards-list/single-payout-rewards-list.component'; | import { SinglePayoutRewardsListComponent } from './single-payout-rewards-list/single-payout-rewards-list.component'; | ||||
| import {SessionService} from './service/session.service'; | |||||
| MenuService, | MenuService, | ||||
| AuthGuard, | AuthGuard, | ||||
| AuthService, | AuthService, | ||||
| SessionService, | |||||
| WebSocketService, | WebSocketService, | ||||
| LoanSummaryService, | LoanSummaryService, | ||||
| LoanSingleService, | LoanSingleService, |
| import {Injectable} from '@angular/core'; | import {Injectable} from '@angular/core'; | ||||
| import {HttpEvent, HttpEventType, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http'; | import {HttpEvent, HttpEventType, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http'; | ||||
| import {Observable} from 'rxjs'; | import {Observable} from 'rxjs'; | ||||
| import {AuthService} from '../service/auth.service'; | |||||
| import {tap} from 'rxjs/operators'; | import {tap} from 'rxjs/operators'; | ||||
| import {SessionService} from '../service/session.service'; | |||||
| @Injectable() | @Injectable() | ||||
| export class AuthHttpInterceptor implements HttpInterceptor { | export class AuthHttpInterceptor implements HttpInterceptor { | ||||
| constructor(private auth: AuthService) { | |||||
| constructor(private ss: SessionService) { | |||||
| } | } | ||||
| intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { | intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { | ||||
| let h = req.headers; | let h = req.headers; | ||||
| if (this.auth.loggedIn.hasValidSession()) { | |||||
| h = h.set('Biukop-Session', this.auth.loggedIn.session); | |||||
| if (this.ss.loggedIn.hasValidSession()) { | |||||
| h = h.set('Biukop-Session', this.ss.loggedIn.session); | |||||
| } | } | ||||
| if (this.auth.loggedIn.hasValidMachineId()) { | |||||
| h = h.set('Biukop-Mid', this.auth.loggedIn.machineId); | |||||
| if (this.ss.loggedIn.hasValidMachineId()) { | |||||
| h = h.set('Biukop-Mid', this.ss.loggedIn.machineId); | |||||
| } | } | ||||
| const authReq = req.clone({ | const authReq = req.clone({ | ||||
| if (event.type === HttpEventType.Response){ | if (event.type === HttpEventType.Response){ | ||||
| const bs = event.headers.get('biukop-session'); | const bs = event.headers.get('biukop-session'); | ||||
| if (bs !== undefined){ | if (bs !== undefined){ | ||||
| if ( this.auth.loggedIn.session !== bs ){ | |||||
| this.auth.loggedIn.session = bs; | |||||
| this.auth.saveSessionInfo(); | |||||
| if ( this.ss.loggedIn.session !== bs ){ | |||||
| this.ss.loggedIn.session = bs; | |||||
| this.ss.saveSessionInfo(); | |||||
| console.log('switch session:' , bs); | console.log('switch session:' , bs); | ||||
| } | } | ||||
| } | } |
| 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'; | ||||
| import {SessionService} from '../service/session.service'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-auth', | selector: 'app-auth', | ||||
| email: new FormControl('admin@supercredit.com.au', Validators.email) | email: new FormControl('admin@supercredit.com.au', Validators.email) | ||||
| }); | }); | ||||
| constructor(private authService: AuthService, private router: Router, private notificationService: NotificationService) { } | |||||
| constructor(private authService: AuthService, private ss: SessionService, | |||||
| private router: Router, private notificationService: NotificationService) { } | |||||
| ngOnInit(): void { | ngOnInit(): void { | ||||
| this.authService.logout(); | this.authService.logout(); | ||||
| this.loginSub = this.authService.loginSuccess.subscribe( | |||||
| this.loginSub = this.ss.loginSuccess.subscribe( | |||||
| responseData => { | responseData => { | ||||
| // console.log(responseData); | // console.log(responseData); | ||||
| this.onLogin(responseData); | this.onLogin(responseData); |
| import {Component, Input, OnInit} from '@angular/core'; | import {Component, Input, OnInit} from '@angular/core'; | ||||
| import {BrokerModel} from '../models/broker.model'; | |||||
| import {LoanModel} from '../models/loan.model'; | |||||
| import {LoanSummaryService} from '../service/loan_summary.service'; | import {LoanSummaryService} from '../service/loan_summary.service'; | ||||
| import {CompositeFilterDescriptor, SortDescriptor} from '@progress/kendo-data-query'; | import {CompositeFilterDescriptor, SortDescriptor} from '@progress/kendo-data-query'; | ||||
| import {AuthService} from '../service/auth.service'; | |||||
| import {PeopleModel} from '../models/people.model'; | import {PeopleModel} from '../models/people.model'; | ||||
| import {AppConfig} from '../app.config'; | |||||
| import {SessionService} from '../service/session.service'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-broker-loan-list', | selector: 'app-broker-loan-list', | ||||
| @Input() public broker: PeopleModel = PeopleModel.EmptyNew(); | @Input() public broker: PeopleModel = PeopleModel.EmptyNew(); | ||||
| public brokerLoans: LoanSummaryService; | public brokerLoans: LoanSummaryService; | ||||
| constructor( private lss: LoanSummaryService, private auth: AuthService) { } | |||||
| constructor( private lss: LoanSummaryService, private ss: SessionService, private config: AppConfig) { } | |||||
| ngOnInit(): void { | ngOnInit(): void { | ||||
| this.brokerLoans = this.lss; | this.brokerLoans = this.lss; | ||||
| this.broker = this.auth.loggedIn.User; | |||||
| this.broker = this.ss.loggedIn.User; | |||||
| this.loadData(); | this.loadData(); | ||||
| } | } | ||||
| } | } | ||||
| private photoURL(peopleId: any): string { | private photoURL(peopleId: any): string { | ||||
| const url = this.auth.getUrl('avatar/') + peopleId; | |||||
| const url = this.config.getUrl('avatar/') + peopleId; | |||||
| return 'url("' + url + '")'; | return 'url("' + url + '")'; | ||||
| } | } | ||||
| } | } |
| import {AuthService} from '../service/auth.service'; | import {AuthService} from '../service/auth.service'; | ||||
| import {RewardByUserModel} from '../models/reward-by-user.model'; | import {RewardByUserModel} from '../models/reward-by-user.model'; | ||||
| import {DataResult, GroupDescriptor, process} from '@progress/kendo-data-query'; | import {DataResult, GroupDescriptor, process} from '@progress/kendo-data-query'; | ||||
| import {SessionService} from '../service/session.service'; | |||||
| import {AppConfig} from '../app.config'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-broker-reward', | selector: 'app-broker-reward', | ||||
| public groups: GroupDescriptor[] = [{ field: 'Description' }, { field: 'Item' } ]; | public groups: GroupDescriptor[] = [{ field: 'Description' }, { field: 'Item' } ]; | ||||
| public gridView: DataResult; | public gridView: DataResult; | ||||
| constructor(private http: HttpClient, private auth: AuthService ) { } | |||||
| constructor(private http: HttpClient, private ss: SessionService, private config: AppConfig ) { } | |||||
| ngOnInit(): void { | ngOnInit(): void { | ||||
| this.loading = true; | this.loading = true; | ||||
| this.gridData = []; | this.gridData = []; | ||||
| // avoid loading everything when used with admin user | // avoid loading everything when used with admin user | ||||
| if ( this.auth.loggedIn.role === 'admin' && this.selectedBrokerId === '' ) { | |||||
| if ( this.ss.loggedIn.role === 'admin' && this.selectedBrokerId === '' ) { | |||||
| this.loading = false; | this.loading = false; | ||||
| return ; | return ; | ||||
| } | } | ||||
| // load a single user | // load a single user | ||||
| this.http.get<RewardByUserModel[]>(this.auth.getUrl('user-reward/' + this.selectedBrokerId )).subscribe( | |||||
| this.http.get<RewardByUserModel[]>(this.config.getUrl('user-reward/' + this.selectedBrokerId )).subscribe( | |||||
| rsp => { | rsp => { | ||||
| rsp.forEach(v => { | rsp.forEach(v => { | ||||
| this.gridData.push(new RewardByUserModel(v)); | this.gridData.push(new RewardByUserModel(v)); |
| import {LoanModel} from '../models/loan.model'; | import {LoanModel} from '../models/loan.model'; | ||||
| import {LoanSingleService} from '../service/loan.single.service'; | import {LoanSingleService} from '../service/loan.single.service'; | ||||
| import {AuthService} from '../service/auth.service'; | import {AuthService} from '../service/auth.service'; | ||||
| import {SessionService} from '../service/session.service'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-client-loan-list', | selector: 'app-client-loan-list', | ||||
| public Loans: LoanModel[] =[]; | public Loans: LoanModel[] =[]; | ||||
| constructor(private ls: LoanSingleService, private auth: AuthService) { } | |||||
| constructor(private ls: LoanSingleService, private ss: SessionService) { } | |||||
| ngOnInit(): void { | ngOnInit(): void { | ||||
| this.ls.getLoanByClient(this.auth.loggedIn.User.Id).subscribe( | |||||
| this.ls.getLoanByClient(this.ss.loggedIn.User.Id).subscribe( | |||||
| resp => { | resp => { | ||||
| this.Loans = []; | this.Loans = []; | ||||
| resp.forEach( v => { | resp.forEach( v => { |
| import {FileInfo, FileRestrictions, FileSelectComponent, SelectEvent} from '@progress/kendo-angular-upload'; | import {FileInfo, FileRestrictions, FileSelectComponent, SelectEvent} from '@progress/kendo-angular-upload'; | ||||
| import {BrokerModel} from '../models/broker.model'; | import {BrokerModel} from '../models/broker.model'; | ||||
| import {AppConfig} from '../app.config'; | import {AppConfig} from '../app.config'; | ||||
| import {SessionService} from '../service/session.service'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-client-profile', | selector: 'app-client-profile', | ||||
| public opened = false; // dialog box | public opened = false; // dialog box | ||||
| public Message = ''; // dialog message | public Message = ''; // dialog message | ||||
| constructor(private auth: AuthService, private ps: PeopleService) { | |||||
| constructor(private ss: SessionService, private config: AppConfig, private ps: PeopleService) { | |||||
| this.avatarUrl = 'url("' + location.origin + './assets/img/avatar.png' + '")'; | this.avatarUrl = 'url("' + location.origin + './assets/img/avatar.png' + '")'; | ||||
| } | } | ||||
| ngOnInit(): void { | ngOnInit(): void { | ||||
| this.User = this.auth.loggedIn.User; | |||||
| this.avatarUrl = 'url(' + this.auth.getUrl('avatar/' + this.User.Id) + ')'; | |||||
| this.User = this.ss.loggedIn.User; | |||||
| this.avatarUrl = 'url(' + this.config.getUrl('avatar/' + this.User.Id) + ')'; | |||||
| } | } | ||||
| public sessionExpire: number, // unix timestamp | public sessionExpire: number, // unix timestamp | ||||
| public role: string, | public role: string, | ||||
| public User: PeopleModel, | public User: PeopleModel, | ||||
| public UserExtra?: UserExtraModel // extra user informaiton | |||||
| public UserExtra?: UserExtraModel // extra user information | |||||
| ) { | ) { | ||||
| this.login = login; | this.login = login; | ||||
| this.machineId = machineId; | this.machineId = machineId; |
| import {PeopleModel} from './people.model'; | |||||
| import {BrokerModel} from './broker.model'; | |||||
| export enum UserRoles { | |||||
| Unknown = 'Unknown', | |||||
| People = 'People', | |||||
| Broker = 'Broker', | |||||
| Beneficiary = 'Beneficiary', | |||||
| Admin = 'admin', | |||||
| Accountant = 'accountant', | |||||
| Super = 'super', | |||||
| } | |||||
| export class UserModel extends PeopleModel{ | |||||
| Role: UserRoles; | |||||
| Broker?: BrokerModel; | |||||
| Login: string; | |||||
| constructor(payload: Partial<UserModel>) { | |||||
| super(payload); | |||||
| this.Role = payload.Role || 'People' as UserRoles; | |||||
| this.Login = payload.Login || ''; | |||||
| this.Broker = new BrokerModel(payload); | |||||
| } | |||||
| } |
| export class WsLoginEventModel{ | |||||
| T: string; | |||||
| Mid: string; | |||||
| Sid: string; | |||||
| Uid: string; | |||||
| Role: string; | |||||
| constructor( payload: Partial<WsLoginEventModel>) { | |||||
| this.T = payload.T || ''; | |||||
| this.Mid = payload.Mid || ''; | |||||
| this.Sid = payload.Sid || ''; | |||||
| this.Uid = payload.Uid || ''; | |||||
| this.Role = payload.Uid || ''; | |||||
| } | |||||
| } |
| import {MessageBoxComponent} from '../../message-box/message-box.component'; | import {MessageBoxComponent} from '../../message-box/message-box.component'; | ||||
| import {UserExtraModel} from '../../models/user-extra.model'; | import {UserExtraModel} from '../../models/user-extra.model'; | ||||
| import {PeopleModel} from '../../models/people.model'; | import {PeopleModel} from '../../models/people.model'; | ||||
| import {SessionService} from '../../service/session.service'; | |||||
| @ViewChild('messageBox', {static: true})msgBox: MessageBoxComponent; | @ViewChild('messageBox', {static: true})msgBox: MessageBoxComponent; | ||||
| public isAdmin = false; | public isAdmin = false; | ||||
| constructor( private auth: AuthService, private ps: PeopleService) { } | |||||
| constructor( private ss: SessionService, private ps: PeopleService) { } | |||||
| ngOnInit(): void { | ngOnInit(): void { | ||||
| this.isAdmin = this.auth.isAdmin(); | |||||
| this.isAdmin = this.ss.isAdmin(); | |||||
| } | } | ||||
| public save(brokerForm: NgForm): void{ | public save(brokerForm: NgForm): void{ |
| import {AuthService} from '../../service/auth.service'; | import {AuthService} from '../../service/auth.service'; | ||||
| import {PeopleService} from '../../service/people.service'; | import {PeopleService} from '../../service/people.service'; | ||||
| import {MessageBoxComponent} from '../../message-box/message-box.component'; | import {MessageBoxComponent} from '../../message-box/message-box.component'; | ||||
| import {SessionService} from '../../service/session.service'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-change-password', | selector: 'app-change-password', | ||||
| NewPass: new FormControl(), | NewPass: new FormControl(), | ||||
| NewPass1: new FormControl(), | NewPass1: new FormControl(), | ||||
| }); | }); | ||||
| constructor(private auth: AuthService, private ps: PeopleService) { } | |||||
| constructor(private ss: SessionService, private ps: PeopleService) { } | |||||
| ngOnInit(): void { | ngOnInit(): void { | ||||
| if (this.auth.isAdmin() && this.PeopleId !== '' && !this.auth.isCurrentUser(this.PeopleId)) { | |||||
| this.isAdmin = this.auth.isAdmin(); | |||||
| if (this.ss.isAdmin() && this.PeopleId !== '' && !this.ss.isCurrentUser(this.PeopleId)) { | |||||
| this.isAdmin = this.ss.isAdmin(); | |||||
| } | } | ||||
| } | } | ||||
| public hidePass(): void{ | public hidePass(): void{ | ||||
| } | } | ||||
| public canChangePassword(): boolean { | public canChangePassword(): boolean { | ||||
| if ( this.auth.isCurrentUser(this.PeopleId) ) { | |||||
| return this.auth.isUser() || this.auth.isBroker() || this.auth.isAdmin(); | |||||
| if ( this.ss.isCurrentUser(this.PeopleId) ) { | |||||
| return this.ss.isUser() || this.ss.isBroker() || this.ss.isAdmin(); | |||||
| }else{ | }else{ | ||||
| return this.auth.isAdmin() ; | |||||
| return this.ss.isAdmin() ; | |||||
| } | } | ||||
| } | } | ||||
| } | } |
| import {PeopleService} from '../../service/people.service'; | import {PeopleService} from '../../service/people.service'; | ||||
| import {NgForm} from '@angular/forms'; | import {NgForm} from '@angular/forms'; | ||||
| import {PeopleModel} from '../../models/people.model'; | import {PeopleModel} from '../../models/people.model'; | ||||
| import {SessionService} from '../../service/session.service'; | |||||
| import {AppConfig} from '../../app.config'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-people-profile', | selector: 'app-people-profile', | ||||
| @ViewChild('messagebox', {static: true}) msgBox: MessageBoxComponent; | @ViewChild('messagebox', {static: true}) msgBox: MessageBoxComponent; | ||||
| @ViewChild('fileSelect', {static: true}) fs: FileSelectComponent; | @ViewChild('fileSelect', {static: true}) fs: FileSelectComponent; | ||||
| constructor(private auth: AuthService, private ps: PeopleService) { } | |||||
| constructor(private ss: SessionService, private config: AppConfig, private ps: PeopleService) { } | |||||
| ngOnInit(): void { | ngOnInit(): void { | ||||
| if (this.auth.isAdmin() && !this.auth.isCurrentUser(this.People.Id)) { | |||||
| if (this.ss.isAdmin() && !this.ss.isCurrentUser(this.People.Id)) { | |||||
| // | // | ||||
| }else{ | }else{ | ||||
| this.People = this.auth.loggedIn.User; | |||||
| this.People = this.ss.loggedIn.User; | |||||
| } | } | ||||
| this.avatarUrl = 'url(' + this.auth.getUrl('avatar/' + this.People.Id) + ')'; | |||||
| this.avatarUrl = 'url(' + this.config.getUrl('avatar/' + this.People.Id) + ')'; | |||||
| } | } | ||||
| onDialogClose(status: string): void { | onDialogClose(status: string): void { | ||||
| } | } | ||||
| this.ps.savePeople(this.People).subscribe( () => { | this.ps.savePeople(this.People).subscribe( () => { | ||||
| this.msgBox.Show('Updated successfully '); | this.msgBox.Show('Updated successfully '); | ||||
| if ( this.auth.loggedIn.User.Id === this.People.Id ) { | |||||
| this.auth.UpdatePeopleInfo(this.People); | |||||
| if ( this.ss.loggedIn.User.Id === this.People.Id ) { | |||||
| this.ss.UpdatePeopleInfo(this.People); | |||||
| } | } | ||||
| peopleForm.form.markAsPristine(); | peopleForm.form.markAsPristine(); | ||||
| }, err => { | }, err => { | ||||
| ppl => { | ppl => { | ||||
| this.People.Copy(ppl); | this.People.Copy(ppl); | ||||
| this.newPeople.emit(this.People); | this.newPeople.emit(this.People); | ||||
| this.avatarUrl = 'url(' + this.auth.getUrl('avatar/' + this.People.Id) + ')'; | |||||
| this.avatarUrl = 'url(' + this.config.getUrl('avatar/' + this.People.Id) + ')'; | |||||
| } | } | ||||
| ); | ); | ||||
| } | } | ||||
| public PeopleChanged(ppl: PeopleModel): void { | public PeopleChanged(ppl: PeopleModel): void { | ||||
| console.log(this); | console.log(this); | ||||
| this.avatarUrl = 'url(' + this.auth.getUrl('avatar/' + this.People.Id) + ')'; | |||||
| this.avatarUrl = 'url(' + this.config.getUrl('avatar/' + this.People.Id) + ')'; | |||||
| } | } | ||||
| public startSelectAvatar(): void { | public startSelectAvatar(): void { |
| import {UserExtraModel} from '../models/user-extra.model'; | import {UserExtraModel} from '../models/user-extra.model'; | ||||
| import {MessageBoxComponent} from '../message-box/message-box.component'; | import {MessageBoxComponent} from '../message-box/message-box.component'; | ||||
| import {setTime} from '@progress/kendo-angular-dateinputs/dist/es2015/util'; | import {setTime} from '@progress/kendo-angular-dateinputs/dist/es2015/util'; | ||||
| import {SessionService} from '../service/session.service'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-profile', | selector: 'app-profile', | ||||
| public isValidPeople = true; | public isValidPeople = true; | ||||
| public isValidBroker = true; | public isValidBroker = true; | ||||
| constructor(private auth: AuthService, private ps: PeopleService, private actRoute: ActivatedRoute) { } | |||||
| constructor(private auth: AuthService, private ss: SessionService, private ps: PeopleService, private actRoute: ActivatedRoute) { } | |||||
| ngOnInit(): void { | ngOnInit(): void { | ||||
| const id = this.actRoute.snapshot.params.id; | const id = this.actRoute.snapshot.params.id; | ||||
| this.PeopleId = id; | this.PeopleId = id; | ||||
| } | } | ||||
| if (this.auth.isAdmin() && this.PeopleId !== '' ){ | |||||
| if (this.ss.isAdmin() && this.PeopleId !== '' ){ | |||||
| if (this.PeopleId === 'start-new-people' ){ | if (this.PeopleId === 'start-new-people' ){ | ||||
| return; | return; | ||||
| }else if (this.PeopleId !== '' && !this.auth.isCurrentUser(this.PeopleId)) { // admin editing someone else | |||||
| }else if (this.PeopleId !== '' && !this.ss.isCurrentUser(this.PeopleId)) { // admin editing someone else | |||||
| this.loadOtherPeople(); | this.loadOtherPeople(); | ||||
| } | } | ||||
| }else { // edit himself | }else { // edit himself | ||||
| this.role = this.auth.loggedIn.role; | |||||
| this.PeopleId = this.auth.loggedIn.User.Id; | |||||
| this.People = this.auth.loggedIn.User; | |||||
| this.UserExtra = this.auth.loggedIn.UserExtra; | |||||
| this.role = this.ss.loggedIn.role; | |||||
| this.PeopleId = this.ss.loggedIn.User.Id; | |||||
| this.People = this.ss.loggedIn.User; | |||||
| this.UserExtra = this.ss.loggedIn.UserExtra; | |||||
| } | } | ||||
| this.updateShowHide(); | this.updateShowHide(); | ||||
| } | } | ||||
| private updateShowHide(): void { | private updateShowHide(): void { | ||||
| this.resetShowHide(); | this.resetShowHide(); | ||||
| this.editOtherPeople = ! this.auth.isCurrentUser(this.PeopleId); | |||||
| this.editOtherPeople = ! this.ss.isCurrentUser(this.PeopleId); | |||||
| if ( this.editOtherPeople ) { | if ( this.editOtherPeople ) { | ||||
| this.showAdminTool = this.isAdmin() && this.People.Id !== '' ; | this.showAdminTool = this.isAdmin() && this.People.Id !== '' ; | ||||
| if ( this.showAdminTool ){ | if ( this.showAdminTool ){ | ||||
| // the user who performs this edit action | // the user who performs this edit action | ||||
| public isAdmin(): boolean { | public isAdmin(): boolean { | ||||
| return this.auth.isAdmin(); | |||||
| return this.ss.isAdmin(); | |||||
| } | } | ||||
| // the user who performs this edit action | // the user who performs this edit action | ||||
| public isBroker(): boolean { | public isBroker(): boolean { | ||||
| return this.auth.isBroker(); | |||||
| return this.ss.isBroker(); | |||||
| } | } | ||||
| // the user who performs this edit action | // the user who performs this edit action | ||||
| public isUser(): boolean { | public isUser(): boolean { | ||||
| return this.auth.isUser(); | |||||
| return this.ss.isUser(); | |||||
| } | } | ||||
| public deletePeople(): void { | public deletePeople(): void { |
| import {PeopleService} from '../../service/people.service'; | import {PeopleService} from '../../service/people.service'; | ||||
| import {asyncValidatorLoginAvailable} from '../../validator/unique.login.validator'; | import {asyncValidatorLoginAvailable} from '../../validator/unique.login.validator'; | ||||
| import {PeopleModel} from '../../models/people.model'; | import {PeopleModel} from '../../models/people.model'; | ||||
| import {SessionService} from '../../service/session.service'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-user-profile', | selector: 'app-user-profile', | ||||
| public UserForm: FormGroup; | public UserForm: FormGroup; | ||||
| constructor(private auth: AuthService, private http: HttpClient, private ps: PeopleService) { } | |||||
| constructor(private auth: AuthService, private ss: SessionService, private http: HttpClient) { } | |||||
| ngOnInit(): void { | ngOnInit(): void { | ||||
| this.showAdmin = this.auth.isAdmin(); | |||||
| this.isCurrentUser = this.auth.isCurrentUser(this.People.Id); | |||||
| this.showAdmin = this.ss.isAdmin(); | |||||
| this.isCurrentUser = this.ss.isCurrentUser(this.People.Id); | |||||
| if (this.auth.isAdmin() && !this.auth.isCurrentUser(this.People.Id)) { | |||||
| if (this.ss.isAdmin() && !this.ss.isCurrentUser(this.People.Id)) { | |||||
| // edit other people, | // edit other people, | ||||
| }else{ | }else{ | ||||
| this.People.Id = this.auth.loggedIn.User.Id; | |||||
| this.UserExtra = this.auth.loggedIn.UserExtra; | |||||
| this.People.Id = this.ss.loggedIn.User.Id; | |||||
| this.UserExtra = this.ss.loggedIn.UserExtra; | |||||
| } | } | ||||
| this.UserForm = new FormGroup({ | this.UserForm = new FormGroup({ | ||||
| Login: new FormControl({value: this.UserExtra.Login, disabled: ! this.showAdmin }, | Login: new FormControl({value: this.UserExtra.Login, disabled: ! this.showAdmin }, | ||||
| } | } | ||||
| public currentUserIsAdmin(): boolean { | public currentUserIsAdmin(): boolean { | ||||
| return this.auth.loggedIn.role === 'admin'; | |||||
| return this.ss.loggedIn.role === 'admin'; | |||||
| } | } | ||||
| public canEditUser(): boolean { | public canEditUser(): boolean { |
| import {UserExtraModel} from '../models/user-extra.model'; | import {UserExtraModel} from '../models/user-extra.model'; | ||||
| import {Observable} from 'rxjs'; | import {Observable} from 'rxjs'; | ||||
| import {AppConfig} from '../app.config'; | import {AppConfig} from '../app.config'; | ||||
| import {SessionService} from './session.service'; | |||||
| @Injectable() | @Injectable() | ||||
| export class AuthService { | export class AuthService { | ||||
| public apiUrl = ''; | |||||
| public apiWsUrl = ''; | |||||
| public loggedIn = ApiV1LoginResponse.EmptyNew(); | |||||
| loginSuccess = new EventEmitter <ApiV1LoginResponse>(); | |||||
| constructor( private http: HttpClient , | constructor( private http: HttpClient , | ||||
| private router: Router, | private router: Router, | ||||
| private config: AppConfig) { | |||||
| this.apiUrl = config.apiUrl; | |||||
| this.apiWsUrl = config.apiWsUrl; | |||||
| } | |||||
| private ss: SessionService, | |||||
| private config: AppConfig) { } | |||||
| public AutoLogin(): void { | public AutoLogin(): void { | ||||
| const sfm: ApiV1LoginResponse = JSON.parse(localStorage.getItem('sfm')); | |||||
| const sfm: ApiV1LoginResponse = JSON.parse(localStorage.getItem(this.config.storageKey)); | |||||
| if (!sfm) { | if (!sfm) { | ||||
| console.log('no auto login'); | console.log('no auto login'); | ||||
| return; | return; | ||||
| } | } | ||||
| this.loggedIn = new ApiV1LoginResponse( | |||||
| this.ss.loggedIn = new ApiV1LoginResponse( | |||||
| sfm.login, | sfm.login, | ||||
| sfm.machineId, | sfm.machineId, | ||||
| sfm.session, | sfm.session, | ||||
| ); | ); | ||||
| if ( sfm.UserExtra !== undefined ) { | if ( sfm.UserExtra !== undefined ) { | ||||
| this.loggedIn.UserExtra = new UserExtraModel(sfm.UserExtra); | |||||
| this.ss.loggedIn.UserExtra = new UserExtraModel(sfm.UserExtra); | |||||
| } | } | ||||
| this.loginSuccess.emit(this.loggedIn); | |||||
| // console.log ( 'auto login emit events', this.loggedIn); | |||||
| this.ss.loginSuccess.emit(this.ss.loggedIn); | |||||
| } | } | ||||
| isAuthenticated(): boolean { | isAuthenticated(): boolean { | ||||
| return this.loggedIn.login; | |||||
| return this.ss.loggedIn.login; | |||||
| } | } | ||||
| allowEditLoan(): boolean{ | allowEditLoan(): boolean{ | ||||
| } | } | ||||
| saveSessionInfo(): void { | saveSessionInfo(): void { | ||||
| localStorage.setItem('sfm', JSON.stringify(this.loggedIn)); | |||||
| localStorage.setItem('mid', this.loggedIn.machineId); | |||||
| localStorage.setItem(this.config.storageKey, JSON.stringify(this.ss.loggedIn)); | |||||
| localStorage.setItem('mid', this.ss.loggedIn.machineId); | |||||
| } | } | ||||
| login(email: string, password: string): void { | login(email: string, password: string): void { | ||||
| this.http.post<ApiV1LoginResponse>(this.apiUrl + 'login', {u: email, p: password}).subscribe( | |||||
| this.http.post<ApiV1LoginResponse>(this.config.apiUrl + 'login', {u: email, p: password}).subscribe( | |||||
| responseData => { | responseData => { | ||||
| this.loggedIn.session = responseData['Biukop-Session']; | |||||
| this.loggedIn.login = responseData.login; | |||||
| this.loggedIn.machineId = responseData['Biukop-Mid']; | |||||
| this.loggedIn.sessionExpire = responseData.sessionExpire; | |||||
| this.loggedIn.role = responseData.role; | |||||
| this.ss.loggedIn.session = responseData['Biukop-Session']; | |||||
| this.ss.loggedIn.login = responseData.login; | |||||
| this.ss.loggedIn.machineId = responseData['Biukop-Mid']; | |||||
| this.ss.loggedIn.sessionExpire = responseData.sessionExpire; | |||||
| this.ss.loggedIn.role = responseData.role; | |||||
| if ( responseData.User !== undefined) { | if ( responseData.User !== undefined) { | ||||
| this.loggedIn.User = new PeopleModel(responseData.User); | |||||
| this.ss.loggedIn.User = new PeopleModel(responseData.User); | |||||
| if (responseData.UserExtra !== undefined ) { | if (responseData.UserExtra !== undefined ) { | ||||
| this.loggedIn.UserExtra = new UserExtraModel(responseData.UserExtra); | |||||
| this.ss.loggedIn.UserExtra = new UserExtraModel(responseData.UserExtra); | |||||
| }else{ | }else{ | ||||
| this.loggedIn.UserExtra = UserExtraModel.EmptyNew(); | |||||
| this.ss.loggedIn.UserExtra = UserExtraModel.EmptyNew(); | |||||
| } | } | ||||
| }else{ | }else{ | ||||
| this.loggedIn.User = PeopleModel.EmptyNew(); | |||||
| this.ss.loggedIn.User = PeopleModel.EmptyNew(); | |||||
| } | } | ||||
| this.saveSessionInfo(); | this.saveSessionInfo(); | ||||
| this.loginSuccess.emit(responseData); | |||||
| this.ss.loginSuccess.emit(responseData); | |||||
| }, | }, | ||||
| error => { | error => { | ||||
| this.loggedIn = ApiV1LoginResponse.EmptyNew(); | |||||
| this.ss.loggedIn = ApiV1LoginResponse.EmptyNew(); | |||||
| console.log('login error', error); | console.log('login error', error); | ||||
| this.loginSuccess.emit(this.loggedIn); | |||||
| this.ss.loginSuccess.emit(this.ss.loggedIn); | |||||
| } | } | ||||
| ); | ); | ||||
| } | } | ||||
| logout(): void { | logout(): void { | ||||
| this.loggedIn = ApiV1LoginResponse.EmptyNew(); | |||||
| localStorage.removeItem('sfm'); | |||||
| this.loginSuccess.emit(this.loggedIn); | |||||
| this.router.navigate(['/login']).then(r => { | |||||
| console.log('prepare to log back in'); | |||||
| } ); | |||||
| this.http.post(`${this.apiUrl}logout`, '').subscribe( | |||||
| resp => { | |||||
| console.log('successfully logout from server'); | |||||
| }, | |||||
| event => { | |||||
| console.log('error logout from server', event); | |||||
| } | |||||
| ); | |||||
| this.ss.logout(); | |||||
| } | } | ||||
| public getUrl(key: string): string{ | public getUrl(key: string): string{ | ||||
| return this.config.getUrl(key); | return this.config.getUrl(key); | ||||
| // const s = this.apiUrl + key; | |||||
| // const kvPair: {key: string, value: string}[] = [ | |||||
| // {key: 'login', value: this.apiUrl + 'login'}, | |||||
| // {key: 'logout', value: this.apiUrl + 'logout'} | |||||
| // ]; | |||||
| // | |||||
| // kvPair.forEach( item => { | |||||
| // if ( item.key === key) { | |||||
| // return item.value; | |||||
| // } | |||||
| // }); | |||||
| // | |||||
| // // not found if arrive here | |||||
| // return s; | |||||
| } | } | ||||
| public UpdatePeopleInfo(people: PeopleModel): void{ | |||||
| this.loggedIn.User.Display = people.Display; | |||||
| this.loggedIn.User.First = people.First; | |||||
| this.loggedIn.User.Last = people.Last; | |||||
| this.saveSessionInfo(); | |||||
| } | |||||
| public LoginAvailable(v: string): Observable<boolean> { | public LoginAvailable(v: string): Observable<boolean> { | ||||
| return this.http.get<boolean>(this.getUrl('login-available/' + v)); | return this.http.get<boolean>(this.getUrl('login-available/' + v)); | ||||
| } | } | ||||
| public isAdmin(): boolean { | |||||
| return this.loggedIn.role === 'admin'; | |||||
| } | |||||
| public isBroker(): boolean { | |||||
| return this.loggedIn.role === 'broker'; | |||||
| } | |||||
| public isUser(): boolean { | |||||
| return this.loggedIn.login === true; | |||||
| } | |||||
| public isCurrentUser(id: string): boolean { | |||||
| return this.loggedIn.login === true && this.loggedIn.User !== undefined && this.loggedIn.User.Id === id; | |||||
| } | |||||
| } | } |
| import {EventEmitter, Injectable} from '@angular/core'; | |||||
| import {AppConfig} from '../app.config'; | |||||
| import {ApiV1LoginResponse} from '../models/api-v1-login-response'; | |||||
| import {PeopleModel} from '../models/people.model'; | |||||
| import {HttpClient} from '@angular/common/http'; | |||||
| import {Router} from '@angular/router'; | |||||
| import {NotificationService} from '@progress/kendo-angular-notification'; | |||||
| @Injectable() | |||||
| export class SessionService { | |||||
| public loggedIn = ApiV1LoginResponse.EmptyNew(); | |||||
| loginSuccess = new EventEmitter <ApiV1LoginResponse>(); | |||||
| constructor(private config: AppConfig, private http: HttpClient, private router: Router, private ns: NotificationService){ } | |||||
| public saveSessionInfo(): void { | |||||
| localStorage.setItem(this.config.storageKey, JSON.stringify(this.loggedIn)); | |||||
| localStorage.setItem('mid', this.loggedIn.machineId); | |||||
| } | |||||
| public isAdmin(): boolean { | |||||
| return this.loggedIn.role === 'admin'; | |||||
| } | |||||
| public isBroker(): boolean { | |||||
| return this.loggedIn.role === 'broker'; | |||||
| } | |||||
| public isUser(): boolean { | |||||
| return this.loggedIn.login === true; | |||||
| } | |||||
| public isCurrentUser(id: string): boolean { | |||||
| return this.loggedIn.login === true && this.loggedIn.User !== undefined && this.loggedIn.User.Id === id; | |||||
| } | |||||
| public UpdatePeopleInfo(people: PeopleModel): void{ | |||||
| this.loggedIn.User.Display = people.Display; | |||||
| this.loggedIn.User.First = people.First; | |||||
| this.loggedIn.User.Last = people.Last; | |||||
| this.saveSessionInfo(); | |||||
| } | |||||
| logout(): void { | |||||
| if ( !this.loggedIn.login ){ | |||||
| return; | |||||
| } | |||||
| this.loggedIn = ApiV1LoginResponse.EmptyNew(); | |||||
| localStorage.removeItem(this.config.storageKey); | |||||
| this.loginSuccess.emit(this.loggedIn); | |||||
| this.router.navigate(['/login']).then(r => { | |||||
| this.show(); | |||||
| } ); | |||||
| this.http.post(`${this.config.apiUrl}logout`, '').subscribe( | |||||
| resp => { | |||||
| console.log('successfully logout from server'); | |||||
| }, | |||||
| event => { | |||||
| console.log('error logout from server', event); | |||||
| } | |||||
| ); | |||||
| } | |||||
| public show(): void { | |||||
| this.ns.show({ | |||||
| content: 'Successfully logged out', | |||||
| cssClass: 'button-notification', | |||||
| animation: { type: 'slide', duration: 400 }, | |||||
| position: { horizontal: 'center', vertical: 'top' }, | |||||
| type: { style: 'info', icon: true }, | |||||
| hideAfter : 2000 | |||||
| }); | |||||
| } | |||||
| } |
| import {ApiV1LoginResponse} from '../models/api-v1-login-response'; | import {ApiV1LoginResponse} from '../models/api-v1-login-response'; | ||||
| import {Subscription} from 'rxjs'; | import {Subscription} from 'rxjs'; | ||||
| import {PeopleModel} from '../models/people.model'; | import {PeopleModel} from '../models/people.model'; | ||||
| import {SessionService} from '../service/session.service'; | |||||
| @Component({ | @Component({ | ||||
| public opened = false; | public opened = false; | ||||
| constructor(private menuService: MenuService, | constructor(private menuService: MenuService, | ||||
| private ss: SessionService, | |||||
| private authService: AuthService) { | private authService: AuthService) { | ||||
| } | } | ||||
| } | } | ||||
| public initAndSubLogin(): void{ | public initAndSubLogin(): void{ | ||||
| this.login = this.authService.loggedIn.login; | |||||
| this.LoggedInUser = this.authService.loggedIn.User; | |||||
| this.login = this.ss.loggedIn.login; | |||||
| this.LoggedInUser = this.ss.loggedIn.User; | |||||
| this.selectMenuShow(this.authService.loggedIn.role); | |||||
| this.selectMenuShow(this.ss.loggedIn.role); | |||||
| this.loginSub = this.authService.loginSuccess.subscribe( | |||||
| this.loginSub = this.ss.loginSuccess.subscribe( | |||||
| (rsp: ApiV1LoginResponse) => { | (rsp: ApiV1LoginResponse) => { | ||||
| this.login = rsp.login; | this.login = rsp.login; | ||||
| this.LoggedInUser = this.authService.loggedIn.User; | |||||
| this.LoggedInUser = this.ss.loggedIn.User; | |||||
| this.selectMenuShow(rsp.role); | this.selectMenuShow(rsp.role); | ||||
| } | } | ||||
| ); | ); | ||||
| } | } | ||||
| public loggedInUserAvatar(): string { | public loggedInUserAvatar(): string { | ||||
| return this.authService.getUrl('avatar/') + this.authService.loggedIn.User.Id; | |||||
| return this.authService.getUrl('avatar/') + this.ss.loggedIn.User.Id; | |||||
| } | } | ||||
| public profile(): void { | public profile(): void { |
| import { Injectable } from '@angular/core'; | import { Injectable } from '@angular/core'; | ||||
| import {Observable, Subscriber} from 'rxjs'; | |||||
| import {Observable, Subject, Subscriber} from 'rxjs'; | |||||
| import {AppConfig} from './app.config'; | |||||
| import {WsLoginEventModel} from './models/websocket/ws.login.event.model'; | |||||
| @Injectable() | @Injectable() | ||||
| export class WebSocketService { | |||||
| export class WebSocketService extends Subject<string>{ | |||||
| public ws: WebSocket; | public ws: WebSocket; | ||||
| private url: string; | |||||
| private observer: Subscriber<string>; | |||||
| public createObservableSocket(url: string): Observable<string> { | |||||
| this.url = url; | |||||
| const ret = new Observable<string> ( observer => { | |||||
| this.observer = observer; | |||||
| }); | |||||
| private readonly url: string; | |||||
| public LoginEvent: Subject<WsLoginEventModel>; | |||||
| constructor(private config: AppConfig) { | |||||
| super(); | |||||
| this.url = config.apiWsUrl; | |||||
| this.startWebsocket(); | this.startWebsocket(); | ||||
| return ret; | |||||
| this.LoginEvent = new Subject<WsLoginEventModel>(); | |||||
| } | } | ||||
| // tslint:disable-next-line:typedef | |||||
| public onMessage(event){ | |||||
| this.observer.next(event.data); | |||||
| private startWebsocket(): void { | |||||
| console.log('starting websocket now..', this.url); | |||||
| this.ws = new WebSocket(this.url); | |||||
| this.ws.onmessage = this.onMessage.bind(this); | |||||
| this.ws.onerror = this.onError.bind(this); | |||||
| this.ws.onclose = this.onClose.bind(this); | |||||
| } | } | ||||
| // tslint:disable-next-line:typedef | |||||
| public onError(event){ | |||||
| // public createObservableSocket(url: string): Observable<string> { | |||||
| // this.url = url; | |||||
| // const ret = new Observable<string> ( observer => { | |||||
| // this.observer = observer; | |||||
| // }); | |||||
| // this.startWebsocket(); | |||||
| // return ret; | |||||
| // } | |||||
| public onMessage(event): void{ | |||||
| super.next(event.data); | |||||
| try { | |||||
| const e = JSON.parse(event.data); | |||||
| if ( e.T === 'login' || e.T === 'logout' ){ | |||||
| this.LoginEvent.next(new WsLoginEventModel(e)); | |||||
| } | |||||
| }catch (e) { | |||||
| console.log(e); | |||||
| } | |||||
| } | |||||
| public onError(event): void{ | |||||
| console.log('on error ', event); | console.log('on error ', event); | ||||
| } | } | ||||
| // tslint:disable-next-line:typedef | |||||
| public onClose(event){ | |||||
| console.log('websocket closed.. reconnect in 1s ..'); | |||||
| public onClose(event): void{ | |||||
| console.log('websocket closed.. reconnect in 1s ..', event); | |||||
| setTimeout(() => { this.startWebsocket(); } , 1000); | setTimeout(() => { this.startWebsocket(); } , 1000); | ||||
| } | } | ||||
| // tslint:disable-next-line:typedef | |||||
| public startWebsocket() { | |||||
| console.log('starting websocket now..', this.url); | |||||
| this.ws = new WebSocket(this.url); | |||||
| this.ws.onmessage = this.onMessage.bind(this); | |||||
| this.ws.onerror = this.onError.bind(this); | |||||
| this.ws.onclose = this.onClose.bind(this); | |||||
| } | |||||
| public sendMessage(message: any): void { | public sendMessage(message: any): void { | ||||
| this.ws.send(message); | this.ws.send(message); |
| server="https://sc5016.biukop.com.au:8080/" | server="https://sc5016.biukop.com.au:8080/" | ||||
| version="0.9.1" | version="0.9.1" | ||||
| > | > | ||||
| eyJTZXJ2ZXIiOiJodHRwczpcL1wvYzUwMTYuYml1a29wLmNvbS5h | |||||
| dTo4MDgwXC9hcGlcL3YxXC8iLCJTb2NrZXQiOiJ3c3M6XC9cL2M1 | |||||
| MDE2LmJpdWtvcC5jb20uYXU6ODA4MFwvYXBpXC92MVwvd3MifQ== | |||||
| eyJTZXJ2ZXIiOiJodHRwczpcL1wvYzUwMTYuYml1a29wLmNvbS5hd | |||||
| To4MDgwXC9hcGlcL3YxXC8iLCJTb2NrZXQiOiJ3c3M6XC9cL2M1MD | |||||
| E2LmJpdWtvcC5jb20uYXU6ODA4MFwvYXBpXC92MVwvd3MiLCJTZXN | |||||
| zaW9uS2V5Ijoic2siLCJWZXJzaW9uIjoyMDIxfQ== | |||||
| </script> | </script> | ||||
| <app-root></app-root> | <app-root></app-root> | ||||
| <script id="config-svr2021" type="text/biukop-config" | |||||
| server="https://svr2021.lawipac.com:8080/" | |||||
| version="0.9.1" | |||||
| > | |||||
| eyJTZXJ2ZXIiOiAiaHR0cHM6Ly9zdnIyMDIxLmxhd2lwYWMuY29tO | |||||
| jgwODAvYXBpL3YxLyIsICJTb2NrZXQiOiAid3NzOi8vc3ZyMjAyMS | |||||
| 5sYXdpcGFjLmNvbTo4MDgwL2FwaS92MS93cyJ9 | |||||
| </script> | |||||
| </body> | </body> | ||||
| </html> | </html> |