diff --git a/src/abstractions/passwordGeneration.service.ts b/src/abstractions/passwordGeneration.service.ts index 1f2433842b..1531eb176b 100644 --- a/src/abstractions/passwordGeneration.service.ts +++ b/src/abstractions/passwordGeneration.service.ts @@ -6,7 +6,7 @@ export interface PasswordGenerationService { generatePassword(options: any): string; getOptions(): any; saveOptions(options: any): Promise; - getHistory(): PasswordHistory[]; + getHistory(): Promise; addHistory(password: string): Promise; clear(): Promise; } diff --git a/src/services/passwordGeneration.service.ts b/src/services/passwordGeneration.service.ts index 771494d0bc..403bb104e2 100644 --- a/src/services/passwordGeneration.service.ts +++ b/src/services/passwordGeneration.service.ts @@ -150,13 +150,7 @@ export class PasswordGenerationService implements PasswordGenerationServiceInter optionsCache: any; history: PasswordHistory[] = []; - constructor(private cryptoService: CryptoService, - private storageService: StorageService) { - storageService.get(Keys.history).then((encrypted) => { - return this.decryptHistory(encrypted); - }).then((history) => { - this.history = history; - }); + constructor(private cryptoService: CryptoService, private storageService: StorageService) { } generatePassword(options: any) { @@ -181,24 +175,42 @@ export class PasswordGenerationService implements PasswordGenerationServiceInter this.optionsCache = options; } - getHistory() { + async getHistory(): Promise { + const hasKey = (await this.cryptoService.getKey()) != null; + if (!hasKey) { + return new Array(); + } + + if (!this.history) { + const encrypted = await this.storageService.get(Keys.history); + this.history = await this.decryptHistory(encrypted); + } + return this.history || new Array(); } async addHistory(password: string): Promise { - // Prevent duplicates - if (this.matchesPrevious(password)) { + // Cannot add new history if no key is available + const hasKey = (await this.cryptoService.getKey()) != null; + if (!hasKey) { return; } - this.history.push(new PasswordHistory(password, Date.now())); + const currentHistory = await this.getHistory(); - // Remove old items. - if (this.history.length > MaxPasswordsInHistory) { - this.history.shift(); + // Prevent duplicates + if (this.matchesPrevious(password, currentHistory)) { + 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); } @@ -207,12 +219,12 @@ export class PasswordGenerationService implements PasswordGenerationServiceInter return await this.storageService.remove(Keys.history); } - private async encryptHistory(): Promise { - if (this.history == null || this.history.length === 0) { + private async encryptHistory(history: PasswordHistory[]): Promise { + if (history == null || history.length === 0) { return Promise.resolve([]); } - const promises = this.history.map(async (item) => { + const promises = history.map(async (item) => { const encrypted = await this.cryptoService.encrypt(item.password); return new PasswordHistory(encrypted.encryptedString, item.date); }); @@ -233,11 +245,11 @@ export class PasswordGenerationService implements PasswordGenerationServiceInter return await Promise.all(promises); } - private matchesPrevious(password: string): boolean { - if (this.history == null || this.history.length === 0) { + private matchesPrevious(password: string, history: PasswordHistory[]): boolean { + if (history == null || history.length === 0) { return false; } - return this.history[this.history.length - 1].password === password; + return history[history.length - 1].password === password; } }