mirror of
https://github.com/bitwarden/browser
synced 2025-12-16 08:13:42 +00:00
lazy load history
This commit is contained in:
@@ -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>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user