offline mode
This commit is contained in:
@@ -1,13 +1,6 @@
|
||||
class BaseCtrl {
|
||||
constructor($rootScope, modelManager) {
|
||||
// $rootScope.resetPasswordSubmit = function() {
|
||||
// var new_keys = Neeto.crypto.generateEncryptionKeysForUser($rootScope.resetData.password, $rootScope.resetData.email);
|
||||
// var data = _.clone($rootScope.resetData);
|
||||
// data.password = new_keys.pw;
|
||||
// data.password_confirmation = new_keys.pw;
|
||||
// $auth.updatePassword(data);
|
||||
// apiController.setMk(new_keys.mk);
|
||||
// }
|
||||
constructor($rootScope, modelManager, apiController) {
|
||||
apiController.getCurrentUser(function(){});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,7 @@ angular.module('app.frontend')
|
||||
scope: {
|
||||
save: "&",
|
||||
remove: "&",
|
||||
note: "=",
|
||||
user: "="
|
||||
note: "="
|
||||
},
|
||||
templateUrl: 'frontend/editor.html',
|
||||
replace: true,
|
||||
@@ -124,6 +123,11 @@ angular.module('app.frontend')
|
||||
statusTimeout = $timeout(function(){
|
||||
this.noteStatus = "All changes saved"
|
||||
}.bind(this), 200)
|
||||
} else {
|
||||
if(statusTimeout) $timeout.cancel(statusTimeout);
|
||||
statusTimeout = $timeout(function(){
|
||||
this.noteStatus = "(Offline) — All changes saved"
|
||||
}.bind(this), 200)
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
@@ -138,7 +142,7 @@ angular.module('app.frontend')
|
||||
this.changesMade = function() {
|
||||
this.note.hasChanges = true;
|
||||
this.note.dummy = false;
|
||||
if(this.user.uuid) {
|
||||
if(apiController.isUserSignedIn()) {
|
||||
// signed out users have local autosave, dont need draft saving
|
||||
apiController.saveDraftToDisk(this.note);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ angular.module('app.frontend')
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
user: "=",
|
||||
logout: "&"
|
||||
},
|
||||
templateUrl: 'frontend/header.html',
|
||||
@@ -21,6 +20,7 @@ angular.module('app.frontend')
|
||||
})
|
||||
.controller('HeaderCtrl', function ($state, apiController, modelManager, serverSideValidation, $timeout, extensionManager) {
|
||||
|
||||
this.user = apiController.user;
|
||||
this.extensionManager = extensionManager;
|
||||
|
||||
this.changePasswordPressed = function() {
|
||||
@@ -104,7 +104,7 @@ angular.module('app.frontend')
|
||||
return;
|
||||
}
|
||||
|
||||
apiController.changePassword(this.user, this.passwordChangeData.current_password, this.passwordChangeData.new_password, function(response){
|
||||
apiController.changePassword(this.passwordChangeData.current_password, this.passwordChangeData.new_password, function(response){
|
||||
|
||||
})
|
||||
|
||||
@@ -210,7 +210,6 @@ angular.module('app.frontend')
|
||||
}
|
||||
|
||||
this.onAuthSuccess = function(user) {
|
||||
this.user.uuid = user.uuid;
|
||||
|
||||
// if(this.user.shouldMerge && this.hasLocalData()) {
|
||||
// apiController.mergeLocalDataRemotely(this.user, function(){
|
||||
|
||||
@@ -2,30 +2,17 @@ angular.module('app.frontend')
|
||||
.controller('HomeCtrl', function ($scope, $rootScope, $timeout, apiController, modelManager) {
|
||||
$rootScope.bodyClass = "app-body-class";
|
||||
|
||||
var onUserSet = function() {
|
||||
apiController.setUser($scope.defaultUser);
|
||||
$scope.allTag = new Tag({all: true});
|
||||
$scope.allTag.title = "All";
|
||||
$scope.tags = modelManager.tags;
|
||||
$scope.allTag.notes = modelManager.notes;
|
||||
apiController.loadLocalItems();
|
||||
$scope.allTag = new Tag({all: true});
|
||||
$scope.allTag.title = "All";
|
||||
$scope.tags = modelManager.tags;
|
||||
$scope.allTag.notes = modelManager.notes;
|
||||
|
||||
apiController.sync(null);
|
||||
// refresh every 30s
|
||||
setInterval(function () {
|
||||
apiController.sync(null);
|
||||
// refresh every 30s
|
||||
setInterval(function () {
|
||||
apiController.sync(null);
|
||||
}, 30000);
|
||||
}
|
||||
|
||||
apiController.getCurrentUser(function(user){
|
||||
if(user) {
|
||||
$scope.defaultUser = user;
|
||||
$rootScope.title = "Notes — Standard Notes";
|
||||
onUserSet();
|
||||
} else {
|
||||
$scope.defaultUser = new User(apiController.loadLocalItemsAndUser());
|
||||
onUserSet();
|
||||
}
|
||||
});
|
||||
}, 30000);
|
||||
|
||||
/*
|
||||
Tags Ctrl Callbacks
|
||||
@@ -115,7 +102,10 @@ angular.module('app.frontend')
|
||||
|
||||
apiController.sync(function(response){
|
||||
if(response && response.error) {
|
||||
alert("There was an error saving your note. Please try again.");
|
||||
if(!$scope.didShowErrorAlert) {
|
||||
$scope.didShowErrorAlert = true;
|
||||
alert("There was an error saving your note. Please try again.");
|
||||
}
|
||||
callback(false);
|
||||
} else {
|
||||
note.hasChanges = false;
|
||||
@@ -147,8 +137,7 @@ angular.module('app.frontend')
|
||||
*/
|
||||
|
||||
$scope.headerLogout = function() {
|
||||
$scope.defaultUser = apiController.loadLocalItemsAndUser();
|
||||
$scope.tags = $scope.defaultUser.tags;
|
||||
apiController.clearLocalStorage();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ angular.module('app.frontend')
|
||||
selectionMade: "&",
|
||||
remove: "&",
|
||||
tag: "=",
|
||||
user: "=",
|
||||
removeTag: "&"
|
||||
},
|
||||
|
||||
@@ -71,7 +70,7 @@ angular.module('app.frontend')
|
||||
this.selectedTagShare = function() {
|
||||
this.showMenu = false;
|
||||
|
||||
if(!this.user.uuid) {
|
||||
if(!apiController.isUserSignedIn()) {
|
||||
alert("You must be signed in to share a tag.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ angular.module('app.frontend')
|
||||
save: "&",
|
||||
tags: "=",
|
||||
allTag: "=",
|
||||
user: "=",
|
||||
updateNoteTag: "&"
|
||||
},
|
||||
templateUrl: 'frontend/tags.html',
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
angular.module('app.frontend')
|
||||
.controller('UsernameModalCtrl', function ($scope, apiController, Restangular, user, callback, $timeout) {
|
||||
.controller('UsernameModalCtrl', function ($scope, apiController, Restangular, callback, $timeout) {
|
||||
$scope.formData = {};
|
||||
|
||||
$scope.saveUsername = function() {
|
||||
apiController.setUsername(user, $scope.formData.username, function(response){
|
||||
apiController.setUsername($scope.formData.username, function(response){
|
||||
var username = response.username;
|
||||
user.username = username;
|
||||
callback(username);
|
||||
$scope.closeThisDialog();
|
||||
})
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
class User {
|
||||
constructor(json_obj) {
|
||||
_.merge(this, json_obj);
|
||||
}
|
||||
}
|
||||
@@ -26,9 +26,8 @@ angular.module('app.frontend')
|
||||
|
||||
function ApiController($rootScope, Restangular, modelManager, ngDialog) {
|
||||
|
||||
this.setUser = function(user) {
|
||||
this.user = user;
|
||||
}
|
||||
this.user = {};
|
||||
this.syncToken = localStorage.getItem("syncToken");
|
||||
|
||||
/*
|
||||
Config
|
||||
@@ -58,7 +57,11 @@ angular.module('app.frontend')
|
||||
*/
|
||||
|
||||
this.isUserSignedIn = function() {
|
||||
return this.user.email && this.retrieveMk();
|
||||
return localStorage.getItem("jwt");
|
||||
}
|
||||
|
||||
this.userId = function() {
|
||||
return localStorage.getItem("uuid");
|
||||
}
|
||||
|
||||
this.getAuthParamsForEmail = function(email, callback) {
|
||||
@@ -79,7 +82,8 @@ angular.module('app.frontend')
|
||||
}
|
||||
Restangular.one("users/current").get().then(function(response){
|
||||
var user = response.plain();
|
||||
callback(user);
|
||||
_.merge(this.user, user);
|
||||
callback();
|
||||
}.bind(this))
|
||||
.catch(function(response){
|
||||
console.log("Error getting current user", response);
|
||||
@@ -100,6 +104,7 @@ angular.module('app.frontend')
|
||||
_.merge(request, params);
|
||||
request.post().then(function(response){
|
||||
localStorage.setItem("jwt", response.token);
|
||||
localStorage.setItem("uuid", response.uuid);
|
||||
callback(response);
|
||||
})
|
||||
.catch(function(response){
|
||||
@@ -118,6 +123,7 @@ angular.module('app.frontend')
|
||||
_.merge(request, params);
|
||||
request.post().then(function(response){
|
||||
localStorage.setItem("jwt", response.token);
|
||||
localStorage.setItem("uuid", response.uuid);
|
||||
callback(response);
|
||||
})
|
||||
.catch(function(response){
|
||||
@@ -126,46 +132,46 @@ angular.module('app.frontend')
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
this.changePassword = function(user, current_password, new_password) {
|
||||
this.getAuthParamsForEmail(email, function(authParams){
|
||||
if(!authParams) {
|
||||
callback(null);
|
||||
return;
|
||||
}
|
||||
Neeto.crypto.computeEncryptionKeysForUser(_.merge({password: current_password, email: user.email}, authParams), function(currentKeys) {
|
||||
Neeto.crypto.computeEncryptionKeysForUser(_.merge({password: new_password, email: user.email}, authParams), function(newKeys){
|
||||
var data = {};
|
||||
data.current_password = currentKeys.pw;
|
||||
data.password = newKeys.pw;
|
||||
data.password_confirmation = newKeys.pw;
|
||||
|
||||
var user = this.user;
|
||||
|
||||
this._performPasswordChange(currentKeys, newKeys, function(response){
|
||||
if(response && !response.error) {
|
||||
// this.showNewPasswordForm = false;
|
||||
// reencrypt data with new mk
|
||||
this.reencryptAllItemsAndSave(user, newKeys.mk, currentKeys.mk, function(success){
|
||||
if(success) {
|
||||
this.setMk(newKeys.mk);
|
||||
alert("Your password has been changed and your data re-encrypted.");
|
||||
} else {
|
||||
// rollback password
|
||||
this._performPasswordChange(newKeys, currentKeys, function(response){
|
||||
alert("There was an error changing your password. Your password has been rolled back.");
|
||||
window.location.reload();
|
||||
})
|
||||
}
|
||||
}.bind(this));
|
||||
} else {
|
||||
// this.showNewPasswordForm = false;
|
||||
alert("There was an error changing your password. Please try again.");
|
||||
}
|
||||
}.bind(this))
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
}
|
||||
// this.changePassword = function(current_password, new_password) {
|
||||
// this.getAuthParamsForEmail(email, function(authParams){
|
||||
// if(!authParams) {
|
||||
// callback(null);
|
||||
// return;
|
||||
// }
|
||||
// Neeto.crypto.computeEncryptionKeysForUser(_.merge({password: current_password, email: user.email}, authParams), function(currentKeys) {
|
||||
// Neeto.crypto.computeEncryptionKeysForUser(_.merge({password: new_password, email: user.email}, authParams), function(newKeys){
|
||||
// var data = {};
|
||||
// data.current_password = currentKeys.pw;
|
||||
// data.password = newKeys.pw;
|
||||
// data.password_confirmation = newKeys.pw;
|
||||
//
|
||||
// var user = this.user;
|
||||
//
|
||||
// this._performPasswordChange(currentKeys, newKeys, function(response){
|
||||
// if(response && !response.error) {
|
||||
// // this.showNewPasswordForm = false;
|
||||
// // reencrypt data with new mk
|
||||
// this.reencryptAllItemsAndSave(user, newKeys.mk, currentKeys.mk, function(success){
|
||||
// if(success) {
|
||||
// this.setMk(newKeys.mk);
|
||||
// alert("Your password has been changed and your data re-encrypted.");
|
||||
// } else {
|
||||
// // rollback password
|
||||
// this._performPasswordChange(newKeys, currentKeys, function(response){
|
||||
// alert("There was an error changing your password. Your password has been rolled back.");
|
||||
// window.location.reload();
|
||||
// })
|
||||
// }
|
||||
// }.bind(this));
|
||||
// } else {
|
||||
// // this.showNewPasswordForm = false;
|
||||
// alert("There was an error changing your password. Please try again.");
|
||||
// }
|
||||
// }.bind(this))
|
||||
// }.bind(this));
|
||||
// }.bind(this));
|
||||
// }.bind(this));
|
||||
// }
|
||||
|
||||
this._performPasswordChange = function(email, current_keys, new_keys, callback) {
|
||||
var request = Restangular.one("auth");
|
||||
@@ -181,53 +187,37 @@ angular.module('app.frontend')
|
||||
User
|
||||
*/
|
||||
|
||||
this.setUsername = function(user, username, callback) {
|
||||
var request = Restangular.one("users", user.uuid);
|
||||
this.setUsername = function(username, callback) {
|
||||
var request = Restangular.one("users", this.userId());
|
||||
request.username = username;
|
||||
request.patch().then(function(response){
|
||||
this.user.username = response.username;
|
||||
callback(response.plain());
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
Ensures that if encryption is disabled, all local items are uncrypted,
|
||||
and that if it's enabled, that all local items are encrypted
|
||||
*/
|
||||
this.verifyEncryptionStatusOfAllItems = function(user, callback) {
|
||||
var allItems = user.filteredItems();
|
||||
var itemsNeedingUpdate = [];
|
||||
allItems.forEach(function(item){
|
||||
if(!item.isPublic()) {
|
||||
if(item.encryptionEnabled() && !item.isEncrypted()) {
|
||||
itemsNeedingUpdate.push(item);
|
||||
}
|
||||
} else {
|
||||
if(item.isEncrypted()) {
|
||||
itemsNeedingUpdate.push(item);
|
||||
}
|
||||
}
|
||||
}.bind(this))
|
||||
|
||||
if(itemsNeedingUpdate.length > 0) {
|
||||
console.log("verifying encryption, items need updating", itemsNeedingUpdate);
|
||||
this.saveBatchItems(user, itemsNeedingUpdate, callback)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Items
|
||||
*/
|
||||
|
||||
this.setSyncToken = function(syncToken) {
|
||||
this.syncToken = syncToken;
|
||||
localStorage.setItem("syncToken", this.syncToken);
|
||||
}
|
||||
|
||||
this.syncWithOptions = function(callback, options = {}) {
|
||||
if(!this.user.uuid) {
|
||||
this.writeItemsToLocalStorage(function(responseItems){
|
||||
this.writeAllItemsToLocalStorage(function(responseItems){
|
||||
if(!this.isUserSignedIn()) {
|
||||
// is not signed in
|
||||
modelManager.clearDirtyItems();
|
||||
if(callback) {
|
||||
callback();
|
||||
}
|
||||
}.bind(this))
|
||||
}
|
||||
}.bind(this))
|
||||
|
||||
if(!this.isUserSignedIn()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -245,7 +235,7 @@ angular.module('app.frontend')
|
||||
|
||||
request.post().then(function(response) {
|
||||
modelManager.clearDirtyItems();
|
||||
this.syncToken = response.sync_token;
|
||||
this.setSyncToken(response.sync_token);
|
||||
$rootScope.$broadcast("sync:updated_token", this.syncToken);
|
||||
|
||||
this.handleItemsResponse(response.retrieved_items, null);
|
||||
@@ -253,13 +243,17 @@ angular.module('app.frontend')
|
||||
var omitFields = ["content", "enc_item_key", "auth_hash"];
|
||||
this.handleItemsResponse(response.saved_items, omitFields);
|
||||
|
||||
this.writeAllItemsToLocalStorage();
|
||||
|
||||
if(callback) {
|
||||
callback(response);
|
||||
}
|
||||
}.bind(this))
|
||||
.catch(function(response){
|
||||
console.log("Sync error: ", response);
|
||||
callback({error: "Sync error"});
|
||||
if(callback) {
|
||||
callback({error: "Sync error"});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -314,7 +308,7 @@ angular.module('app.frontend')
|
||||
}
|
||||
|
||||
this.shareItem = function(item, callback) {
|
||||
if(!this.user.uuid) {
|
||||
if(!this.isUserSignedIn()) {
|
||||
alert("You must be signed in to share.");
|
||||
return;
|
||||
}
|
||||
@@ -333,7 +327,6 @@ angular.module('app.frontend')
|
||||
template: 'frontend/modals/username.html',
|
||||
controller: 'UsernameModalCtrl',
|
||||
resolve: {
|
||||
user: function() {return this.user}.bind(this),
|
||||
callback: function() {
|
||||
return shareFn;
|
||||
}
|
||||
@@ -407,52 +400,56 @@ angular.module('app.frontend')
|
||||
/*
|
||||
Merging
|
||||
*/
|
||||
this.mergeLocalDataRemotely = function(user, callback) {
|
||||
var request = Restangular.one("users", user.uuid).one("merge");
|
||||
var tags = user.tags;
|
||||
request.items = user.items;
|
||||
request.items.forEach(function(item){
|
||||
if(item.tag_id) {
|
||||
var tag = tags.filter(function(tag){return tag.uuid == item.tag_id})[0];
|
||||
item.tag_name = tag.title;
|
||||
}
|
||||
})
|
||||
request.post().then(function(response){
|
||||
callback();
|
||||
localStorage.removeItem('user');
|
||||
})
|
||||
// this.mergeLocalDataRemotely = function(user, callback) {
|
||||
// var request = Restangular.one("users", this.userId()).one("merge");
|
||||
// var tags = user.tags;
|
||||
// request.items = user.items;
|
||||
// request.items.forEach(function(item){
|
||||
// if(item.tag_id) {
|
||||
// var tag = tags.filter(function(tag){return tag.uuid == item.tag_id})[0];
|
||||
// item.tag_name = tag.title;
|
||||
// }
|
||||
// })
|
||||
// request.post().then(function(response){
|
||||
// callback();
|
||||
// localStorage.removeItem('user');
|
||||
// })
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
this.clearLocalStorage = function() {
|
||||
localStorage.removeItem("items");
|
||||
localStorage.removeItem("mk");
|
||||
localStorage.removeItem("jwt");
|
||||
localStorage.removeItem("uuid");
|
||||
localStorage.removeItem("syncToken");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
this.staticifyObject = function(object) {
|
||||
return JSON.parse(JSON.stringify(object));
|
||||
}
|
||||
|
||||
this.writeItemsToLocalStorage = function(callback) {
|
||||
this.writeAllItemsToLocalStorage = function(callback) {
|
||||
var items = _.map(modelManager.allItems, function(item){
|
||||
return this.paramsForItem(item, false, ["created_at", "updated_at"], false)
|
||||
return this.paramsForItem(item, this.isUserSignedIn(), ["created_at", "updated_at"], false)
|
||||
}.bind(this));
|
||||
console.log("Writing items to local", items);
|
||||
// console.log("Writing items to local", items);
|
||||
this.writeToLocalStorage('items', items);
|
||||
callback(items);
|
||||
if(callback) {
|
||||
callback(items);
|
||||
}
|
||||
}
|
||||
|
||||
this.writeToLocalStorage = function(key, value) {
|
||||
localStorage.setItem(key, angular.toJson(value));
|
||||
}
|
||||
|
||||
this.loadLocalItemsAndUser = function() {
|
||||
var user = {};
|
||||
this.loadLocalItems = function() {
|
||||
var items = JSON.parse(localStorage.getItem('items')) || [];
|
||||
items = this.handleItemsResponse(items, null);
|
||||
Item.sortItemsByDate(items);
|
||||
user.items = items;
|
||||
user.shouldMerge = true;
|
||||
return user;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -551,7 +548,7 @@ angular.module('app.frontend')
|
||||
}
|
||||
|
||||
this.reencryptAllItemsAndSave = function(user, newMasterKey, oldMasterKey, callback) {
|
||||
var items = user.filteredItems();
|
||||
var items = modelManager.allItems();
|
||||
items.forEach(function(item){
|
||||
if(item.content.substring(0, 3) == "001" && item.enc_item_key) {
|
||||
// first decrypt item_key with old key
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"tags" => "tags", "user" => "defaultUser", "update-note-tag" => "tagsUpdateNoteTag"}
|
||||
|
||||
%notes-section{"remove-tag" => "notesRemoveTag", "user" => "defaultUser", "add-new" => "notesAddNew", "selection-made" => "notesSelectionMade",
|
||||
"tag" => "selectedTag", "user-id" => "defaultUser.uuid", "remove" => "deleteNote"}
|
||||
"tag" => "selectedTag", "remove" => "deleteNote"}
|
||||
|
||||
%editor-section{"ng-if" => "selectedNote", "note" => "selectedNote", "remove" => "deleteNote",
|
||||
"user" => "defaultUser", "save" => "saveNote"}
|
||||
|
||||
294
vendor/assets/javascripts/transpiled.js
vendored
294
vendor/assets/javascripts/transpiled.js
vendored
@@ -438,17 +438,10 @@ angular.module('app.frontend', ['ui.router', 'restangular', 'ngDialog']).config(
|
||||
$locationProvider.html5Mode(true);
|
||||
});
|
||||
;
|
||||
var BaseCtrl = function BaseCtrl($rootScope, modelManager) {
|
||||
// $rootScope.resetPasswordSubmit = function() {
|
||||
// var new_keys = Neeto.crypto.generateEncryptionKeysForUser($rootScope.resetData.password, $rootScope.resetData.email);
|
||||
// var data = _.clone($rootScope.resetData);
|
||||
// data.password = new_keys.pw;
|
||||
// data.password_confirmation = new_keys.pw;
|
||||
// $auth.updatePassword(data);
|
||||
// apiController.setMk(new_keys.mk);
|
||||
// }
|
||||
|
||||
var BaseCtrl = function BaseCtrl($rootScope, modelManager, apiController) {
|
||||
_classCallCheck(this, BaseCtrl);
|
||||
|
||||
apiController.getCurrentUser(function () {});
|
||||
};
|
||||
|
||||
angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||
@@ -458,8 +451,7 @@ angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||
scope: {
|
||||
save: "&",
|
||||
remove: "&",
|
||||
note: "=",
|
||||
user: "="
|
||||
note: "="
|
||||
},
|
||||
templateUrl: 'frontend/editor.html',
|
||||
replace: true,
|
||||
@@ -576,6 +568,11 @@ angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||
statusTimeout = $timeout(function () {
|
||||
this.noteStatus = "All changes saved";
|
||||
}.bind(this), 200);
|
||||
} else {
|
||||
if (statusTimeout) $timeout.cancel(statusTimeout);
|
||||
statusTimeout = $timeout(function () {
|
||||
this.noteStatus = "(Offline) — All changes saved";
|
||||
}.bind(this), 200);
|
||||
}
|
||||
}.bind(this));
|
||||
};
|
||||
@@ -590,7 +587,7 @@ angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||
this.changesMade = function () {
|
||||
this.note.hasChanges = true;
|
||||
this.note.dummy = false;
|
||||
if (this.user.uuid) {
|
||||
if (apiController.isUserSignedIn()) {
|
||||
// signed out users have local autosave, dont need draft saving
|
||||
apiController.saveDraftToDisk(this.note);
|
||||
}
|
||||
@@ -720,7 +717,6 @@ angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: {
|
||||
user: "=",
|
||||
logout: "&"
|
||||
},
|
||||
templateUrl: 'frontend/header.html',
|
||||
@@ -737,6 +733,7 @@ angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||
};
|
||||
}).controller('HeaderCtrl', function ($state, apiController, modelManager, serverSideValidation, $timeout, extensionManager) {
|
||||
|
||||
this.user = apiController.user;
|
||||
this.extensionManager = extensionManager;
|
||||
|
||||
this.changePasswordPressed = function () {
|
||||
@@ -820,7 +817,7 @@ angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||
return;
|
||||
}
|
||||
|
||||
apiController.changePassword(this.user, this.passwordChangeData.current_password, this.passwordChangeData.new_password, function (response) {});
|
||||
apiController.changePassword(this.passwordChangeData.current_password, this.passwordChangeData.new_password, function (response) {});
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
@@ -923,7 +920,6 @@ angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||
};
|
||||
|
||||
this.onAuthSuccess = function (user) {
|
||||
this.user.uuid = user.uuid;
|
||||
|
||||
// if(this.user.shouldMerge && this.hasLocalData()) {
|
||||
// apiController.mergeLocalDataRemotely(this.user, function(){
|
||||
@@ -940,30 +936,17 @@ angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||
;angular.module('app.frontend').controller('HomeCtrl', function ($scope, $rootScope, $timeout, apiController, modelManager) {
|
||||
$rootScope.bodyClass = "app-body-class";
|
||||
|
||||
var onUserSet = function onUserSet() {
|
||||
apiController.setUser($scope.defaultUser);
|
||||
$scope.allTag = new Tag({ all: true });
|
||||
$scope.allTag.title = "All";
|
||||
$scope.tags = modelManager.tags;
|
||||
$scope.allTag.notes = modelManager.notes;
|
||||
apiController.loadLocalItems();
|
||||
$scope.allTag = new Tag({ all: true });
|
||||
$scope.allTag.title = "All";
|
||||
$scope.tags = modelManager.tags;
|
||||
$scope.allTag.notes = modelManager.notes;
|
||||
|
||||
apiController.sync(null);
|
||||
// refresh every 30s
|
||||
setInterval(function () {
|
||||
apiController.sync(null);
|
||||
// refresh every 30s
|
||||
setInterval(function () {
|
||||
apiController.sync(null);
|
||||
}, 30000);
|
||||
};
|
||||
|
||||
apiController.getCurrentUser(function (user) {
|
||||
if (user) {
|
||||
$scope.defaultUser = user;
|
||||
$rootScope.title = "Notes — Standard Notes";
|
||||
onUserSet();
|
||||
} else {
|
||||
$scope.defaultUser = new User(apiController.loadLocalItemsAndUser());
|
||||
onUserSet();
|
||||
}
|
||||
});
|
||||
}, 30000);
|
||||
|
||||
/*
|
||||
Tags Ctrl Callbacks
|
||||
@@ -1053,7 +1036,10 @@ angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||
|
||||
apiController.sync(function (response) {
|
||||
if (response && response.error) {
|
||||
alert("There was an error saving your note. Please try again.");
|
||||
if (!$scope.didShowErrorAlert) {
|
||||
$scope.didShowErrorAlert = true;
|
||||
alert("There was an error saving your note. Please try again.");
|
||||
}
|
||||
callback(false);
|
||||
} else {
|
||||
note.hasChanges = false;
|
||||
@@ -1085,8 +1071,7 @@ angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||
*/
|
||||
|
||||
$scope.headerLogout = function () {
|
||||
$scope.defaultUser = apiController.loadLocalItemsAndUser();
|
||||
$scope.tags = $scope.defaultUser.tags;
|
||||
apiController.clearLocalStorage();
|
||||
};
|
||||
});
|
||||
;angular.module('app.frontend').directive("notesSection", function () {
|
||||
@@ -1096,7 +1081,6 @@ angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||
selectionMade: "&",
|
||||
remove: "&",
|
||||
tag: "=",
|
||||
user: "=",
|
||||
removeTag: "&"
|
||||
},
|
||||
|
||||
@@ -1160,7 +1144,7 @@ angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||
this.selectedTagShare = function () {
|
||||
this.showMenu = false;
|
||||
|
||||
if (!this.user.uuid) {
|
||||
if (!apiController.isUserSignedIn()) {
|
||||
alert("You must be signed in to share a tag.");
|
||||
return;
|
||||
}
|
||||
@@ -1232,7 +1216,6 @@ angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||
save: "&",
|
||||
tags: "=",
|
||||
allTag: "=",
|
||||
user: "=",
|
||||
updateNoteTag: "&"
|
||||
},
|
||||
templateUrl: 'frontend/tags.html',
|
||||
@@ -1329,13 +1312,12 @@ angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
||||
this.updateNoteTag()(note, newTag, this.selectedTag);
|
||||
}.bind(this);
|
||||
});
|
||||
;angular.module('app.frontend').controller('UsernameModalCtrl', function ($scope, apiController, Restangular, user, callback, $timeout) {
|
||||
;angular.module('app.frontend').controller('UsernameModalCtrl', function ($scope, apiController, Restangular, callback, $timeout) {
|
||||
$scope.formData = {};
|
||||
|
||||
$scope.saveUsername = function () {
|
||||
apiController.setUsername(user, $scope.formData.username, function (response) {
|
||||
apiController.setUsername($scope.formData.username, function (response) {
|
||||
var username = response.username;
|
||||
user.username = username;
|
||||
callback(username);
|
||||
$scope.closeThisDialog();
|
||||
});
|
||||
@@ -1889,13 +1871,6 @@ var Tag = function (_Item3) {
|
||||
return Tag;
|
||||
}(Item);
|
||||
|
||||
;
|
||||
var User = function User(json_obj) {
|
||||
_classCallCheck(this, User);
|
||||
|
||||
_.merge(this, json_obj);
|
||||
};
|
||||
|
||||
;angular.module('app.frontend').provider('apiController', function () {
|
||||
|
||||
function domainName() {
|
||||
@@ -1922,9 +1897,8 @@ var User = function User(json_obj) {
|
||||
|
||||
function ApiController($rootScope, Restangular, modelManager, ngDialog) {
|
||||
|
||||
this.setUser = function (user) {
|
||||
this.user = user;
|
||||
};
|
||||
this.user = {};
|
||||
this.syncToken = localStorage.getItem("syncToken");
|
||||
|
||||
/*
|
||||
Config
|
||||
@@ -1953,7 +1927,11 @@ var User = function User(json_obj) {
|
||||
*/
|
||||
|
||||
this.isUserSignedIn = function () {
|
||||
return this.user.email && this.retrieveMk();
|
||||
return localStorage.getItem("jwt");
|
||||
};
|
||||
|
||||
this.userId = function () {
|
||||
return localStorage.getItem("uuid");
|
||||
};
|
||||
|
||||
this.getAuthParamsForEmail = function (email, callback) {
|
||||
@@ -1973,7 +1951,8 @@ var User = function User(json_obj) {
|
||||
}
|
||||
Restangular.one("users/current").get().then(function (response) {
|
||||
var user = response.plain();
|
||||
callback(user);
|
||||
_.merge(this.user, user);
|
||||
callback();
|
||||
}.bind(this)).catch(function (response) {
|
||||
console.log("Error getting current user", response);
|
||||
callback(response.data);
|
||||
@@ -1993,6 +1972,7 @@ var User = function User(json_obj) {
|
||||
_.merge(request, params);
|
||||
request.post().then(function (response) {
|
||||
localStorage.setItem("jwt", response.token);
|
||||
localStorage.setItem("uuid", response.uuid);
|
||||
callback(response);
|
||||
}).catch(function (response) {
|
||||
callback(response.data);
|
||||
@@ -2010,6 +1990,7 @@ var User = function User(json_obj) {
|
||||
_.merge(request, params);
|
||||
request.post().then(function (response) {
|
||||
localStorage.setItem("jwt", response.token);
|
||||
localStorage.setItem("uuid", response.uuid);
|
||||
callback(response);
|
||||
}).catch(function (response) {
|
||||
callback(response.data);
|
||||
@@ -2017,46 +1998,46 @@ var User = function User(json_obj) {
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
this.changePassword = function (user, current_password, new_password) {
|
||||
this.getAuthParamsForEmail(email, function (authParams) {
|
||||
if (!authParams) {
|
||||
callback(null);
|
||||
return;
|
||||
}
|
||||
Neeto.crypto.computeEncryptionKeysForUser(_.merge({ password: current_password, email: user.email }, authParams), function (currentKeys) {
|
||||
Neeto.crypto.computeEncryptionKeysForUser(_.merge({ password: new_password, email: user.email }, authParams), function (newKeys) {
|
||||
var data = {};
|
||||
data.current_password = currentKeys.pw;
|
||||
data.password = newKeys.pw;
|
||||
data.password_confirmation = newKeys.pw;
|
||||
|
||||
var user = this.user;
|
||||
|
||||
this._performPasswordChange(currentKeys, newKeys, function (response) {
|
||||
if (response && !response.error) {
|
||||
// this.showNewPasswordForm = false;
|
||||
// reencrypt data with new mk
|
||||
this.reencryptAllItemsAndSave(user, newKeys.mk, currentKeys.mk, function (success) {
|
||||
if (success) {
|
||||
this.setMk(newKeys.mk);
|
||||
alert("Your password has been changed and your data re-encrypted.");
|
||||
} else {
|
||||
// rollback password
|
||||
this._performPasswordChange(newKeys, currentKeys, function (response) {
|
||||
alert("There was an error changing your password. Your password has been rolled back.");
|
||||
window.location.reload();
|
||||
});
|
||||
}
|
||||
}.bind(this));
|
||||
} else {
|
||||
// this.showNewPasswordForm = false;
|
||||
alert("There was an error changing your password. Please try again.");
|
||||
}
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
}.bind(this));
|
||||
};
|
||||
// this.changePassword = function(current_password, new_password) {
|
||||
// this.getAuthParamsForEmail(email, function(authParams){
|
||||
// if(!authParams) {
|
||||
// callback(null);
|
||||
// return;
|
||||
// }
|
||||
// Neeto.crypto.computeEncryptionKeysForUser(_.merge({password: current_password, email: user.email}, authParams), function(currentKeys) {
|
||||
// Neeto.crypto.computeEncryptionKeysForUser(_.merge({password: new_password, email: user.email}, authParams), function(newKeys){
|
||||
// var data = {};
|
||||
// data.current_password = currentKeys.pw;
|
||||
// data.password = newKeys.pw;
|
||||
// data.password_confirmation = newKeys.pw;
|
||||
//
|
||||
// var user = this.user;
|
||||
//
|
||||
// this._performPasswordChange(currentKeys, newKeys, function(response){
|
||||
// if(response && !response.error) {
|
||||
// // this.showNewPasswordForm = false;
|
||||
// // reencrypt data with new mk
|
||||
// this.reencryptAllItemsAndSave(user, newKeys.mk, currentKeys.mk, function(success){
|
||||
// if(success) {
|
||||
// this.setMk(newKeys.mk);
|
||||
// alert("Your password has been changed and your data re-encrypted.");
|
||||
// } else {
|
||||
// // rollback password
|
||||
// this._performPasswordChange(newKeys, currentKeys, function(response){
|
||||
// alert("There was an error changing your password. Your password has been rolled back.");
|
||||
// window.location.reload();
|
||||
// })
|
||||
// }
|
||||
// }.bind(this));
|
||||
// } else {
|
||||
// // this.showNewPasswordForm = false;
|
||||
// alert("There was an error changing your password. Please try again.");
|
||||
// }
|
||||
// }.bind(this))
|
||||
// }.bind(this));
|
||||
// }.bind(this));
|
||||
// }.bind(this));
|
||||
// }
|
||||
|
||||
this._performPasswordChange = function (email, current_keys, new_keys, callback) {
|
||||
var request = Restangular.one("auth");
|
||||
@@ -2071,53 +2052,38 @@ var User = function User(json_obj) {
|
||||
User
|
||||
*/
|
||||
|
||||
this.setUsername = function (user, username, callback) {
|
||||
var request = Restangular.one("users", user.uuid);
|
||||
this.setUsername = function (username, callback) {
|
||||
var request = Restangular.one("users", this.userId());
|
||||
request.username = username;
|
||||
request.patch().then(function (response) {
|
||||
this.user.username = response.username;
|
||||
callback(response.plain());
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
Ensures that if encryption is disabled, all local items are uncrypted,
|
||||
and that if it's enabled, that all local items are encrypted
|
||||
*/
|
||||
this.verifyEncryptionStatusOfAllItems = function (user, callback) {
|
||||
var allItems = user.filteredItems();
|
||||
var itemsNeedingUpdate = [];
|
||||
allItems.forEach(function (item) {
|
||||
if (!item.isPublic()) {
|
||||
if (item.encryptionEnabled() && !item.isEncrypted()) {
|
||||
itemsNeedingUpdate.push(item);
|
||||
}
|
||||
} else {
|
||||
if (item.isEncrypted()) {
|
||||
itemsNeedingUpdate.push(item);
|
||||
}
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
if (itemsNeedingUpdate.length > 0) {
|
||||
console.log("verifying encryption, items need updating", itemsNeedingUpdate);
|
||||
this.saveBatchItems(user, itemsNeedingUpdate, callback);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Items
|
||||
*/
|
||||
|
||||
this.setSyncToken = function (syncToken) {
|
||||
this.syncToken = syncToken;
|
||||
localStorage.setItem("syncToken", this.syncToken);
|
||||
};
|
||||
|
||||
this.syncWithOptions = function (callback) {
|
||||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
if (!this.user.uuid) {
|
||||
this.writeItemsToLocalStorage(function (responseItems) {
|
||||
this.writeAllItemsToLocalStorage(function (responseItems) {
|
||||
if (!this.isUserSignedIn()) {
|
||||
// is not signed in
|
||||
modelManager.clearDirtyItems();
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
if (!this.isUserSignedIn()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2135,7 +2101,7 @@ var User = function User(json_obj) {
|
||||
|
||||
request.post().then(function (response) {
|
||||
modelManager.clearDirtyItems();
|
||||
this.syncToken = response.sync_token;
|
||||
this.setSyncToken(response.sync_token);
|
||||
$rootScope.$broadcast("sync:updated_token", this.syncToken);
|
||||
|
||||
this.handleItemsResponse(response.retrieved_items, null);
|
||||
@@ -2143,12 +2109,16 @@ var User = function User(json_obj) {
|
||||
var omitFields = ["content", "enc_item_key", "auth_hash"];
|
||||
this.handleItemsResponse(response.saved_items, omitFields);
|
||||
|
||||
this.writeAllItemsToLocalStorage();
|
||||
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
}.bind(this)).catch(function (response) {
|
||||
console.log("Sync error: ", response);
|
||||
callback({ error: "Sync error" });
|
||||
if (callback) {
|
||||
callback({ error: "Sync error" });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -2202,7 +2172,7 @@ var User = function User(json_obj) {
|
||||
};
|
||||
|
||||
this.shareItem = function (item, callback) {
|
||||
if (!this.user.uuid) {
|
||||
if (!this.isUserSignedIn()) {
|
||||
alert("You must be signed in to share.");
|
||||
return;
|
||||
}
|
||||
@@ -2221,9 +2191,6 @@ var User = function User(json_obj) {
|
||||
template: 'frontend/modals/username.html',
|
||||
controller: 'UsernameModalCtrl',
|
||||
resolve: {
|
||||
user: function () {
|
||||
return this.user;
|
||||
}.bind(this),
|
||||
callback: function callback() {
|
||||
return shareFn;
|
||||
}
|
||||
@@ -2295,49 +2262,54 @@ var User = function User(json_obj) {
|
||||
/*
|
||||
Merging
|
||||
*/
|
||||
this.mergeLocalDataRemotely = function (user, callback) {
|
||||
var request = Restangular.one("users", user.uuid).one("merge");
|
||||
var tags = user.tags;
|
||||
request.items = user.items;
|
||||
request.items.forEach(function (item) {
|
||||
if (item.tag_id) {
|
||||
var tag = tags.filter(function (tag) {
|
||||
return tag.uuid == item.tag_id;
|
||||
})[0];
|
||||
item.tag_name = tag.title;
|
||||
}
|
||||
});
|
||||
request.post().then(function (response) {
|
||||
callback();
|
||||
localStorage.removeItem('user');
|
||||
});
|
||||
// this.mergeLocalDataRemotely = function(user, callback) {
|
||||
// var request = Restangular.one("users", this.userId()).one("merge");
|
||||
// var tags = user.tags;
|
||||
// request.items = user.items;
|
||||
// request.items.forEach(function(item){
|
||||
// if(item.tag_id) {
|
||||
// var tag = tags.filter(function(tag){return tag.uuid == item.tag_id})[0];
|
||||
// item.tag_name = tag.title;
|
||||
// }
|
||||
// })
|
||||
// request.post().then(function(response){
|
||||
// callback();
|
||||
// localStorage.removeItem('user');
|
||||
// })
|
||||
// }
|
||||
|
||||
|
||||
this.clearLocalStorage = function () {
|
||||
localStorage.removeItem("items");
|
||||
localStorage.removeItem("mk");
|
||||
localStorage.removeItem("jwt");
|
||||
localStorage.removeItem("uuid");
|
||||
localStorage.removeItem("syncToken");
|
||||
};
|
||||
|
||||
this.staticifyObject = function (object) {
|
||||
return JSON.parse(JSON.stringify(object));
|
||||
};
|
||||
|
||||
this.writeItemsToLocalStorage = function (callback) {
|
||||
this.writeAllItemsToLocalStorage = function (callback) {
|
||||
var items = _.map(modelManager.allItems, function (item) {
|
||||
return this.paramsForItem(item, false, ["created_at", "updated_at"], false);
|
||||
return this.paramsForItem(item, this.isUserSignedIn(), ["created_at", "updated_at"], false);
|
||||
}.bind(this));
|
||||
console.log("Writing items to local", items);
|
||||
// console.log("Writing items to local", items);
|
||||
this.writeToLocalStorage('items', items);
|
||||
callback(items);
|
||||
if (callback) {
|
||||
callback(items);
|
||||
}
|
||||
};
|
||||
|
||||
this.writeToLocalStorage = function (key, value) {
|
||||
localStorage.setItem(key, angular.toJson(value));
|
||||
};
|
||||
|
||||
this.loadLocalItemsAndUser = function () {
|
||||
var user = {};
|
||||
this.loadLocalItems = function () {
|
||||
var items = JSON.parse(localStorage.getItem('items')) || [];
|
||||
items = this.handleItemsResponse(items, null);
|
||||
Item.sortItemsByDate(items);
|
||||
user.items = items;
|
||||
user.shouldMerge = true;
|
||||
return user;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -2456,7 +2428,7 @@ var User = function User(json_obj) {
|
||||
};
|
||||
|
||||
this.reencryptAllItemsAndSave = function (user, newMasterKey, oldMasterKey, callback) {
|
||||
var items = user.filteredItems();
|
||||
var items = modelManager.allItems();
|
||||
items.forEach(function (item) {
|
||||
if (item.content.substring(0, 3) == "001" && item.enc_item_key) {
|
||||
// first decrypt item_key with old key
|
||||
|
||||
2
vendor/assets/javascripts/transpiled.js.map
vendored
2
vendor/assets/javascripts/transpiled.js.map
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user