From ce053226a55599cb4f577cc727b841902e4dd6ba Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Fri, 27 Jan 2017 18:32:27 -0600 Subject: [PATCH] before destruction --- .../app/frontend/models/local/itemParams.js | 5 ++-- .../directives/accountNewAccountSection.js | 20 +-------------- .../javascripts/app/services/keyManager.js | 4 ++- .../app/services/sync/encryptionHelper.js | 9 +++---- .../app/services/sync/syncManager.js | 11 ++++---- .../app/services/sync/syncProvider.js | 2 +- .../app/services/sync/syncRunner.js | 25 +++++++++---------- .../account-new-account-section.html.haml | 4 --- 8 files changed, 29 insertions(+), 51 deletions(-) diff --git a/app/assets/javascripts/app/frontend/models/local/itemParams.js b/app/assets/javascripts/app/frontend/models/local/itemParams.js index 033360956..396a51bd1 100644 --- a/app/assets/javascripts/app/frontend/models/local/itemParams.js +++ b/app/assets/javascripts/app/frontend/models/local/itemParams.js @@ -1,9 +1,8 @@ class ItemParams { - constructor(item, ek, encryptionHelper) { + constructor(item, ek) { this.item = item; this.ek = ek; - this.encryptionHelper = encryptionHelper; } paramsForExportFile() { @@ -34,7 +33,7 @@ class ItemParams { var params = {uuid: this.item.uuid, content_type: this.item.content_type, deleted: this.item.deleted, created_at: this.item.created_at}; if(this.ek) { - this.encryptionHelper.encryptItem(itemCopy, this.ek); + EncryptionHelper.encryptItem(itemCopy, this.ek); params.content = itemCopy.content; params.enc_item_key = itemCopy.enc_item_key; params.auth_hash = itemCopy.auth_hash; diff --git a/app/assets/javascripts/app/services/directives/accountNewAccountSection.js b/app/assets/javascripts/app/services/directives/accountNewAccountSection.js index 06c19c181..b7b8161af 100644 --- a/app/assets/javascripts/app/services/directives/accountNewAccountSection.js +++ b/app/assets/javascripts/app/services/directives/accountNewAccountSection.js @@ -10,7 +10,7 @@ class AccountNewAccountSection { controller($scope, apiController, modelManager, $timeout, dbManager, syncManager) { 'ngInject'; - $scope.formData = {mergeLocal: true, url: syncManager.defaultServerURL()}; + $scope.formData = {url: syncManager.defaultServerURL()}; $scope.user = apiController.user; $scope.showForm = syncManager.syncProviders.length == 0; @@ -42,18 +42,6 @@ class AccountNewAccountSection { }) } - $scope.localNotesCount = function() { - return modelManager.filteredNotes.length; - } - - $scope.mergeLocalChanged = function() { - if(!$scope.formData.mergeLocal) { - if(!confirm("Unchecking this option means any of the notes you have written while you were signed out will be deleted. Are you sure you want to discard these notes?")) { - $scope.formData.mergeLocal = true; - } - } - } - $scope.loginSubmitPressed = function() { $scope.formData.status = "Generating Login Keys..."; console.log("logging in with url", $scope.formData.url); @@ -87,12 +75,6 @@ class AccountNewAccountSection { }); }) } - - $scope.encryptionStatusForNotes = function() { - var allNotes = modelManager.filteredNotes; - return allNotes.length + "/" + allNotes.length + " notes encrypted"; - } - } } diff --git a/app/assets/javascripts/app/services/keyManager.js b/app/assets/javascripts/app/services/keyManager.js index 292bc6b7a..9f108474d 100644 --- a/app/assets/javascripts/app/services/keyManager.js +++ b/app/assets/javascripts/app/services/keyManager.js @@ -17,9 +17,11 @@ class KeyManager { } keyForName(name) { - return _.find(this.keys, function(key){ + var keyObj = _.find(this.keys, function(key){ return key.name.toLowerCase() == name.toLowerCase(); }); + + return keyObj ? keyObj.key : null; } deleteKey(name) { diff --git a/app/assets/javascripts/app/services/sync/encryptionHelper.js b/app/assets/javascripts/app/services/sync/encryptionHelper.js index a5b547eab..076786f6d 100644 --- a/app/assets/javascripts/app/services/sync/encryptionHelper.js +++ b/app/assets/javascripts/app/services/sync/encryptionHelper.js @@ -1,8 +1,9 @@ class EncryptionHelper { - encryptItem(item, key) { + static encryptItem(item, key) { var item_key = null; if(item.enc_item_key) { + // we reuse the key, but this is optional item_key = Neeto.crypto.decryptText(item.enc_item_key, key); } else { item_key = Neeto.crypto.generateRandomEncryptionKey(); @@ -19,7 +20,7 @@ class EncryptionHelper { item.local_encryption_scheme = "1.0"; } - decryptItem(item, key) { + static decryptItem(item, key) { var item_key = Neeto.crypto.decryptText(item.enc_item_key, key); var ek = Neeto.crypto.firstHalfOfKey(item_key); @@ -34,7 +35,7 @@ class EncryptionHelper { item.content = content; } - decryptMultipleItems(items, key) { + static decryptMultipleItems(items, key) { for (var item of items) { if(item.deleted == true) { continue; @@ -59,5 +60,3 @@ class EncryptionHelper { } } - -angular.module('app.frontend').service('encryptionHelper', EncryptionHelper); diff --git a/app/assets/javascripts/app/services/sync/syncManager.js b/app/assets/javascripts/app/services/sync/syncManager.js index 61c07d88c..67bc4aacf 100644 --- a/app/assets/javascripts/app/services/sync/syncManager.js +++ b/app/assets/javascripts/app/services/sync/syncManager.js @@ -60,7 +60,7 @@ class SyncManager { this.didMakeChangesToSyncProviders(); } - primarySyncProvider() { + get primarySyncProvider() { return _.find(this.syncProviders, {primary: true}); } @@ -107,7 +107,7 @@ class SyncManager { addAccountBasedSyncProvider({url, email, uuid, ek, jwt, auth_params} = {}) { var provider = new SyncProvider({ url: url + "/items/sync", - primary: !this.primarySyncProvider(), + primary: !this.primarySyncProvider, email: email, uuid: uuid, jwt: jwt, @@ -119,8 +119,6 @@ class SyncManager { this.syncProviders.push(provider); - this.didMakeChangesToSyncProviders(); - this.keyManager.addKey(provider.keyName, ek); this.enableSyncProvider(provider, this.enabledProviders == 0); @@ -136,6 +134,9 @@ class SyncManager { } enableSyncProvider(syncProvider, primary) { + // we want to sync the new provider where our current primary one is + syncProvider.syncToken = this.primarySyncProvider ? this.primarySyncProvider.syncToken : null; + if(primary) { for(var provider of this.syncProviders) { provider.primary = false; @@ -161,7 +162,7 @@ class SyncManager { } clearSyncToken() { - var primary = this.primarySyncProvider(); + var primary = this.primarySyncProvider; if(primary) { primary.syncToken = null; } diff --git a/app/assets/javascripts/app/services/sync/syncProvider.js b/app/assets/javascripts/app/services/sync/syncProvider.js index 6c6767317..2647931e1 100644 --- a/app/assets/javascripts/app/services/sync/syncProvider.js +++ b/app/assets/javascripts/app/services/sync/syncProvider.js @@ -16,7 +16,7 @@ class SyncProvider { this.pendingItems = []; } - this.pendingItems = this.pendingItems.concat(items); + this.pendingItems = _.uniqBy(this.pendingItems.concat(items), "uuid"); } removePendingItems(items) { diff --git a/app/assets/javascripts/app/services/sync/syncRunner.js b/app/assets/javascripts/app/services/sync/syncRunner.js index fc4398583..89c123182 100644 --- a/app/assets/javascripts/app/services/sync/syncRunner.js +++ b/app/assets/javascripts/app/services/sync/syncRunner.js @@ -1,10 +1,9 @@ class SyncRunner { - constructor($rootScope, modelManager, dbManager, encryptionHelper, keyManager, Restangular) { + constructor($rootScope, modelManager, dbManager, keyManager, Restangular) { this.rootScope = $rootScope; this.modelManager = modelManager; this.dbManager = dbManager; - this.encryptionHelper = encryptionHelper; this.keyManager = keyManager; this.Restangular = Restangular; } @@ -90,9 +89,9 @@ class SyncRunner { return; } - // whether this is a repeat sync (a continuation from another sync; we use this to update status accurately) - var isRepeatRun = provider.repeatOnCompletion; + var isContinuationSync = provider.needsMoreSync; + provider.repeatOnCompletion = false; provider.syncOpInProgress = true; let submitLimit = 100; @@ -100,17 +99,16 @@ class SyncRunner { var subItems = allItems.slice(0, submitLimit); if(subItems.length < allItems.length) { // more items left to be synced, repeat - provider.repeatOnCompletion = true; + provider.needsMoreSync = true; } else { - provider.repeatOnCompletion = false; + provider.needsMoreSync = false; } - if(!isRepeatRun) { + if(!isContinuationSync) { provider.syncStatus.total = allItems.length; provider.syncStatus.current = 0; } - // Remove dirty items now. If this operation fails, we'll re-add them. // This allows us to queue changes on the same item provider.removePendingItems(subItems); @@ -118,12 +116,13 @@ class SyncRunner { var request = this.Restangular.oneUrl(provider.url, provider.url); request.limit = 150; request.items = _.map(subItems, function(item){ - var itemParams = new ItemParams(item, provider.ek); + var key = this.keyManager.keyForName(provider.keyName); + var itemParams = new ItemParams(item, key); itemParams.additionalFields = options.additionalFields; return itemParams.paramsForSync(); }.bind(this)); - // request.sync_token = provider.syncToken; + request.sync_token = provider.syncToken; request.cursor_token = provider.cursorToken; console.log("Syncing with provider:", provider, "items:", subItems.length, "token", request.sync_token); @@ -155,7 +154,7 @@ class SyncRunner { provider.syncOpInProgress = false; provider.syncStatus.current += subItems.length; - if(provider.cursorToken || provider.repeatOnCompletion == true) { + if(provider.cursorToken || provider.repeatOnCompletion || provider.needsMoreSync) { this.__performSyncWithProvider(provider, options, callback); } else { if(callback) { @@ -206,8 +205,8 @@ class SyncRunner { } handleItemsResponse(responseItems, omitFields, syncProvider) { - var ek = syncProvider ? this.keyManager.keyForName(syncProvider.keyName).key : null; - this.encryptionHelper.decryptMultipleItems(responseItems, ek); + var ek = syncProvider ? this.keyManager.keyForName(syncProvider.keyName) : null; + EncryptionHelper.decryptMultipleItems(responseItems, ek); return this.modelManager.mapResponseItemsToLocalModelsOmittingFields(responseItems, omitFields); } } diff --git a/app/assets/templates/frontend/directives/account-menu/account-new-account-section.html.haml b/app/assets/templates/frontend/directives/account-menu/account-new-account-section.html.haml index b015a1443..6a9b3cbfa 100644 --- a/app/assets/templates/frontend/directives/account-menu/account-new-account-section.html.haml +++ b/app/assets/templates/frontend/directives/account-menu/account-new-account-section.html.haml @@ -10,10 +10,6 @@ %input.form-control{:placeholder => 'Password', :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.user_password'} %div{"ng-if" => "!formData.status"} - .checkbox{"ng-if" => "localNotesCount() > 0"} - %label - %input{"type" => "checkbox", "ng-model" => "formData.mergeLocal", "ng-bind" => "true", "ng-change" => "mergeLocalChanged()"} - Merge local notes ({{localNotesCount()}} notes) %button.btn.dark-button.half-button{"ng-click" => "loginSubmitPressed()", "data-style" => "expand-right", "data-size" => "s", "state" => "buttonState"} %span Sign In %button.btn.dark-button.half-button{"ng-click" => "submitRegistrationForm()", "data-style" => "expand-right", "data-size" => "s", "state" => "buttonState"}