From 9e23e28ca5bf3f10ad58818af84769b7876bab86 Mon Sep 17 00:00:00 2001 From: panaaj <38519157+panaaj@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:10:30 +1030 Subject: [PATCH] Watch for SK server login changes --- src/app/app.component.ts | 48 +++++++++++++-------- src/app/app.info.ts | 47 +++++++++++++++++--- src/app/modules/skstream/skstream.facade.ts | 2 +- 3 files changed, 71 insertions(+), 26 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index b73366dc..0f44878c 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -207,6 +207,14 @@ export class AppComponent { // ********************* SUBSCRIPTIONS ***************** // ** SIGNAL K STREAM ** + this.obsList.push( + this.app.skLogin$.subscribe({ + next: (token: string) => { + this.app.debug('SK Login Event', token); + this.handleSKLoginEvent(); + } + }) + ); this.obsList.push( this.stream .delta$() @@ -508,6 +516,25 @@ export class AppComponent { } // ************************************************ + handleSKLoginEvent() { + this.signalk.getLoginStatus().subscribe((r) => { + this.app.data.loginRequired = r.authenticationRequired ?? false; + this.app.data.loggedIn = r.status === 'loggedIn' ? true : false; + // ** Request using cached auth token and display badge + this.signalk.get('/plugins/freeboard-sk').subscribe( + () => { + this.app.debug('User Authenticated'); + this.app.data.loggedIn = true; + }, + (err: HttpErrorResponse) => { + if (err.status === 401) { + this.app.debug('User NOT Authenticated'); + this.app.data.loggedIn = false; + } + } + ); + }); + } // ** establish connection to server private connectSignalKServer() { @@ -518,24 +545,9 @@ export class AppComponent { .connect(this.app.hostName, this.app.hostPort, this.app.hostSSL) .subscribe( () => { - this.signalk.authToken = this.app.getToken(); - - this.signalk.getLoginStatus().subscribe((r) => { - this.app.data.loginRequired = r.authenticationRequired ?? false; - this.app.data.loggedIn = r.status === 'loggedIn' ? true : false; - // ** Request using cached auth token and display badge - this.signalk.get('/plugins/freeboard-sk').subscribe( - () => { - this.app.debug('User Authenticated'); - this.app.data.loggedIn = true; - }, - (err: HttpErrorResponse) => { - if (err.status === 401) { - this.app.data.loggedIn = false; - } - } - ); - }); + this.signalk.authToken = this.app.getFBToken(); + this.app.watchSKLogin(); + this.handleSKLoginEvent(); this.app.loadSettingsfromServer().subscribe((r) => { const msg = r diff --git a/src/app/app.info.ts b/src/app/app.info.ts index 4c4b5667..8a44ca69 100644 --- a/src/app/app.info.ts +++ b/src/app/app.info.ts @@ -103,6 +103,10 @@ export class AppInfo extends Info { : false; } + private skLoginSource: Subject; + public skLogin$: Observable; + private watchingSKLogin: number; + constructor( public signalk: SignalKClient, private stream: SKStreamProvider, @@ -113,6 +117,9 @@ export class AppInfo extends Info { this.db = new AppDB(); + this.skLoginSource = new Subject(); + this.skLogin$ = this.skLoginSource.asObservable(); + // process searchParams if (window.location.search) { const p = window.location.search.slice(1).split('&'); @@ -160,7 +167,7 @@ export class AppInfo extends Info { this.name = 'Freeboard-SK'; this.shortName = 'Freeboard'; this.description = `Signal K Chart Plotter.`; - this.version = '2.12.1'; + this.version = '2.12.2'; this.url = 'https://github.com/signalk/freeboard-sk'; this.logo = './assets/img/app_logo.png'; @@ -401,17 +408,43 @@ export class AppInfo extends Info { } } - // return auth token for session - getToken(): string { + // Start watching for change in skLoginInfo cookie + watchSKLogin() { + if (this.watchingSKLogin) return; + this.watchingSKLogin = window.setInterval( + (() => { + let lastCookie = this.getCookie(document.cookie, 'skLoginInfo'); + return () => { + const currentCookie = this.getCookie(document.cookie, 'skLoginInfo'); + if (currentCookie !== lastCookie) { + lastCookie = currentCookie; + this.skLoginSource.next(currentCookie); + } + }; + })(), + 2000 + ); + } + + // return FB auth token for session + getFBToken(): string { + return this.getCookie(document.cookie, 'sktoken'); + } + + // return the requested cookie + private getCookie(c: string, sel: 'sktoken' | 'skLoginInfo') { + if (!c) { + return undefined; + } const tk = new Map(); - document.cookie.split(';').map((i) => { + c.split(';').map((i) => { const c = i.split('='); tk.set(c[0], c[1]); }); - if (tk.has('sktoken')) { - return tk.get('sktoken'); + if (tk.has(sel)) { + return tk.get(sel); } else { - return null; + return undefined; } } diff --git a/src/app/modules/skstream/skstream.facade.ts b/src/app/modules/skstream/skstream.facade.ts index 0ada3938..2d8af020 100644 --- a/src/app/modules/skstream/skstream.facade.ts +++ b/src/app/modules/skstream/skstream.facade.ts @@ -61,7 +61,7 @@ export class SKStreamFacade { this.post({ cmd: 'auth', options: { - token: this.app.getToken() + token: this.app.getFBToken() } }); this.onConnect.next(msg);