From 35fe78e49e83e6eb346dba7e092b984ad9327009 Mon Sep 17 00:00:00 2001 From: Baptiste Grob <60621355+baptiste-grob@users.noreply.github.com> Date: Thu, 3 Sep 2020 23:33:11 +0200 Subject: [PATCH] fix: desktop interop --- app/assets/javascripts/services/bridge.ts | 22 ++++++ .../javascripts/services/desktopManager.ts | 78 ++++++------------- .../javascripts/ui_models/application.ts | 2 +- .../ui_models/application_group.ts | 3 +- 4 files changed, 47 insertions(+), 58 deletions(-) diff --git a/app/assets/javascripts/services/bridge.ts b/app/assets/javascripts/services/bridge.ts index 08fa09076..ec19e963f 100644 --- a/app/assets/javascripts/services/bridge.ts +++ b/app/assets/javascripts/services/bridge.ts @@ -1,13 +1,24 @@ +import { PurePayload, Environment } from "snjs"; + /** Platform-specific (i-e Electron/browser) behavior is handled by a Bridge object. */ export interface Bridge { + environment: Environment, + getKeychainValue(): Promise; setKeychainValue(value: any): Promise; clearKeychainValue(): Promise; + + extensionsServerHost?: string; + syncComponents(payloads: PurePayload[]): void; + onMajorDataChange(): void; + onInitialDataLoad(): void; + onSearch(text?: string): void; } const KEYCHAIN_STORAGE_KEY = 'keychain'; export class BrowserBridge implements Bridge { + environment = Environment.Web; async getKeychainValue(): Promise { const value = localStorage.getItem(KEYCHAIN_STORAGE_KEY); @@ -23,4 +34,15 @@ export class BrowserBridge implements Bridge { async clearKeychainValue(): Promise { localStorage.removeItem(KEYCHAIN_STORAGE_KEY); } + + /** No-ops */ + + syncComponents() { + } + onMajorDataChange() { + } + onInitialDataLoad() { + } + onSearch() { + } } diff --git a/app/assets/javascripts/services/desktopManager.ts b/app/assets/javascripts/services/desktopManager.ts index ab63ee6f2..c3894d843 100644 --- a/app/assets/javascripts/services/desktopManager.ts +++ b/app/assets/javascripts/services/desktopManager.ts @@ -1,9 +1,10 @@ -import { SNComponent, PurePayload, ComponentMutator, AppDataField } from 'snjs'; +import { SNComponent, PurePayload, ComponentMutator, AppDataField, ContentType } from 'snjs'; /* eslint-disable camelcase */ import { WebApplication } from '@/ui_models/application'; // An interface used by the Desktop app to interact with SN import { isDesktopApplication } from '@/utils'; import { EncryptionIntent, ApplicationService, ApplicationEvent, removeFromArray } from 'snjs'; +import { Bridge } from './bridge'; type UpdateObserverCallback = (component: SNComponent) => void type ComponentActivationCallback = (payload: PurePayload) => void @@ -23,18 +24,14 @@ export class DesktopManager extends ApplicationService { isDesktop = isDesktopApplication(); dataLoaded = false - dataLoadHandler?: () => void - majorDataChangeHandler?: () => void - extServerHost?: string - installationSyncHandler?: (payloads: PurePayload[]) => void - installComponentHandler?: (payload: PurePayload) => void lastSearchedText?: string - searchHandler?: (text?: string) => void + private removeComponentObserver?: () => void; constructor( $rootScope: ng.IRootScopeService, $timeout: ng.ITimeoutService, - application: WebApplication + application: WebApplication, + private bridge: Bridge, ) { super(application); this.$rootScope = $rootScope; @@ -48,6 +45,8 @@ export class DesktopManager extends ApplicationService { deinit() { this.componentActivationObservers.length = 0; this.updateObservers.length = 0; + this.removeComponentObserver?.(); + this.removeComponentObserver = undefined; super.deinit(); } @@ -55,33 +54,29 @@ export class DesktopManager extends ApplicationService { super.onAppEvent(eventName); if (eventName === ApplicationEvent.LocalDataLoaded) { this.dataLoaded = true; - if (this.dataLoadHandler) { - this.dataLoadHandler(); - } + this.bridge.onInitialDataLoad(); } else if (eventName === ApplicationEvent.MajorDataChange) { - if (this.majorDataChangeHandler) { - this.majorDataChangeHandler(); - } + this.bridge.onMajorDataChange(); } } saveBackup() { - this.majorDataChangeHandler && this.majorDataChangeHandler(); + this.bridge.onMajorDataChange(); } getExtServerHost() { console.assert( - this.extServerHost, + this.bridge.extensionsServerHost, 'extServerHost is null' ); - return this.extServerHost; + return this.bridge.extensionsServerHost; } /** * Sending a component in its raw state is really slow for the desktop app * Keys are not passed into ItemParams, so the result is not encrypted */ - async convertComponentForTransmission(component: SNComponent) { + convertComponentForTransmission(component: SNComponent) { return this.application!.protocolService!.payloadByEncryptingPayload( component.payloadRepresentation(), EncryptionIntent.FileDecrypted @@ -96,16 +91,14 @@ export class DesktopManager extends ApplicationService { Promise.all(components.map((component) => { return this.convertComponentForTransmission(component); })).then((payloads) => { - this.installationSyncHandler!(payloads); + this.bridge.syncComponents( + payloads.filter(payload => + !payload.errorDecrypting && !payload.waitingForKey + ) + ); }); } - async installComponent(component: SNComponent) { - this.installComponentHandler!( - await this.convertComponentForTransmission(component) - ); - } - registerUpdateObserver(callback: UpdateObserverCallback) { const observer = { callback: callback @@ -121,7 +114,7 @@ export class DesktopManager extends ApplicationService { return; } this.lastSearchedText = text; - this.searchHandler && this.searchHandler(text); + this.bridge.onSearch(text); } redoSearch() { @@ -130,11 +123,6 @@ export class DesktopManager extends ApplicationService { } } - // Pass null to cancel search - desktop_setSearchHandler(handler: (text?: string) => void) { - this.searchHandler = handler; - } - desktop_windowGainedFocus() { this.$rootScope.$broadcast('window-gained-focus'); } @@ -199,38 +187,16 @@ export class DesktopManager extends ApplicationService { }); } - /* Used to resolve 'sn://' */ - desktop_setExtServerHost(host: string) { - this.extServerHost = host; + onExtensionsReady() { this.webApplication.getAppState().desktopExtensionsReady(); } - desktop_setComponentInstallationSyncHandler(handler: (payloads: PurePayload[]) => void) { - this.installationSyncHandler = handler; - } - - desktop_setInstallComponentHandler(handler: (payload: PurePayload) => void) { - this.installComponentHandler = handler; - } - - desktop_setInitialDataLoadHandler(handler: () => void) { - this.dataLoadHandler = handler; - if (this.dataLoaded) { - this.dataLoadHandler(); - } - } - - async desktop_requestBackupFile(callback: (data: any) => void) { - const data = await this.application!.createBackupFile( + desktop_requestBackupFile() { + return this.application!.createBackupFile( undefined, undefined, true ); - callback(data); - } - - desktop_setMajorDataChangeHandler(handler: () => void) { - this.majorDataChangeHandler = handler; } desktop_didBeginBackup() { diff --git a/app/assets/javascripts/ui_models/application.ts b/app/assets/javascripts/ui_models/application.ts index 4a68378b7..c5fb3dab6 100644 --- a/app/assets/javascripts/ui_models/application.ts +++ b/app/assets/javascripts/ui_models/application.ts @@ -64,7 +64,7 @@ export class WebApplication extends SNApplication { bridge ); super( - Environment.Web, + bridge.environment, platformFromString(getPlatformString()), deviceInterface, new SNWebCrypto(), diff --git a/app/assets/javascripts/ui_models/application_group.ts b/app/assets/javascripts/ui_models/application_group.ts index 984f05e11..19a033cda 100644 --- a/app/assets/javascripts/ui_models/application_group.ts +++ b/app/assets/javascripts/ui_models/application_group.ts @@ -86,7 +86,8 @@ export class ApplicationGroup { const desktopService = new DesktopManager( this.$rootScope, this.$timeout, - application + application, + this.bridge, ); const keyboardService = new KeyboardManager(); const lockService = new LockManager(