1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 08:13:42 +00:00

lazy load history

This commit is contained in:
Kyle Spearrin
2018-01-19 14:58:06 -05:00
parent 8636033159
commit e753becd33
2 changed files with 34 additions and 22 deletions

View File

@@ -6,7 +6,7 @@ export interface PasswordGenerationService {
generatePassword(options: any): string; generatePassword(options: any): string;
getOptions(): any; getOptions(): any;
saveOptions(options: any): Promise<any>; saveOptions(options: any): Promise<any>;
getHistory(): PasswordHistory[]; getHistory(): Promise<PasswordHistory[]>;
addHistory(password: string): Promise<any>; addHistory(password: string): Promise<any>;
clear(): Promise<any>; clear(): Promise<any>;
} }

View File

@@ -150,13 +150,7 @@ export class PasswordGenerationService implements PasswordGenerationServiceInter
optionsCache: any; optionsCache: any;
history: PasswordHistory[] = []; history: PasswordHistory[] = [];
constructor(private cryptoService: CryptoService, constructor(private cryptoService: CryptoService, private storageService: StorageService) {
private storageService: StorageService) {
storageService.get<PasswordHistory[]>(Keys.history).then((encrypted) => {
return this.decryptHistory(encrypted);
}).then((history) => {
this.history = history;
});
} }
generatePassword(options: any) { generatePassword(options: any) {
@@ -181,24 +175,42 @@ export class PasswordGenerationService implements PasswordGenerationServiceInter
this.optionsCache = options; this.optionsCache = options;
} }
getHistory() { async getHistory(): Promise<PasswordHistory[]> {
const hasKey = (await this.cryptoService.getKey()) != null;
if (!hasKey) {
return new Array<PasswordHistory>();
}
if (!this.history) {
const encrypted = await this.storageService.get<PasswordHistory[]>(Keys.history);
this.history = await this.decryptHistory(encrypted);
}
return this.history || new Array<PasswordHistory>(); return this.history || new Array<PasswordHistory>();
} }
async addHistory(password: string): Promise<any> { async addHistory(password: string): Promise<any> {
// Prevent duplicates // Cannot add new history if no key is available
if (this.matchesPrevious(password)) { const hasKey = (await this.cryptoService.getKey()) != null;
if (!hasKey) {
return; return;
} }
this.history.push(new PasswordHistory(password, Date.now())); const currentHistory = await this.getHistory();
// Remove old items. // Prevent duplicates
if (this.history.length > MaxPasswordsInHistory) { if (this.matchesPrevious(password, currentHistory)) {
this.history.shift(); return;
} }
const newHistory = await this.encryptHistory(); currentHistory.push(new PasswordHistory(password, Date.now()));
// Remove old items.
if (currentHistory.length > MaxPasswordsInHistory) {
currentHistory.shift();
}
const newHistory = await this.encryptHistory(currentHistory);
return await this.storageService.save(Keys.history, newHistory); return await this.storageService.save(Keys.history, newHistory);
} }
@@ -207,12 +219,12 @@ export class PasswordGenerationService implements PasswordGenerationServiceInter
return await this.storageService.remove(Keys.history); return await this.storageService.remove(Keys.history);
} }
private async encryptHistory(): Promise<PasswordHistory[]> { private async encryptHistory(history: PasswordHistory[]): Promise<PasswordHistory[]> {
if (this.history == null || this.history.length === 0) { if (history == null || history.length === 0) {
return Promise.resolve([]); return Promise.resolve([]);
} }
const promises = this.history.map(async (item) => { const promises = history.map(async (item) => {
const encrypted = await this.cryptoService.encrypt(item.password); const encrypted = await this.cryptoService.encrypt(item.password);
return new PasswordHistory(encrypted.encryptedString, item.date); return new PasswordHistory(encrypted.encryptedString, item.date);
}); });
@@ -233,11 +245,11 @@ export class PasswordGenerationService implements PasswordGenerationServiceInter
return await Promise.all(promises); return await Promise.all(promises);
} }
private matchesPrevious(password: string): boolean { private matchesPrevious(password: string, history: PasswordHistory[]): boolean {
if (this.history == null || this.history.length === 0) { if (history == null || history.length === 0) {
return false; return false;
} }
return this.history[this.history.length - 1].password === password; return history[history.length - 1].password === password;
} }
} }