1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-10 13:23:34 +00:00

[PM-10079] Add keyboard shortcut to autofill identity and credit cards (#10254)

* [BEEEP] Autofill Identity and Card Ciphers From Keyboard Shortcut

* [PM-10079] Add keyboard shortcut to autofill identity and credit card ciphers

* [PM-10079] Fixing jest tests

* [PM-10079] Added an enum for the autofill commands, and adjusted how we filter out cipher types before sorting them by last used when calling for ID and card ciphers

* [PM-10079] Updating copywriting for the autofill settings revolving around keyboard shortcuts

* [PM-10079] Setting a method within CipherService as private
This commit is contained in:
Cesar Gonzalez
2024-07-31 12:52:04 -05:00
committed by GitHub
parent 85c8ff04a1
commit 86acca3bec
17 changed files with 187 additions and 61 deletions

View File

@@ -85,3 +85,17 @@ export const DisablePasswordManagerUris = {
Vivaldi: "vivaldi://settings/autofill",
Unknown: "https://bitwarden.com/help/disable-browser-autofill/",
} as const;
export const ExtensionCommand = {
AutofillCommand: "autofill_cmd",
AutofillCard: "autofill_card",
AutofillIdentity: "autofill_identity",
AutofillLogin: "autofill_login",
OpenAutofillOverlay: "open_autofill_overlay",
GeneratePassword: "generate_password",
OpenPopup: "open_popup",
LockVault: "lock_vault",
NoopCommand: "noop",
} as const;
export type ExtensionCommandType = (typeof ExtensionCommand)[keyof typeof ExtensionCommand];

View File

@@ -162,4 +162,6 @@ export abstract class CipherService implements UserKeyRotationDataProvider<Ciphe
newUserKey: UserKey,
userId: UserId,
) => Promise<CipherWithIdRequest[]>;
getNextCardCipher: () => Promise<CipherView>;
getNextIdentityCipher: () => Promise<CipherView>;
}

View File

@@ -500,6 +500,13 @@ export class CipherService implements CipherServiceAbstraction {
});
}
private async getAllDecryptedCiphersOfType(type: CipherType[]): Promise<CipherView[]> {
const ciphers = await this.getAllDecrypted();
return ciphers
.filter((cipher) => cipher.deletedDate == null && type.includes(cipher.type))
.sort((a, b) => this.sortCiphersByLastUsedThenName(a, b));
}
async getAllFromApiForOrganization(organizationId: string): Promise<CipherView[]> {
const response = await this.apiService.getCiphersOrganization(organizationId);
return await this.decryptOrganizationCiphersResponse(response, organizationId);
@@ -549,6 +556,36 @@ export class CipherService implements CipherServiceAbstraction {
return this.getCipherForUrl(url, false, false, false);
}
async getNextCardCipher(): Promise<CipherView> {
const cacheKey = "cardCiphers";
if (!this.sortedCiphersCache.isCached(cacheKey)) {
const ciphers = await this.getAllDecryptedCiphersOfType([CipherType.Card]);
if (!ciphers?.length) {
return null;
}
this.sortedCiphersCache.addCiphers(cacheKey, ciphers);
}
return this.sortedCiphersCache.getNext(cacheKey);
}
async getNextIdentityCipher() {
const cacheKey = "identityCiphers";
if (!this.sortedCiphersCache.isCached(cacheKey)) {
const ciphers = await this.getAllDecryptedCiphersOfType([CipherType.Identity]);
if (!ciphers?.length) {
return null;
}
this.sortedCiphersCache.addCiphers(cacheKey, ciphers);
}
return this.sortedCiphersCache.getNext(cacheKey);
}
updateLastUsedIndexForUrl(url: string) {
this.sortedCiphersCache.updateLastUsedIndex(url);
}