bitwarden-estensione-browser/apps/browser/src/background/contextMenus.background.ts

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

147 lines
5.3 KiB
TypeScript
Raw Normal View History

2022-06-14 17:10:53 +02:00
import { AuthService } from "@bitwarden/common/abstractions/auth.service";
import { CipherService } from "@bitwarden/common/abstractions/cipher.service";
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
2022-06-14 17:10:53 +02:00
import { PasswordGenerationService } from "@bitwarden/common/abstractions/passwordGeneration.service";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { TotpService } from "@bitwarden/common/abstractions/totp.service";
import { AuthenticationStatus } from "@bitwarden/common/enums/authenticationStatus";
import { CipherRepromptType } from "@bitwarden/common/enums/cipherRepromptType";
import { EventType } from "@bitwarden/common/enums/eventType";
import { CipherView } from "@bitwarden/common/models/view/cipher.view";
2022-02-24 18:14:04 +01:00
import { BrowserApi } from "../browser/browserApi";
import MainBackground from "./main.background";
import LockedVaultPendingNotificationsItem from "./models/lockedVaultPendingNotificationsItem";
2017-12-07 22:02:15 +01:00
export default class ContextMenusBackground {
2021-10-20 17:45:19 +02:00
private readonly noopCommandSuffix = "noop";
2017-12-07 22:02:15 +01:00
private contextMenus: any;
2021-12-21 15:43:35 +01:00
2017-12-07 22:02:15 +01:00
constructor(
private main: MainBackground,
private cipherService: CipherService,
private passwordGenerationService: PasswordGenerationService,
private platformUtilsService: PlatformUtilsService,
private authService: AuthService,
private eventCollectionService: EventCollectionService,
private totpService: TotpService
) {
2017-12-07 22:02:15 +01:00
this.contextMenus = chrome.contextMenus;
2021-12-21 15:43:35 +01:00
}
2017-12-07 22:02:15 +01:00
async init() {
if (!this.contextMenus) {
2021-12-21 15:43:35 +01:00
return;
2017-12-07 22:02:15 +01:00
}
this.contextMenus.onClicked.addListener(
2021-10-19 16:00:38 +02:00
async (info: chrome.contextMenus.OnClickData, tab: chrome.tabs.Tab) => {
2017-12-07 22:02:15 +01:00
if (info.menuItemId === "generate-password") {
await this.generatePasswordToClipboard();
} else if (info.menuItemId === "copy-identifier") {
await this.getClickedElement(tab, info.frameId);
} else if (
info.parentMenuItemId === "autofill" ||
2017-12-07 22:02:15 +01:00
info.parentMenuItemId === "copy-username" ||
2020-03-03 16:42:49 +01:00
info.parentMenuItemId === "copy-password" ||
info.parentMenuItemId === "copy-totp"
2021-12-21 15:43:35 +01:00
) {
await this.cipherAction(tab, info);
2017-12-07 22:02:15 +01:00
}
2021-12-21 15:43:35 +01:00
}
);
2021-10-19 16:00:38 +02:00
BrowserApi.messageListener(
"contextmenus.background",
async (msg: any, sender: chrome.runtime.MessageSender, sendResponse: any) => {
if (msg.command === "unlockCompleted" && msg.data.target === "contextmenus.background") {
await this.cipherAction(
msg.data.commandToRetry.sender.tab,
msg.data.commandToRetry.msg.data
2021-12-21 15:43:35 +01:00
);
}
}
);
}
private async generatePasswordToClipboard() {
[EC-377] Transition Policy service into providing observables (#3259) * Added abstractions for PolicyApiService and PolicyService * Added implementations for PolicyApiService and PolicyService * Updated all references to new PolicyApiService and PolicyService * Deleted old PolicyService abstraction and implementation * Fixed CLI import path for policy.service * Fixed main.background.ts policyApiService dependency for policyService * Ran prettier * Updated policy-api.service with the correct imports * [EC-377] Removed methods from StateService that read policies * [EC-377] Updated policy service getAll method to use observable collection * [EC-377] Added first unit tests for policy service * [EC-377] Added more unit tests for Policy Service * [EC-376] Sorted methods order in PolicyApiService * [EC-376] Removed unused clearCache method from PolicyService * [EC-376] Added upsert method to PolicyService * [EC-376] PolicyApiService putPolicy method now upserts data to PolicyService * [EC-377] Removed tests for deleted clearCache method * [EC-377] Added unit test for PolicyService.upsert * [EC-377] Updated references to state service observables * [EC-377] Removed getAll method from PolicyService and refactored components to use observable collection * [EC-377] Updated components to use concatMap instead of async subscribe * [EC-377] Removed getPolicyForOrganization from policyApiService * [EC-377] Updated policyAppliesToUser to return observable collection * [EC-377] Changed policyService.policyAppliesToUser to return observable * [EC-377] Fixed browser settings.component.ts getting vault timeout * Updated people.component.ts to get ResetPassword policy through a subscription * [EC-377] Changed passwordGenerationService.getOptions to return observable * [EC-377] Fixed CLI generate.command.ts getting enforcePasswordGeneratorPoliciesOnOptions * [EC-377] Fixed eslint errors on rxjs * [EC-377] Reverted changes on passwordGeneration.service and vaultTimeout.service * [EC-377] Removed eslint disable on web/vault/add-edit-component * [EC-377] Changed AccountData.policies to TemporaryDataEncryption * [EC-377] Updated import.component to be reactive to policyAppliesToUser$ * [EC-377] Updated importBlockedByPolicy$ * [EC-377] Fixed missing rename * [EC-377] Updated policyService.masterPasswordPolicyOptions to return observable * [EC-377] Fixed vaultTimeout imports from merge * [EC-377] Reverted call to passwordGenerationService.getOptions * [EC-377] Reverted call to enforcePasswordGeneratorPoliciesOnOptions * [EC-377] Removed unneeded ngOnDestroy * Apply suggestions from code review Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> * [EC-377] Fixed login.component.ts and register.component.ts * [EC-377] Updated PolicyService to update vaultTimeout * [EC-377] Updated PolicyService dependencies * [EC-377] Renamed policyAppliesToUser to policyAppliesToActiveUser * [EC-377] VaultTimeoutSettings service now gets the vault timeout directly instead of using observables * [EC-377] Fixed unit tests by removing unneeded vaultTimeoutSettingsService * [EC-377] Set getDecryptedPolicies and setDecryptedPolicies as deprecated * [EC-377] Set PolicyService.getAll as deprecated and updated to use prototype.hasOwnProperty * [EC-565] Reverted unintended change to vaultTimeoutSettings that was causing a bug to not display the correct vault timeout * [EC-377] Removed unneeded destroy$ from preferences.component.ts * [EC-377] Fixed policy.service.ts import of OrganizationService Co-authored-by: Oscar Hinton <Hinton@users.noreply.github.com> Co-authored-by: mimartin12 <77340197+mimartin12@users.noreply.github.com>
2022-10-11 14:08:48 +02:00
const options = (await this.passwordGenerationService.getOptions())?.[0] ?? {};
const password = await this.passwordGenerationService.generatePassword(options);
this.platformUtilsService.copyToClipboard(password, { window: window });
2017-12-07 22:02:15 +01:00
this.passwordGenerationService.addHistory(password);
2021-12-21 15:43:35 +01:00
}
private async getClickedElement(tab: chrome.tabs.Tab, frameId: number) {
if (tab == null) {
2021-12-21 15:43:35 +01:00
return;
2017-12-07 22:02:15 +01:00
}
BrowserApi.tabSendMessage(tab, { command: "getClickedElement" }, { frameId: frameId });
2021-12-21 15:43:35 +01:00
}
2017-12-07 22:02:15 +01:00
private async cipherAction(tab: chrome.tabs.Tab, info: chrome.contextMenus.OnClickData) {
if (typeof info.menuItemId !== "string") {
return;
}
const id = info.menuItemId.split("_")[1];
2021-12-21 15:43:35 +01:00
if ((await this.authService.getAuthStatus()) < AuthenticationStatus.Unlocked) {
2018-04-23 19:04:11 +02:00
const retryMessage: LockedVaultPendingNotificationsItem = {
commandToRetry: {
msg: { command: this.noopCommandSuffix, data: info },
sender: { tab: tab },
2021-12-21 15:43:35 +01:00
},
2017-12-07 22:02:15 +01:00
target: "contextmenus.background",
};
await BrowserApi.tabSendMessageData(
2021-12-21 15:43:35 +01:00
tab,
2017-12-07 22:02:15 +01:00
"addToLockedVaultPendingNotifications",
retryMessage
2021-12-21 15:43:35 +01:00
);
2017-12-07 22:02:15 +01:00
BrowserApi.tabSendMessageData(tab, "promptForLogin");
2021-12-21 15:43:35 +01:00
return;
2017-12-07 22:02:15 +01:00
}
let cipher: CipherView;
if (id === this.noopCommandSuffix) {
const ciphers = await this.cipherService.getAllDecryptedForUrl(tab.url);
cipher = ciphers.find((c) => c.reprompt === CipherRepromptType.None);
} else {
const ciphers = await this.cipherService.getAllDecrypted();
cipher = ciphers.find((c) => c.id === id);
}
2021-10-20 17:45:19 +02:00
if (cipher == null) {
return;
2017-12-07 22:02:15 +01:00
}
if (info.parentMenuItemId === "autofill") {
await this.startAutofillPage(tab, cipher);
2017-12-07 22:02:15 +01:00
} else if (info.parentMenuItemId === "copy-username") {
this.platformUtilsService.copyToClipboard(cipher.login.username, { window: window });
} else if (info.parentMenuItemId === "copy-password") {
this.platformUtilsService.copyToClipboard(cipher.login.password, { window: window });
this.eventCollectionService.collect(EventType.Cipher_ClientCopiedPassword, cipher.id);
2017-12-07 22:02:15 +01:00
} else if (info.parentMenuItemId === "copy-totp") {
const totpValue = await this.totpService.getCode(cipher.login.totp);
this.platformUtilsService.copyToClipboard(totpValue, { window: window });
2017-12-07 22:02:15 +01:00
}
2021-12-21 15:43:35 +01:00
}
2017-12-07 22:02:15 +01:00
private async startAutofillPage(tab: chrome.tabs.Tab, cipher: CipherView) {
2017-12-07 22:02:15 +01:00
this.main.loginToAutoFill = cipher;
if (tab == null) {
return;
}
2021-12-21 15:43:35 +01:00
BrowserApi.tabSendMessage(tab, {
2017-12-07 22:02:15 +01:00
command: "collectPageDetails",
2021-12-21 15:43:35 +01:00
tab: tab,
2017-12-07 22:02:15 +01:00
sender: "contextMenu",
2021-12-21 15:43:35 +01:00
});
}
2017-12-07 22:02:15 +01:00
}