import { BrowserApi } from "../browser/browserApi" ; import MainBackground from "./main.background" ; import { CipherService } from "jslib-common/abstractions/cipher.service" ; import { EventService } from "jslib-common/abstractions/event.service" ; import { PasswordGenerationService } from "jslib-common/abstractions/passwordGeneration.service" ; import { PlatformUtilsService } from "jslib-common/abstractions/platformUtils.service" ; import { TotpService } from "jslib-common/abstractions/totp.service" ; import { VaultTimeoutService } from "jslib-common/abstractions/vaultTimeout.service" ; import { CipherRepromptType } from "jslib-common/enums/cipherRepromptType" ; import { EventType } from "jslib-common/enums/eventType" ; import { CipherView } from "jslib-common/models/view/cipherView" ; import LockedVaultPendingNotificationsItem from "./models/lockedVaultPendingNotificationsItem" ; export default class ContextMenusBackground { private readonly noopCommandSuffix = "noop" ; private contextMenus : any ; constructor ( private main , private cipherService , private passwordGenerationService , private platformUtilsService , private vaultTimeoutService , private eventService , private totpService ) { this . contextMenus = chrome . contextMenus ; } async init ( ) { if ( ! this . contextMenus ) { return ; } this . contextMenus . onClicked . addListener ( async ( info , tab ) => { 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" || info . parentMenuItemId === "copy-username" || info . parentMenuItemId === "copy-password" || info . parentMenuItemId === "copy-totp" ) { await this . cipherAction ( tab , info ) ; } } ) ; BrowserApi . messageListener ( "contextmenus.background" , async ( msg , sender , sendResponse ) => { if ( msg . command === "unlockCompleted" && msg . data . target === "contextmenus.background" ) { await this . cipherAction ( msg . data . commandToRetry . sender . tab , msg . data . commandToRetry . msg . data ) ; } } ) ; } private async generatePasswordToClipboard ( ) { const options = ( await this . passwordGenerationService . getOptions ( ) ) [ 0 ] ; const password = await this . passwordGenerationService . generatePassword ( options ) ; this . platformUtilsService . copyToClipboard ( password , { window : window } ) ; this . passwordGenerationService . addHistory ( password ) ; } private async getClickedElement ( tab , frameId ) { if ( tab == null ) { return ; } BrowserApi . tabSendMessage ( tab , { command : "getClickedElement" } , { frameId : frameId } ) ; } private async cipherAction ( tab , info ) { const id = info . menuItemId . split ( "_" ) [ 1 ] ; if ( await this . vaultTimeoutService . isLocked ( ) ) { const retryMessage = { commandToRetry : { msg : { command : this . noopCommandSuffix , data : info } , sender : { tab : tab } , } , target : "contextmenus.background" , } ; await BrowserApi . tabSendMessageData ( tab , "addToLockedVaultPendingNotifications" , retryMessage ) ; BrowserApi . tabSendMessageData ( tab , "promptForLogin" ) ; return ; } let cipher ; 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 ) ; } if ( cipher == null ) { return ; } if ( info . parentMenuItemId === "autofill" ) { await this . startAutofillPage ( tab , cipher ) ; } 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 . eventService . collect ( EventType . Cipher_ClientCopiedPassword , cipher . id ) ; } else if ( info . parentMenuItemId === "copy-totp" ) { const totpValue = await this . totpService . getCode ( cipher . login . totp ) ; this . platformUtilsService . copyToClipboard ( totpValue , { window : window } ) ; } } private async startAutofillPage ( tab , cipher ) { this . main . loginToAutoFill = cipher ; if ( tab == null ) { return ; } BrowserApi . tabSendMessage ( tab , { command : "collectPageDetails" , tab : tab , sender : "contextMenu" , } ) ; } }