diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts
index 00c23b9e..d914c927 100644
--- a/frontend/src/app/app.component.ts
+++ b/frontend/src/app/app.component.ts
@@ -30,7 +30,7 @@ export class AppComponent implements OnInit {
modifyHeader(event) {
if (event instanceof NavigationEnd) {
- if (event.url?.startsWith('/auth')) {
+ if (event.url?.startsWith('/auth') || event.url?.startsWith('/desktop')) {
this.showHeader = false;
} else {
// console.log("NU")
diff --git a/frontend/src/app/pages/desktop-callback/desktop-callback.component.html b/frontend/src/app/pages/desktop-callback/desktop-callback.component.html
index 2b98cb57..b6e49612 100644
--- a/frontend/src/app/pages/desktop-callback/desktop-callback.component.html
+++ b/frontend/src/app/pages/desktop-callback/desktop-callback.component.html
@@ -1 +1,5 @@
-
desktop-callback works!
+
diff --git a/frontend/src/app/pages/desktop-callback/desktop-callback.component.ts b/frontend/src/app/pages/desktop-callback/desktop-callback.component.ts
index 76501e12..91967ca1 100644
--- a/frontend/src/app/pages/desktop-callback/desktop-callback.component.ts
+++ b/frontend/src/app/pages/desktop-callback/desktop-callback.component.ts
@@ -1,4 +1,5 @@
import { Component, OnInit } from '@angular/core';
+import {ActivatedRoute} from '@angular/router';
@Component({
selector: 'app-desktop-callback',
@@ -8,14 +9,14 @@ import { Component, OnInit } from '@angular/core';
export class DesktopCallbackComponent implements OnInit {
//This component is used to redirect the user to the desktop app after they have authenticated with a source
- constructor() { }
+ constructor(private activatedRoute : ActivatedRoute) { }
ngOnInit(): void {
- wails.Event.Emit({
- name: "wails:fasten-lighthouse:success",
- data:
-
- )
+ this.activatedRoute.queryParams.subscribe(values => {
+ wails.Events.Emit({
+ name: "wails:fasten-lighthouse:response",
+ data: values,
+ })
+ })
}
-
}
diff --git a/frontend/src/app/pages/medical-sources/medical-sources.component.ts b/frontend/src/app/pages/medical-sources/medical-sources.component.ts
index a9534f90..f5850894 100644
--- a/frontend/src/app/pages/medical-sources/medical-sources.component.ts
+++ b/frontend/src/app/pages/medical-sources/medical-sources.component.ts
@@ -5,7 +5,7 @@ import {LighthouseSourceMetadata} from '../../models/lighthouse/lighthouse-sourc
import {Source} from '../../models/fasten/source';
import {MetadataSource} from '../../models/fasten/metadata-source';
import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
-import {ActivatedRoute} from '@angular/router';
+import {ActivatedRoute, Router, UrlSerializer} from '@angular/router';
import {environment} from '../../../environments/environment';
import {BehaviorSubject, forkJoin, Observable, of, Subject} from 'rxjs';
import {
@@ -17,7 +17,7 @@ import {debounceTime, distinctUntilChanged, pairwise, startWith} from 'rxjs/oper
import {MedicalSourcesFilter, MedicalSourcesFilterService} from '../../services/medical-sources-filter.service';
import {FormControl, FormGroup} from '@angular/forms';
import * as _ from 'lodash';
-// If you dont import this angular will import the wrong "Location"
+import {Location} from '@angular/common';
export const sourceConnectWindowTimeout = 24*5000 //wait 2 minutes (5 * 24 = 120)
@@ -79,6 +79,9 @@ export class MedicalSourcesComponent implements OnInit {
private activatedRoute: ActivatedRoute,
private filterService: MedicalSourcesFilterService,
private modalService: NgbModal,
+ private router: Router,
+ private urlSerializer: UrlSerializer,
+ private location: Location,
) {
this.filterService.filterChanges.subscribe((filterInfo) => {
@@ -284,8 +287,31 @@ export class MedicalSourcesComponent implements OnInit {
let authorizationUrl = await this.lighthouseApi.generateSourceAuthorizeUrl(sourceType, sourceMetadata)
console.log('authorize url:', authorizationUrl.toString());
- // redirect to lighthouse with uri's
- this.lighthouseApi.redirectWithOriginAndDestination(authorizationUrl.toString(), sourceType, sourceMetadata.redirect_uri)
+ // redirect to lighthouse with uri's (or open a new window in desktop mode)
+ this.lighthouseApi.redirectWithOriginAndDestination(authorizationUrl.toString(), sourceType, sourceMetadata.redirect_uri).subscribe((codeData) => {
+ //Note: this code will only run in Desktop mode (with popups)
+ //in non-desktop environments, the user is redirected in the same window, and this code is never executed.
+
+ //always close the modal
+ this.modalService.dismissAll()
+
+ if(!codeData){
+ //if we redirected completely, no callback data will be present.
+ return
+ }
+
+ //User was shown a popup, which was closed, and data was returned using events
+ //redirect to callback page with code
+
+ let urlTree = this.router.createUrlTree(
+ ['/sources/callback/' + sourceType],
+ { queryParams: codeData, }
+ );
+
+ let absUrl = this.location.prepareExternalUrl(this.urlSerializer.serialize(urlTree))
+ console.log(absUrl);
+ window.location.replace(absUrl)
+ })
});
}
diff --git a/frontend/src/app/services/lighthouse.service.ts b/frontend/src/app/services/lighthouse.service.ts
index d4c90a72..3565a546 100644
--- a/frontend/src/app/services/lighthouse.service.ts
+++ b/frontend/src/app/services/lighthouse.service.ts
@@ -1,6 +1,6 @@
import {Inject, Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
-import {Observable, of, throwError, fromEvent } from 'rxjs';
+import {Observable, of, throwError, bindCallback} from 'rxjs';
import {environment} from '../../environments/environment';
import {concatMap, delay, retryWhen, timeout, first, map, filter, catchError, tap} from 'rxjs/operators';
import {ResponseWrapper} from '../models/response-wrapper';
@@ -146,7 +146,7 @@ export class LighthouseService {
* dest_url - https://patient360la.anthem.com/.../connect/authorize?redirect_uri=https://lighthouse.fastenhealth.com/callback/anthem
* redirect_url - lighthouse.fastenhealth.com/sandbox/redirect/anthem?origin_url=...&dest_url=...
*/
- redirectWithOriginAndDestination(destUrl: string, sourceType: string, callbackUri: string): void {
+ redirectWithOriginAndDestination(destUrl: string, sourceType: string, callbackUri: string): Observable {
const originUrlParts = new URL(window.location.href)
if(environment.environment_desktop){
@@ -171,23 +171,15 @@ export class LighthouseService {
if(environment.environment_desktop && environment.popup_source_auth){
//@ts-ignore
- OpenExternalLink(redirectUrlParts.toString(), environment.environment_desktop)
- // let openedWindow = window.runtime.BrowserOpenURL(redirectUrlParts.toString());
+ OpenExternalLink(redirectUrlParts.toString(), environment.environment_desktop, sourceType)
- wails.Event.Once("wails:fasten-lighthouse:success", (code: string) => {
- console.log("GOT CODE FROM DESKTOP", code)
-
- })
-
- this.waitForDesktopCodeOrTimeout(null, sourceType).subscribe(async (codeData) => {
- //TODO: redirect to the callback url with the code.
- console.log("DONE WAITING FOR CODE")
- })
+ return this.waitForDesktopCodeOrTimeout(sourceType)
//now wait for response from the opened window
} else {
//redirect to the url in the same window
window.location.href = redirectUrlParts.toString();
+ return of(null) //should never happen
}
}
@@ -260,26 +252,32 @@ export class LighthouseService {
return parts.join(separator);
}
- private waitForDesktopCodeOrTimeout(openedWindow: Window, sourceType: string): Observable {
- console.log(`waiting for postMessage notification from ${sourceType} window`)
+ private waitForDesktopCodeOrTimeout(sourceType: string): Observable {
+ console.log(`waiting for wails Event notification from window`)
+
+ if(typeof wails == "undefined"){
+ return throwError("wails is not defined, this is likely because you're running in a browser.")
+ }
+
+ let fromWailsEvent = bindCallback(wails.Events.Once)
//new code to listen to post message
- return fromEvent(window, 'message')
+ return fromWailsEvent('wails:fasten-lighthouse:response')
.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),
+ filter((eventPayload: any ) => eventPayload.sender == sourceType),
//after filtering, we should only have one event to handle.
first(),
map((event) => {
- console.log(`received postMessage notification from ${sourceType} window & sending acknowledgment`, event)
+ console.log(`received wails event notification from ${sourceType} window & sending acknowledgment`, event)
// @ts-ignore
- event.source.postMessage(JSON.stringify({close:true}), event.origin);
+ return event.data
}),
catchError((err) => {
console.warn(`timed out waiting for notification from ${sourceType} (${sourceConnectDesktopTimeout/1000}s), closing window`)
- openedWindow.self.close()
+ wails.Application.GetWindowByName(sourceType).Window.Close()
return throwError(err)
})
)
diff --git a/frontend/src/environments/environment.desktop_prod.ts b/frontend/src/environments/environment.desktop_prod.ts
index 2c27c05e..3a16b67c 100644
--- a/frontend/src/environments/environment.desktop_prod.ts
+++ b/frontend/src/environments/environment.desktop_prod.ts
@@ -3,7 +3,7 @@ export const environment = {
environment_cloud: false,
environment_desktop: true,
environment_name: "desktop_prod",
- popup_source_auth: false,
+ popup_source_auth: true,
lighthouse_api_endpoint_base: 'https://lighthouse.fastenhealth.com/v1',
diff --git a/frontend/src/lib/utils/external_link.ts b/frontend/src/lib/utils/external_link.ts
index f1a23198..168ac708 100644
--- a/frontend/src/lib/utils/external_link.ts
+++ b/frontend/src/lib/utils/external_link.ts
@@ -1,4 +1,4 @@
-export function OpenExternalLink(url: string, desktopMode: boolean){
+export function OpenExternalLink(url: string, desktopMode: boolean, windowId?: string){
//check if url starts with https, and if not, prepend it (external links are never relative)
if(!url.startsWith("https://") && !url.startsWith("http://")){
url = "https://" + url;
@@ -6,7 +6,7 @@ export function OpenExternalLink(url: string, desktopMode: boolean){
//check if wails exists and is defined
if(typeof wails !== "undefined" && desktopMode){
- wails.CallByName("pkg.AppService.BrowserOpenURL", url)
+ wails.CallByName("pkg.AppService.BrowserOpenURL", url, windowId || 'external')
} else{
window.open(url, "_blank");
}
diff --git a/frontend/src/polyfills.ts b/frontend/src/polyfills.ts
index 054eaa50..28528659 100644
--- a/frontend/src/polyfills.ts
+++ b/frontend/src/polyfills.ts
@@ -66,7 +66,10 @@ declare global {
// let wails: any
let wails: {
- Event: {
+ Application: {
+ GetWindowByName: (sourceType: string) => any
+ }
+ Events: {
Emit: (event: any) => void
Once: (eventName, callback) => void
On: (eventName, callback) => void