1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-22 11:13:46 +00:00

History of generated passwords (#310)

* Save last 5 passwords.

* Move password history to seperate page.

* Use the util helpers for accessing the local storage.

* Change close to back for password history. Remove unused html.

* Change orderBy to use the date instead of magic array.

* Move historyService to background.

* Add passwords generated from shortcut and contextmenu to history.

* Fix return to edit/add not working in password generator history.

* Change password icon to clipboard.

* Change link to password history to use on-click.

* Clear password generator history on logout.

* Code style fix.

* Add new .wrap class for wrapping long text. Fix password icon.
This commit is contained in:
Oscar Hinton
2017-10-17 22:42:05 +02:00
committed by Kyle Spearrin
parent 358fb9b277
commit f1262147a3
11 changed files with 186 additions and 5 deletions

View File

@@ -9,6 +9,7 @@ function ConstantsService(i18nService) {
enableAutoFillOnPageLoadKey: 'enableAutoFillOnPageLoad',
lockOptionKey: 'lockOption',
lastActiveKey: 'lastActive',
generatedPasswordHistory: 'generatedPasswordHistory',
encType: {
AesCbc256_B64: 0,
AesCbc128_HmacSha256_B64: 1,

View File

@@ -1,10 +1,14 @@
function PasswordGenerationService() {
function PasswordGenerationService(constantsService, utilsService, cryptoService) {
this.optionsCache = null;
this.constantsService = constantsService;
this.utilsService = utilsService;
this.cryptoService = cryptoService;
this.history = [];
initPasswordGenerationService();
initPasswordGenerationService(this);
}
function initPasswordGenerationService() {
function initPasswordGenerationService(self) {
var optionsKey = 'passwordGenerationOptions';
var defaultOptions = {
length: 10,
@@ -181,4 +185,85 @@ function initPasswordGenerationService() {
return deferred.promise;
};
// History
var key = self.constantsService.generatedPasswordHistory;
var MAX_PASSWORDS_IN_HISTORY = 10;
self.utilsService
.getObjFromStorage(key)
.then(function(encrypted) {
return decrypt(encrypted);
}).then(function(history) {
history.forEach(function(item) {
self.history.push(item);
});
});
PasswordGenerationService.prototype.getHistory = function () {
return self.history;
};
PasswordGenerationService.prototype.addHistory = function (password) {
// Prevent duplicates
if (matchesPrevious(password)) {
return;
}
self.history.push({
password: password,
date: Date.now()
});
// Remove old items.
if (self.history.length > MAX_PASSWORDS_IN_HISTORY) {
self.history.shift();
}
save();
};
PasswordGenerationService.prototype.clear = function () {
self.history = [];
self.utilsService.removeFromStorage(key);
};
function save() {
return encryptHistory()
.then(function(history) {
return self.utilsService.saveObjToStorage(key, history);
});
}
function encryptHistory() {
var promises = self.history.map(function(historyItem) {
return self.cryptoService.encrypt(historyItem.password).then(function(encrypted) {
return {
password: encrypted.encryptedString,
date: historyItem.date
};
});
});
return Q.all(promises);
}
function decrypt(history) {
var promises = history.map(function(item) {
return self.cryptoService.decrypt(new CipherString(item.password)).then(function(decrypted) {
return {
password: decrypted,
date: item.date
};
});
});
return Q.all(promises);
}
function matchesPrevious(password) {
var len = self.history.length;
return len !== 0 && self.history[len-1].password === password;
}
}