mirror of
https://github.com/bitwarden/browser
synced 2025-12-18 09:13:33 +00:00
Added export vault function to tools.
This commit is contained in:
@@ -141,6 +141,13 @@
|
||||
data: { authorize: true },
|
||||
params: { animation: null, addState: null, editState: null }
|
||||
})
|
||||
.state('export', {
|
||||
url: '/export',
|
||||
templateUrl: 'app/tools/views/toolsExport.html',
|
||||
controller: 'toolsExportController',
|
||||
data: { authorize: true },
|
||||
params: { animation: null }
|
||||
})
|
||||
|
||||
.state('about', {
|
||||
url: '/about',
|
||||
|
||||
116
src/popup/app/tools/toolsExportController.js
Normal file
116
src/popup/app/tools/toolsExportController.js
Normal file
@@ -0,0 +1,116 @@
|
||||
angular
|
||||
.module('bit.tools')
|
||||
|
||||
.controller('toolsExportController', function ($scope, $state, toastr, $q, $analytics,
|
||||
i18nService, cryptoService, userService, folderService, loginService) {
|
||||
$scope.i18n = i18nService;
|
||||
|
||||
$scope.submitPromise = null;
|
||||
$scope.submit = function () {
|
||||
$scope.submitPromise = checkPassword().then(function () {
|
||||
return getCsv();
|
||||
}).then(function (csv) {
|
||||
downloadFile(csv);
|
||||
}, function () {
|
||||
toastr.error(i18nService.invalidMasterPassword, i18nService.errorsOccurred);
|
||||
});
|
||||
};
|
||||
|
||||
function checkPassword() {
|
||||
var deferred = $q.defer();
|
||||
|
||||
userService.getEmail(function (email) {
|
||||
var key = cryptoService.makeKey($scope.masterPassword, email);
|
||||
cryptoService.hashPassword($scope.masterPassword, key, function (keyHash) {
|
||||
cryptoService.getKeyHash(true, function (storedKeyHash) {
|
||||
if (storedKeyHash && keyHash && storedKeyHash === keyHash) {
|
||||
deferred.resolve();
|
||||
}
|
||||
else {
|
||||
deferred.reject();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function getCsv() {
|
||||
var deferred = $q.defer();
|
||||
var decFolders = [];
|
||||
var decLogins = [];
|
||||
var promises = [];
|
||||
|
||||
var folderPromise = $q.when(folderService.getAllDecrypted());
|
||||
folderPromise.then(function (folders) {
|
||||
decFolders = folders;
|
||||
});
|
||||
promises.push(folderPromise);
|
||||
|
||||
var loginPromise = $q.when(loginService.getAllDecrypted());
|
||||
loginPromise.then(function (logins) {
|
||||
decLogins = logins;
|
||||
});
|
||||
promises.push(loginPromise);
|
||||
|
||||
$q.all(promises).then(function () {
|
||||
var exportLogins = [];
|
||||
for (var i = 0; i < decLogins.length; i++) {
|
||||
var login = {
|
||||
name: decLogins[i].name,
|
||||
uri: decLogins[i].uri,
|
||||
username: decLogins[i].username,
|
||||
password: decLogins[i].password,
|
||||
notes: decLogins[i].notes,
|
||||
folder: null
|
||||
};
|
||||
|
||||
for (var j = 0; j < decFolders.length; j++) {
|
||||
if (decFolders[j].id === decLogins[i].folderId && decFolders[j].name !== i18nService.noneFolder) {
|
||||
login.folder = decFolders[j].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
exportLogins.push(login);
|
||||
}
|
||||
|
||||
var csv = Papa.unparse(exportLogins);
|
||||
deferred.resolve(csv);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function downloadFile(csvString) {
|
||||
var csvBlob = new Blob([csvString]);
|
||||
if (window.navigator.msSaveOrOpenBlob) {
|
||||
window.navigator.msSaveBlob(csvBlob, makeFileName());
|
||||
}
|
||||
else {
|
||||
var a = window.document.createElement('a');
|
||||
a.href = window.URL.createObjectURL(csvBlob, { type: 'text/plain' });
|
||||
a.download = makeFileName();
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
}
|
||||
}
|
||||
|
||||
function makeFileName() {
|
||||
var now = new Date();
|
||||
var dateString =
|
||||
now.getFullYear() + '' + padNumber(now.getMonth() + 1, 2) + '' + padNumber(now.getDate(), 2) +
|
||||
padNumber(now.getHours(), 2) + '' + padNumber(now.getMinutes(), 2) +
|
||||
padNumber(now.getSeconds(), 2);
|
||||
|
||||
return 'bitwarden_export_' + dateString + '.csv';
|
||||
}
|
||||
|
||||
function padNumber(number, width, paddingCharacter) {
|
||||
paddingCharacter = paddingCharacter || '0';
|
||||
number = number + '';
|
||||
return number.length >= width ? number : new Array(width - number.length + 1).join(paddingCharacter) + number;
|
||||
}
|
||||
});
|
||||
@@ -30,6 +30,11 @@
|
||||
<span class="text">{{i18n.importLogins}}</span>
|
||||
<span class="detail">{{i18n.importLoginsInfo}}</span>
|
||||
</a>
|
||||
<a class="list-section-item wrap" href="" ui-sref="export({animation: 'in-slide-up'})">
|
||||
<span class="leading-icon" style="color: #ff6f6f;"><i class="fa fa-cloud-download fa-fw"></i></span>
|
||||
<span class="text">{{i18n.exportVault}}</span>
|
||||
<span class="detail">{{i18n.exportVaultInfo}}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
29
src/popup/app/tools/views/toolsExport.html
Normal file
29
src/popup/app/tools/views/toolsExport.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<form name="theForm" ng-submit="submit()" bit-form="submitPromise">
|
||||
<div class="header">
|
||||
<div class="left">
|
||||
<a ui-sref="tabs.tools({animation: 'out-slide-down'})">{{i18n.close}}</a>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button type="submit" class="btn btn-link">{{i18n.submit}}</button>
|
||||
</div>
|
||||
<div class="title">{{i18n.exportVault}}</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="list">
|
||||
<div class="list-section">
|
||||
<div class="list-section-items">
|
||||
<div class="list-section-item list-section-item-icon-input">
|
||||
<i class="fa fa-lock fa-lg fa-fw"></i>
|
||||
<label for="master-password" class="sr-only">{{i18n.masterPass}}</label>
|
||||
<input id="master-password" type="password" name="MasterPassword" placeholder="{{i18n.masterPass}}"
|
||||
ng-model="masterPassword">
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-section-footer">
|
||||
<p>{{i18n.exportMasterPassword}}</p>
|
||||
<b>{{i18n.warning}}</b>: {{i18n.exportWarning}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
<script src="../lib/jquery/jquery.js"></script>
|
||||
<script src="../lib/bootstrap/js/bootstrap.js"></script>
|
||||
<script src="../lib/papaparse/papaparse.js"></script>
|
||||
<script src="../lib/clipboard/clipboard.js"></script>
|
||||
<script src="../scripts/analytics.js"></script>
|
||||
|
||||
@@ -82,6 +83,7 @@
|
||||
<script src="app/tools/toolsModule.js"></script>
|
||||
<script src="app/tools/toolsController.js"></script>
|
||||
<script src="app/tools/toolsPasswordGeneratorController.js"></script>
|
||||
<script src="app/tools/toolsExportController.js"></script>
|
||||
|
||||
<script src="app/lock/lockModule.js"></script>
|
||||
<script src="app/lock/lockController.js"></script>
|
||||
|
||||
Reference in New Issue
Block a user