From 9be431c2a649ae190ad93e96c1bf21a494529d86 Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Tue, 5 Sep 2023 07:30:10 -0700 Subject: [PATCH] adding support for popup-auth (disabled by default in all envs). --- .../src/app/services/lighthouse.service.ts | 52 +++++++++++++++++-- .../environments/environment.cloud_sandbox.ts | 2 + .../environments/environment.desktop_prod.ts | 1 + .../environment.desktop_sandbox.ts | 2 +- frontend/src/environments/environment.prod.ts | 1 + .../src/environments/environment.sandbox.ts | 1 + frontend/src/environments/environment.ts | 2 + 7 files changed, 56 insertions(+), 5 deletions(-) diff --git a/frontend/src/app/services/lighthouse.service.ts b/frontend/src/app/services/lighthouse.service.ts index 4fe6158e..da260d6f 100644 --- a/frontend/src/app/services/lighthouse.service.ts +++ b/frontend/src/app/services/lighthouse.service.ts @@ -1,8 +1,8 @@ import {Inject, Injectable} from '@angular/core'; import {HttpClient} from '@angular/common/http'; -import {Observable} from 'rxjs'; +import {Observable, of, throwError, fromEvent } from 'rxjs'; import {environment} from '../../environments/environment'; -import {map, tap} from 'rxjs/operators'; +import {concatMap, delay, retryWhen, timeout, first, map, filter, catchError, tap} from 'rxjs/operators'; import {ResponseWrapper} from '../models/response-wrapper'; import {LighthouseSourceMetadata} from '../models/lighthouse/lighthouse-source-metadata'; import * as Oauth from '@panva/oauth4webapi'; @@ -13,6 +13,8 @@ import {LighthouseSourceSearch} from '../models/lighthouse/lighthouse-source-sea import {HTTP_CLIENT_TOKEN} from "../dependency-injection"; import {MedicalSourcesFilter} from './medical-sources-filter.service'; +export const sourceConnectDesktopTimeout = 24*5000 //wait 2 minutes (5 * 24 = 120) + @Injectable({ providedIn: 'root' }) @@ -163,8 +165,23 @@ export class LighthouseService { redirectUrlParts.search = redirectParams.toString() console.log(redirectUrlParts.toString()); - // Simulate a mouse click: - window.location.href = redirectUrlParts.toString(); + + //if we're in desktop mode, we can open a new window, rather than redirecting the current window (which is an app frame) + if(environment.environment_desktop && environment.popup_source_auth){ + //@ts-ignore + let openedWindow = window.runtime.BrowserOpenURL(redirectUrlParts.toString()); + + this.waitForDesktopCodeOrTimeout(openedWindow, sourceType).subscribe(async (codeData) => { + //TODO: redirect to the callback url with the code. + console.log("DONE WAITING FOR CODE") + }) + + //now wait for response from the opened window + } else { + //redirect to the url in the same window + window.location.href = redirectUrlParts.toString(); + } + } async swapOauthToken(sourceType: string, sourceMetadata: LighthouseSourceMetadata, expectedSourceStateInfo: SourceState, code: string): Promise{ @@ -234,5 +251,32 @@ export class LighthouseService { }) return parts.join(separator); } + + private waitForDesktopCodeOrTimeout(openedWindow: Window, sourceType: string): Observable { + console.log(`waiting for postMessage notification from ${sourceType} window`) + + //new code to listen to post message + return fromEvent(window, 'message') + .pipe( + //throw an error if we wait more than 2 minutes (this will close the window) + timeout(sourceConnectDesktopTimeout), + //make sure we're only listening to events from the "opened" window. + filter((event: MessageEvent) => event.source == openedWindow), + //after filtering, we should only have one event to handle. + first(), + map((event) => { + console.log(`received postMessage notification from ${sourceType} window & sending acknowledgment`, event) + // @ts-ignore + event.source.postMessage(JSON.stringify({close:true}), event.origin); + }), + catchError((err) => { + console.warn(`timed out waiting for notification from ${sourceType} (${sourceConnectDesktopTimeout/1000}s), closing window`) + openedWindow.self.close() + return throwError(err) + }) + ) + } + + } diff --git a/frontend/src/environments/environment.cloud_sandbox.ts b/frontend/src/environments/environment.cloud_sandbox.ts index fd9b648e..49ed974f 100644 --- a/frontend/src/environments/environment.cloud_sandbox.ts +++ b/frontend/src/environments/environment.cloud_sandbox.ts @@ -3,6 +3,8 @@ export const environment = { environment_cloud: true, environment_desktop: false, environment_name: "sandbox", + popup_source_auth: false, + lighthouse_api_endpoint_base: 'https://lighthouse.fastenhealth.com/sandbox', //used to specify the couchdb server that we're going to use (can be relative or absolute). Must not have trailing slash diff --git a/frontend/src/environments/environment.desktop_prod.ts b/frontend/src/environments/environment.desktop_prod.ts index 76f8ae37..2c27c05e 100644 --- a/frontend/src/environments/environment.desktop_prod.ts +++ b/frontend/src/environments/environment.desktop_prod.ts @@ -3,6 +3,7 @@ export const environment = { environment_cloud: false, environment_desktop: true, environment_name: "desktop_prod", + popup_source_auth: false, lighthouse_api_endpoint_base: 'https://lighthouse.fastenhealth.com/v1', diff --git a/frontend/src/environments/environment.desktop_sandbox.ts b/frontend/src/environments/environment.desktop_sandbox.ts index 3923246f..fd530b6c 100644 --- a/frontend/src/environments/environment.desktop_sandbox.ts +++ b/frontend/src/environments/environment.desktop_sandbox.ts @@ -3,10 +3,10 @@ export const environment = { environment_cloud: false, environment_desktop: true, environment_name: "desktop_sandbox", + popup_source_auth: false, lighthouse_api_endpoint_base: 'https://lighthouse.fastenhealth.com/sandbox', - //used to specify the api server that we're going to use (can be relative or absolute). Must not have trailing slash fasten_api_endpoint_base: '/api', }; diff --git a/frontend/src/environments/environment.prod.ts b/frontend/src/environments/environment.prod.ts index 8a1c0555..ded622c6 100644 --- a/frontend/src/environments/environment.prod.ts +++ b/frontend/src/environments/environment.prod.ts @@ -3,6 +3,7 @@ export const environment = { environment_cloud: false, environment_desktop: false, environment_name: "prod", + popup_source_auth: false, lighthouse_api_endpoint_base: 'https://lighthouse.fastenhealth.com/v1', diff --git a/frontend/src/environments/environment.sandbox.ts b/frontend/src/environments/environment.sandbox.ts index 92d7111b..e0965aa0 100644 --- a/frontend/src/environments/environment.sandbox.ts +++ b/frontend/src/environments/environment.sandbox.ts @@ -7,6 +7,7 @@ export const environment = { environment_cloud: false, environment_desktop: false, environment_name: "sandbox", + popup_source_auth: false, lighthouse_api_endpoint_base: 'https://lighthouse.fastenhealth.com/sandbox', diff --git a/frontend/src/environments/environment.ts b/frontend/src/environments/environment.ts index 5cd09947..b39ce921 100644 --- a/frontend/src/environments/environment.ts +++ b/frontend/src/environments/environment.ts @@ -11,6 +11,8 @@ export const environment = { // is the application running in a desktop environment (Wails). If so we will use hash based routing environment_desktop: false, + //when environment_desktop=true, we can use the postMessage api to communicate with the desktop app (otherwise use redirects) + popup_source_auth: false, // the environment name, `sandbox`, `prod`, `beta` environment_name: "sandbox",