import require password
This commit is contained in:
@@ -193,19 +193,39 @@ angular.module('app.frontend')
|
|||||||
link.click();
|
link.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.performImport = function(data, password) {
|
||||||
|
apiController.importJSONData(data, password, function(success, response){
|
||||||
|
console.log("import response", success, response);
|
||||||
|
if(success) {
|
||||||
|
this.importData = null;
|
||||||
|
} else {
|
||||||
|
alert("There was an error importing your data. Please try again.");
|
||||||
|
}
|
||||||
|
}.bind(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
this.submitImportPassword = function() {
|
||||||
|
this.performImport(this.importData.data, this.importData.password);
|
||||||
|
}
|
||||||
|
|
||||||
this.importFileSelected = function(files) {
|
this.importFileSelected = function(files) {
|
||||||
|
this.importData = {};
|
||||||
|
|
||||||
var file = files[0];
|
var file = files[0];
|
||||||
var reader = new FileReader();
|
var reader = new FileReader();
|
||||||
reader.onload = function(e) {
|
reader.onload = function(e) {
|
||||||
apiController.importJSONData(e.target.result, function(success, response){
|
var data = JSON.parse(e.target.result);
|
||||||
console.log("import response", success, response);
|
$timeout(function(){
|
||||||
if(success) {
|
if(data.auth_params) {
|
||||||
// window.location.reload();
|
// request password
|
||||||
|
this.importData.requestPassword = true;
|
||||||
|
this.importData.data = data;
|
||||||
} else {
|
} else {
|
||||||
alert("There was an error importing your data. Please try again.");
|
this.performImport(data, null);
|
||||||
}
|
}
|
||||||
})
|
}.bind(this))
|
||||||
}
|
}.bind(this)
|
||||||
|
|
||||||
reader.readAsText(file);
|
reader.readAsText(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,10 @@ angular.module('app.frontend')
|
|||||||
Auth
|
Auth
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
this.getAuthParams = function() {
|
||||||
|
return JSON.parse(localStorage.getItem("auth_params"));
|
||||||
|
}
|
||||||
|
|
||||||
this.isUserSignedIn = function() {
|
this.isUserSignedIn = function() {
|
||||||
return localStorage.getItem("jwt");
|
return localStorage.getItem("jwt");
|
||||||
}
|
}
|
||||||
@@ -97,7 +101,7 @@ angular.module('app.frontend')
|
|||||||
callback(null);
|
callback(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Neeto.crypto.computeEncryptionKeysForUser(_.merge({email: email, password: password}, authParams), function(keys){
|
Neeto.crypto.computeEncryptionKeysForUser(_.merge({password: password}, authParams), function(keys){
|
||||||
this.setMk(keys.mk);
|
this.setMk(keys.mk);
|
||||||
var request = Restangular.one("auth/sign_in");
|
var request = Restangular.one("auth/sign_in");
|
||||||
var params = {password: keys.pw, email: email};
|
var params = {password: keys.pw, email: email};
|
||||||
@@ -105,6 +109,7 @@ angular.module('app.frontend')
|
|||||||
request.post().then(function(response){
|
request.post().then(function(response){
|
||||||
localStorage.setItem("jwt", response.token);
|
localStorage.setItem("jwt", response.token);
|
||||||
localStorage.setItem("uuid", response.uuid);
|
localStorage.setItem("uuid", response.uuid);
|
||||||
|
localStorage.setItem("auth_params", JSON.stringify(authParams));
|
||||||
callback(response);
|
callback(response);
|
||||||
})
|
})
|
||||||
.catch(function(response){
|
.catch(function(response){
|
||||||
@@ -124,6 +129,7 @@ angular.module('app.frontend')
|
|||||||
request.post().then(function(response){
|
request.post().then(function(response){
|
||||||
localStorage.setItem("jwt", response.token);
|
localStorage.setItem("jwt", response.token);
|
||||||
localStorage.setItem("uuid", response.uuid);
|
localStorage.setItem("uuid", response.uuid);
|
||||||
|
localStorage.setItem("auth_params", JSON.stringify(authParams));
|
||||||
callback(response);
|
callback(response);
|
||||||
})
|
})
|
||||||
.catch(function(response){
|
.catch(function(response){
|
||||||
@@ -352,15 +358,34 @@ angular.module('app.frontend')
|
|||||||
Import
|
Import
|
||||||
*/
|
*/
|
||||||
|
|
||||||
this.importJSONData = function(jsonString, callback) {
|
this.importJSONData = function(data, password, callback) {
|
||||||
var data = JSON.parse(jsonString);
|
console.log("Importing data", data);
|
||||||
console.log("importing data", data);
|
|
||||||
this.decryptItems(data.items);
|
var onDataReady = function() {
|
||||||
modelManager.mapResponseItemsToLocalModels(data.items);
|
modelManager.mapResponseItemsToLocalModels(data.items);
|
||||||
modelManager.allItems.forEach(function(item){
|
modelManager.allItems.forEach(function(item){
|
||||||
item.setDirty(true);
|
item.setDirty(true);
|
||||||
})
|
})
|
||||||
this.syncWithOptions(callback, {additionalFields: ["created_at", "updated_at"]});
|
this.syncWithOptions(callback, {additionalFields: ["created_at", "updated_at"]});
|
||||||
|
}.bind(this)
|
||||||
|
|
||||||
|
if(data.auth_params) {
|
||||||
|
Neeto.crypto.computeEncryptionKeysForUser(_.merge({password: password}, data.auth_params), function(keys){
|
||||||
|
var mk = keys.mk;
|
||||||
|
try {
|
||||||
|
this.decryptItemsWithKey(data.items, mk);
|
||||||
|
onDataReady();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.log("Error decrypting", e);
|
||||||
|
alert("There was an error decrypting your items. Make sure the password you entered is correct and try again.");
|
||||||
|
callback(false, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
} else {
|
||||||
|
onDataReady();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -392,6 +417,10 @@ angular.module('app.frontend')
|
|||||||
items: items
|
items: items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(encrypted) {
|
||||||
|
data["auth_params"] = this.getAuthParams();
|
||||||
|
}
|
||||||
|
|
||||||
return makeTextFile(JSON.stringify(data, null, 2 /* pretty print */));
|
return makeTextFile(JSON.stringify(data, null, 2 /* pretty print */));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -530,6 +559,10 @@ angular.module('app.frontend')
|
|||||||
|
|
||||||
this.decryptItems = function(items) {
|
this.decryptItems = function(items) {
|
||||||
var masterKey = this.retrieveMk();
|
var masterKey = this.retrieveMk();
|
||||||
|
this.decryptItemsWithKey(items, masterKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.decryptItemsWithKey = function(items, key) {
|
||||||
for (var item of items) {
|
for (var item of items) {
|
||||||
if(item.deleted == true) {
|
if(item.deleted == true) {
|
||||||
continue;
|
continue;
|
||||||
@@ -538,7 +571,7 @@ angular.module('app.frontend')
|
|||||||
if(isString) {
|
if(isString) {
|
||||||
if(item.content.substring(0, 3) == "001" && item.enc_item_key) {
|
if(item.content.substring(0, 3) == "001" && item.enc_item_key) {
|
||||||
// is encrypted
|
// is encrypted
|
||||||
this.decryptSingleItem(item, masterKey);
|
this.decryptSingleItem(item, key);
|
||||||
} else {
|
} else {
|
||||||
// is base64 encoded
|
// is base64 encoded
|
||||||
item.content = Neeto.crypto.base64Decode(item.content.substring(3, item.content.length))
|
item.content = Neeto.crypto.base64Decode(item.content.substring(3, item.content.length))
|
||||||
|
|||||||
@@ -255,6 +255,9 @@ class ExtensionManager {
|
|||||||
|
|
||||||
performPost(action, extension, params, callback) {
|
performPost(action, extension, params, callback) {
|
||||||
var request = this.Restangular.oneUrl(action.url, action.url);
|
var request = this.Restangular.oneUrl(action.url, action.url);
|
||||||
|
if(this.extensionUsesEncryptedData(extension)) {
|
||||||
|
request.auth_params = this.apiController.getAuthParams();
|
||||||
|
}
|
||||||
_.merge(request, params);
|
_.merge(request, params);
|
||||||
|
|
||||||
request.post().then(function(response){
|
request.post().then(function(response){
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ class SNCrypto {
|
|||||||
return CryptoJS.HmacSHA256(messageData, keyData).toString();
|
return CryptoJS.HmacSHA256(messageData, keyData).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
computeEncryptionKeysForUser({email, password, pw_salt, pw_func, pw_alg, pw_cost, pw_key_size} = {}, callback) {
|
computeEncryptionKeysForUser({password, pw_salt, pw_func, pw_alg, pw_cost, pw_key_size} = {}, callback) {
|
||||||
this.generateSymmetricKeyPair({password: password, pw_salt: pw_salt,
|
this.generateSymmetricKeyPair({password: password, pw_salt: pw_salt,
|
||||||
pw_func: pw_func, pw_alg: pw_alg, pw_cost: pw_cost, pw_key_size: pw_key_size}, function(keys){
|
pw_func: pw_func, pw_alg: pw_alg, pw_cost: pw_cost, pw_key_size: pw_key_size}, function(keys){
|
||||||
var pw = keys[0];
|
var pw = keys[0];
|
||||||
@@ -99,7 +99,7 @@ class SNCrypto {
|
|||||||
var pw = keys[0];
|
var pw = keys[0];
|
||||||
var mk = keys[1];
|
var mk = keys[1];
|
||||||
|
|
||||||
callback(_.merge({pw: pw, mk: mk, pw_nonce: pw_nonce}, defaults));
|
callback({pw: pw, mk: mk, pw_nonce: pw_nonce}, defaults);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,7 +129,7 @@
|
|||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
a {
|
a {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #00228f;
|
color: $blue-color;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
margin-bottom: 34px;
|
margin-bottom: 34px;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #00228f;
|
color: $blue-color;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@@ -186,6 +186,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.import-password {
|
||||||
|
margin-top: 14px;
|
||||||
|
|
||||||
|
> .field {
|
||||||
|
display: block;
|
||||||
|
margin: 5px 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.encryption-confirmation {
|
.encryption-confirmation {
|
||||||
position: relative;
|
position: relative;
|
||||||
.buttons {
|
.buttons {
|
||||||
|
|||||||
@@ -90,6 +90,10 @@
|
|||||||
%a.disabled
|
%a.disabled
|
||||||
%span
|
%span
|
||||||
Import Data from Archive
|
Import Data from Archive
|
||||||
|
.import-password{"ng-if" => "ctrl.importData.requestPassword"}
|
||||||
|
Enter the account password associated with the import file.
|
||||||
|
%input.field{"type" => "text", "ng-model" => "ctrl.importData.password"}
|
||||||
|
%button{"ng-click" => "ctrl.submitImportPassword()"} Decrypt & Import
|
||||||
|
|
||||||
.item
|
.item
|
||||||
%a{"ng-click" => "ctrl.toggleExtensions()"} Extensions
|
%a{"ng-click" => "ctrl.toggleExtensions()"} Extensions
|
||||||
|
|||||||
94
vendor/assets/javascripts/transpiled.js
vendored
94
vendor/assets/javascripts/transpiled.js
vendored
@@ -118,7 +118,6 @@ var SNCrypto = function () {
|
|||||||
key: 'computeEncryptionKeysForUser',
|
key: 'computeEncryptionKeysForUser',
|
||||||
value: function computeEncryptionKeysForUser() {
|
value: function computeEncryptionKeysForUser() {
|
||||||
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
||||||
email = _ref.email,
|
|
||||||
password = _ref.password,
|
password = _ref.password,
|
||||||
pw_salt = _ref.pw_salt,
|
pw_salt = _ref.pw_salt,
|
||||||
pw_func = _ref.pw_func,
|
pw_func = _ref.pw_func,
|
||||||
@@ -157,7 +156,7 @@ var SNCrypto = function () {
|
|||||||
var pw = keys[0];
|
var pw = keys[0];
|
||||||
var mk = keys[1];
|
var mk = keys[1];
|
||||||
|
|
||||||
callback(_.merge({ pw: pw, mk: mk, pw_nonce: pw_nonce }, defaults));
|
callback({ pw: pw, mk: mk, pw_nonce: pw_nonce }, defaults);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
@@ -903,19 +902,39 @@ angular.module('app.frontend').controller('BaseCtrl', BaseCtrl);
|
|||||||
link.click();
|
link.click();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.performImport = function (data, password) {
|
||||||
|
apiController.importJSONData(data, password, function (success, response) {
|
||||||
|
console.log("import response", success, response);
|
||||||
|
if (success) {
|
||||||
|
this.importData = null;
|
||||||
|
} else {
|
||||||
|
alert("There was an error importing your data. Please try again.");
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
this.submitImportPassword = function () {
|
||||||
|
this.performImport(this.importData.data, this.importData.password);
|
||||||
|
};
|
||||||
|
|
||||||
this.importFileSelected = function (files) {
|
this.importFileSelected = function (files) {
|
||||||
|
this.importData = {};
|
||||||
|
|
||||||
var file = files[0];
|
var file = files[0];
|
||||||
var reader = new FileReader();
|
var reader = new FileReader();
|
||||||
reader.onload = function (e) {
|
reader.onload = function (e) {
|
||||||
apiController.importJSONData(e.target.result, function (success, response) {
|
var data = JSON.parse(e.target.result);
|
||||||
console.log("import response", success, response);
|
$timeout(function () {
|
||||||
if (success) {
|
if (data.auth_params) {
|
||||||
// window.location.reload();
|
// request password
|
||||||
|
this.importData.requestPassword = true;
|
||||||
|
this.importData.data = data;
|
||||||
} else {
|
} else {
|
||||||
alert("There was an error importing your data. Please try again.");
|
this.performImport(data, null);
|
||||||
}
|
}
|
||||||
});
|
}.bind(this));
|
||||||
};
|
}.bind(this);
|
||||||
|
|
||||||
reader.readAsText(file);
|
reader.readAsText(file);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1926,6 +1945,10 @@ var Tag = function (_Item3) {
|
|||||||
Auth
|
Auth
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
this.getAuthParams = function () {
|
||||||
|
return JSON.parse(localStorage.getItem("auth_params"));
|
||||||
|
};
|
||||||
|
|
||||||
this.isUserSignedIn = function () {
|
this.isUserSignedIn = function () {
|
||||||
return localStorage.getItem("jwt");
|
return localStorage.getItem("jwt");
|
||||||
};
|
};
|
||||||
@@ -1965,7 +1988,7 @@ var Tag = function (_Item3) {
|
|||||||
callback(null);
|
callback(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Neeto.crypto.computeEncryptionKeysForUser(_.merge({ email: email, password: password }, authParams), function (keys) {
|
Neeto.crypto.computeEncryptionKeysForUser(_.merge({ password: password }, authParams), function (keys) {
|
||||||
this.setMk(keys.mk);
|
this.setMk(keys.mk);
|
||||||
var request = Restangular.one("auth/sign_in");
|
var request = Restangular.one("auth/sign_in");
|
||||||
var params = { password: keys.pw, email: email };
|
var params = { password: keys.pw, email: email };
|
||||||
@@ -1973,6 +1996,7 @@ var Tag = function (_Item3) {
|
|||||||
request.post().then(function (response) {
|
request.post().then(function (response) {
|
||||||
localStorage.setItem("jwt", response.token);
|
localStorage.setItem("jwt", response.token);
|
||||||
localStorage.setItem("uuid", response.uuid);
|
localStorage.setItem("uuid", response.uuid);
|
||||||
|
localStorage.setItem("auth_params", JSON.stringify(authParams));
|
||||||
callback(response);
|
callback(response);
|
||||||
}).catch(function (response) {
|
}).catch(function (response) {
|
||||||
callback(response.data);
|
callback(response.data);
|
||||||
@@ -1991,6 +2015,7 @@ var Tag = function (_Item3) {
|
|||||||
request.post().then(function (response) {
|
request.post().then(function (response) {
|
||||||
localStorage.setItem("jwt", response.token);
|
localStorage.setItem("jwt", response.token);
|
||||||
localStorage.setItem("uuid", response.uuid);
|
localStorage.setItem("uuid", response.uuid);
|
||||||
|
localStorage.setItem("auth_params", JSON.stringify(authParams));
|
||||||
callback(response);
|
callback(response);
|
||||||
}).catch(function (response) {
|
}).catch(function (response) {
|
||||||
callback(response.data);
|
callback(response.data);
|
||||||
@@ -2216,15 +2241,33 @@ var Tag = function (_Item3) {
|
|||||||
Import
|
Import
|
||||||
*/
|
*/
|
||||||
|
|
||||||
this.importJSONData = function (jsonString, callback) {
|
this.importJSONData = function (data, password, callback) {
|
||||||
var data = JSON.parse(jsonString);
|
console.log("Importing data", data);
|
||||||
console.log("importing data", data);
|
|
||||||
this.decryptItems(data.items);
|
var onDataReady = function () {
|
||||||
modelManager.mapResponseItemsToLocalModels(data.items);
|
modelManager.mapResponseItemsToLocalModels(data.items);
|
||||||
modelManager.allItems.forEach(function (item) {
|
modelManager.allItems.forEach(function (item) {
|
||||||
item.setDirty(true);
|
item.setDirty(true);
|
||||||
});
|
});
|
||||||
this.syncWithOptions(callback, { additionalFields: ["created_at", "updated_at"] });
|
this.syncWithOptions(callback, { additionalFields: ["created_at", "updated_at"] });
|
||||||
|
}.bind(this);
|
||||||
|
|
||||||
|
if (data.auth_params) {
|
||||||
|
Neeto.crypto.computeEncryptionKeysForUser(_.merge({ password: password }, data.auth_params), function (keys) {
|
||||||
|
var mk = keys.mk;
|
||||||
|
try {
|
||||||
|
this.decryptItemsWithKey(data.items, mk);
|
||||||
|
onDataReady();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Error decrypting", e);
|
||||||
|
alert("There was an error decrypting your items. Make sure the password you entered is correct and try again.");
|
||||||
|
callback(false, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
} else {
|
||||||
|
onDataReady();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2256,6 +2299,10 @@ var Tag = function (_Item3) {
|
|||||||
items: items
|
items: items
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (encrypted) {
|
||||||
|
data["auth_params"] = this.getAuthParams();
|
||||||
|
}
|
||||||
|
|
||||||
return makeTextFile(JSON.stringify(data, null, 2 /* pretty print */));
|
return makeTextFile(JSON.stringify(data, null, 2 /* pretty print */));
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2389,6 +2436,10 @@ var Tag = function (_Item3) {
|
|||||||
|
|
||||||
this.decryptItems = function (items) {
|
this.decryptItems = function (items) {
|
||||||
var masterKey = this.retrieveMk();
|
var masterKey = this.retrieveMk();
|
||||||
|
this.decryptItemsWithKey(items, masterKey);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.decryptItemsWithKey = function (items, key) {
|
||||||
var _iteratorNormalCompletion4 = true;
|
var _iteratorNormalCompletion4 = true;
|
||||||
var _didIteratorError4 = false;
|
var _didIteratorError4 = false;
|
||||||
var _iteratorError4 = undefined;
|
var _iteratorError4 = undefined;
|
||||||
@@ -2404,7 +2455,7 @@ var Tag = function (_Item3) {
|
|||||||
if (isString) {
|
if (isString) {
|
||||||
if (item.content.substring(0, 3) == "001" && item.enc_item_key) {
|
if (item.content.substring(0, 3) == "001" && item.enc_item_key) {
|
||||||
// is encrypted
|
// is encrypted
|
||||||
this.decryptSingleItem(item, masterKey);
|
this.decryptSingleItem(item, key);
|
||||||
} else {
|
} else {
|
||||||
// is base64 encoded
|
// is base64 encoded
|
||||||
item.content = Neeto.crypto.base64Decode(item.content.substring(3, item.content.length));
|
item.content = Neeto.crypto.base64Decode(item.content.substring(3, item.content.length));
|
||||||
@@ -3218,6 +3269,9 @@ var ExtensionManager = function () {
|
|||||||
key: 'performPost',
|
key: 'performPost',
|
||||||
value: function performPost(action, extension, params, callback) {
|
value: function performPost(action, extension, params, callback) {
|
||||||
var request = this.Restangular.oneUrl(action.url, action.url);
|
var request = this.Restangular.oneUrl(action.url, action.url);
|
||||||
|
if (this.extensionUsesEncryptedData(extension)) {
|
||||||
|
request.auth_params = this.apiController.getAuthParams();
|
||||||
|
}
|
||||||
_.merge(request, params);
|
_.merge(request, params);
|
||||||
|
|
||||||
request.post().then(function (response) {
|
request.post().then(function (response) {
|
||||||
|
|||||||
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