diff --git a/src/components/confirmDialog/confirmDialog.component.ts b/src/components/confirmDialog/confirmDialog.component.ts index c27500612afb8eec97047344c7662343cf569c75..b1782761449051a601e8fac5046241e92c572433 100644 --- a/src/components/confirmDialog/confirmDialog.component.ts +++ b/src/components/confirmDialog/confirmDialog.component.ts @@ -16,9 +16,17 @@ export class ConfirmDialogComponent { @Input() public message: string = 'Would you like to proceed?' + @Input() + public okBtnText: string = `OK` + + @Input() + public cancelBtnText: string = `Cancel` + constructor(@Inject(MAT_DIALOG_DATA) data: any) { - const { title = null, message = null} = data || {} - if (title) { this.title = title } - if (message) { this.message = message } + const { title = null, message = null, okBtnText, cancelBtnText} = data || {} + if (title) this.title = title + if (message) this.message = message + if (okBtnText) this.okBtnText = okBtnText + if (cancelBtnText) this.cancelBtnText = cancelBtnText } } diff --git a/src/components/confirmDialog/confirmDialog.template.html b/src/components/confirmDialog/confirmDialog.template.html index eb0c76fffdca11eda3487eb259b2be3cbbaa032e..df52270e96592f165d5497b5ecb610cfc92bcbcf 100644 --- a/src/components/confirmDialog/confirmDialog.template.html +++ b/src/components/confirmDialog/confirmDialog.template.html @@ -11,6 +11,6 @@ <mat-divider></mat-divider> <mat-dialog-actions class="justify-content-start flex-row-reverse"> - <button [mat-dialog-close]="true" mat-raised-button color="primary">OK</button> - <button [mat-dialog-close]="false" mat-button>Cancel</button> -</mat-dialog-actions> \ No newline at end of file + <button [mat-dialog-close]="true" mat-raised-button color="primary">{{ okBtnText }}</button> + <button [mat-dialog-close]="false" mat-button>{{ cancelBtnText }}</button> +</mat-dialog-actions> diff --git a/src/main.module.ts b/src/main.module.ts index 06c2a92305d7213bf957698a7c9710827caa905e..d559316fd2faf5641f35e91357f7bb96653ecd7e 100644 --- a/src/main.module.ts +++ b/src/main.module.ts @@ -57,8 +57,7 @@ import { DatasetPreviewGlue, datasetPreviewMetaReducer, IDatasetPreviewGlue, Glu import { viewerStateHelperReducer, viewerStateFleshOutDetail, viewerStateMetaReducers, ViewerStateHelperEffect } from './services/state/viewerState.store.helper'; import { TOS_OBS_INJECTION_TOKEN } from './ui/kgtos/kgtos.component'; import { UiEffects } from './services/state/uiState/ui.effects'; -import { OVERWRITE_SHOW_DATASET_DIALOG_TOKEN, TOverwriteShowDatasetDialog } from './util/interfaces'; -import { uiActionShowDatasetWtihId } from './services/state/uiState/actions'; +import { MesssagingModule } from './messaging/module'; export function debug(reducer: ActionReducer<any>): ActionReducer<any> { return function(state, action) { @@ -85,6 +84,7 @@ export function debug(reducer: ActionReducer<any>): ActionReducer<any> { PluginModule, LoggingModule, ShareModule, + MesssagingModule, SpotLightModule, diff --git a/src/messaging/module.ts b/src/messaging/module.ts new file mode 100644 index 0000000000000000000000000000000000000000..1f78c517c4df02657c9760cfa11da278bf429baa --- /dev/null +++ b/src/messaging/module.ts @@ -0,0 +1,98 @@ +import { NgModule } from "@angular/core"; +import { MatDialog } from "@angular/material/dialog"; +import { ComponentsModule } from "src/components"; +import { ConfirmDialogComponent } from "src/components/confirmDialog/confirmDialog.component"; +import { AngularMaterialModule } from "src/ui/sharedModules/angularMaterial.module"; + +const IAV_POSTMESSAGE_NAMESPACE = `ebrains:iav:` + +@NgModule({ + imports: [ + AngularMaterialModule, + ComponentsModule, + ] +}) + +export class MesssagingModule{ + + private whiteListedOrigins = new Set() + private pendingRequests: Map<string, Promise<boolean>> = new Map() + + constructor( + private dialog: MatDialog + ){ + + window.addEventListener('message', async ({ data, origin, source }) => { + const { method, id } = data + const src = source as Window + if (!method) return + if (method.indexOf(IAV_POSTMESSAGE_NAMESPACE) !== 0) return + const strippedMethod = method.replace(IAV_POSTMESSAGE_NAMESPACE, '') + switch (strippedMethod) { + case 'ping': { + window.opener.postMessage({ + id, + result: 'pong', + jsonrpc: '2.0' + }, origin) + + break + } + case 'dummyMethod': { + try { + const result = await this.dummyMethod({ data, origin }) + src.postMessage({ + id, + result + }, origin) + } catch (e) { + + src.postMessage({ + id, + error: e.code + ? e + : { code: 500, message: e.toString() } + }, origin) + } + + break; + } + default: { + src.postMessage({ + id, + error: { + code: 404, + message: 'Method not found' + } + }, origin) + } + } + }) + } + + async checkOrigin({ origin }){ + if (this.whiteListedOrigins.has(origin)) return true + if (this.pendingRequests.has(origin)) return this.pendingRequests.get(origin) + const responsePromise = this.dialog.open( + ConfirmDialogComponent, + { + data: { + title: `Cross tab messaging`, + message: `${origin} would like to send data to interactive atlas viewer`, + okBtnText: `Allow` + } + } + ).afterClosed().toPromise() + this.pendingRequests.set(origin, responsePromise) + const response = await responsePromise + this.pendingRequests.delete(origin) + if (response) this.whiteListedOrigins.add(origin) + return response + } + + async dummyMethod({ data, origin }){ + const allow = await this.checkOrigin({ origin }) + if (!allow) throw ({ code: 403, message: 'User declined' }) + return 'OK' + } +} \ No newline at end of file