From efff875d50db173c747bd6db5328ca72235db391 Mon Sep 17 00:00:00 2001 From: Yannick Chiron Date: Thu, 2 Dec 2021 11:41:45 +0100 Subject: [PATCH 01/10] fix: add missing permission for `activeTab` While Chrome and Firefox seems not to care about this permission, Safari displays an error about missing `activeTab` I'm not sure about the impact of this modification as the only observed effect is the disappearing of the error message (app was still loading without it) --- src/manifest.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/manifest.json b/src/manifest.json index c384606d2ef9..c5cb0fdfb4c1 100755 --- a/src/manifest.json +++ b/src/manifest.json @@ -82,6 +82,7 @@ }, "permissions": [ "tabs", + "activeTab", "contextMenus", "storage", "unlimitedStorage", From 103c1ec5d0fa0360e7de6949d8846bc72581d22e Mon Sep 17 00:00:00 2001 From: Yannick Chiron Date: Thu, 2 Dec 2021 11:44:52 +0100 Subject: [PATCH 02/10] fix: include missing `inPageMenu` folder in XCode project `inPageMenu` was not present in the XCode project. This resulted on folder not present in the extension package's content and the `in-page` Cozy menu was not loaded by Safari --- src/safari/desktop.xcodeproj/project.pbxproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/safari/desktop.xcodeproj/project.pbxproj b/src/safari/desktop.xcodeproj/project.pbxproj index fc05760fc99b..9669fb7fe8b5 100644 --- a/src/safari/desktop.xcodeproj/project.pbxproj +++ b/src/safari/desktop.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 2C24FE7E2757BFA5003CB360 /* inPageMenu in Resources */ = {isa = PBXBuildFile; fileRef = 2C24FE7D2757BFA5003CB360 /* inPageMenu */; }; 55E0374D2577FA6B00979016 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55E0374C2577FA6B00979016 /* AppDelegate.swift */; }; 55E037502577FA6B00979016 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 55E0374E2577FA6B00979016 /* Main.storyboard */; }; 55E037522577FA6B00979016 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55E037512577FA6B00979016 /* ViewController.swift */; }; @@ -50,6 +51,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 2C24FE7D2757BFA5003CB360 /* inPageMenu */ = {isa = PBXFileReference; lastKnownFileType = folder; name = inPageMenu; path = ../../../build/inPageMenu; sourceTree = ""; }; 5508DD7926051B5900A85C58 /* libswiftAppKit.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libswiftAppKit.tbd; path = usr/lib/swift/libswiftAppKit.tbd; sourceTree = SDKROOT; }; 55E037482577FA6B00979016 /* desktop.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = desktop.app; sourceTree = BUILT_PRODUCTS_DIR; }; 55E0374B2577FA6B00979016 /* desktop.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = desktop.entitlements; sourceTree = ""; }; @@ -148,6 +150,7 @@ 55E0376F2577FA6F00979016 /* Resources */ = { isa = PBXGroup; children = ( + 2C24FE7D2757BFA5003CB360 /* inPageMenu */, 55E037702577FA6F00979016 /* popup */, 55E037712577FA6F00979016 /* background.js */, 55E037722577FA6F00979016 /* images */, @@ -258,6 +261,7 @@ buildActionMask = 2147483647; files = ( 55E037812577FA6F00979016 /* _locales in Resources */, + 2C24FE7E2757BFA5003CB360 /* inPageMenu in Resources */, 55E0377B2577FA6F00979016 /* images in Resources */, 55E0377F2577FA6F00979016 /* manifest.json in Resources */, 55E037802577FA6F00979016 /* background.html in Resources */, From 877c8e89a86033cd5a27a5d6f6ddae74ae41ae05 Mon Sep 17 00:00:00 2001 From: Yannick Chiron Date: Thu, 2 Dec 2021 11:49:52 +0100 Subject: [PATCH 03/10] DO_NOT_MERGE: set correct `DEVELOPMENT_TEAM` id Previous `DEVELOPMENT_TEAM` was corresponding to Bitwarden's team id Current corresponds to Cozy team and was taken from https://developer.apple.com/account/resources/profiles/list (displayed on top right, under account's name) This edit seems not enough to make code signature correctly working App is building but there are console warning during buid about missing signatures --- src/safari/desktop.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/safari/desktop.xcodeproj/project.pbxproj b/src/safari/desktop.xcodeproj/project.pbxproj index 9669fb7fe8b5..1e78986f5a6e 100644 --- a/src/safari/desktop.xcodeproj/project.pbxproj +++ b/src/safari/desktop.xcodeproj/project.pbxproj @@ -439,7 +439,7 @@ CODE_SIGN_ENTITLEMENTS = safari/safari.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = LTZ2PFU5D6; + DEVELOPMENT_TEAM = 3AKXFMV43J; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = safari/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -463,7 +463,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = LTZ2PFU5D6; + DEVELOPMENT_TEAM = 3AKXFMV43J; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = safari/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -488,7 +488,7 @@ CODE_SIGN_ENTITLEMENTS = desktop/desktop.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = LTZ2PFU5D6; + DEVELOPMENT_TEAM = 3AKXFMV43J; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = desktop/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -512,7 +512,7 @@ CODE_SIGN_INJECT_BASE_ENTITLEMENTS = NO; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - DEVELOPMENT_TEAM = LTZ2PFU5D6; + DEVELOPMENT_TEAM = 3AKXFMV43J; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = desktop/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( From eedc0e78efcede188e6265f5955c3e4d25c8b64c Mon Sep 17 00:00:00 2001 From: Yannick Chiron Date: Thu, 2 Dec 2021 11:55:11 +0100 Subject: [PATCH 04/10] fix: change BundleIdentifier for `io.cozy.pass.desktop` We wan't to adapt the BundleIdentifier to avoid conflict with Bitwarden extension if installed in parallel of Cozy Pass extension --- src/browser/safariApp.ts | 2 +- src/safari/desktop.xcodeproj/project.pbxproj | 8 ++++---- src/safari/desktop/ViewController.swift | 2 +- src/safari/safari/Info.plist | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/browser/safariApp.ts b/src/browser/safariApp.ts index 80930a3d5728..48a776a3f986 100644 --- a/src/browser/safariApp.ts +++ b/src/browser/safariApp.ts @@ -8,7 +8,7 @@ export class SafariApp { return new Promise(resolve => { const now = new Date(); const messageId = now.getTime().toString() + '_' + Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); - (browser as any).runtime.sendNativeMessage('com.bitwarden.desktop', { + (browser as any).runtime.sendNativeMessage('io.cozy.pass.desktop', { id: messageId, command: command, data: data, diff --git a/src/safari/desktop.xcodeproj/project.pbxproj b/src/safari/desktop.xcodeproj/project.pbxproj index 1e78986f5a6e..4cf862125079 100644 --- a/src/safari/desktop.xcodeproj/project.pbxproj +++ b/src/safari/desktop.xcodeproj/project.pbxproj @@ -448,7 +448,7 @@ "@executable_path/../../../../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.14; - PRODUCT_BUNDLE_IDENTIFIER = com.bitwarden.desktop.safari; + PRODUCT_BUNDLE_IDENTIFIER = io.cozy.pass.desktop.safari; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; @@ -472,7 +472,7 @@ "@executable_path/../../../../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.14; - PRODUCT_BUNDLE_IDENTIFIER = com.bitwarden.desktop.safari; + PRODUCT_BUNDLE_IDENTIFIER = io.cozy.pass.desktop.safari; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; @@ -496,7 +496,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.14; - PRODUCT_BUNDLE_IDENTIFIER = com.bitwarden.desktop; + PRODUCT_BUNDLE_IDENTIFIER = io.cozy.pass.desktop; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; }; @@ -520,7 +520,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.14; - PRODUCT_BUNDLE_IDENTIFIER = com.bitwarden.desktop; + PRODUCT_BUNDLE_IDENTIFIER = io.cozy.pass.desktop; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; }; diff --git a/src/safari/desktop/ViewController.swift b/src/safari/desktop/ViewController.swift index fbda5decf85a..f626d7e6d74c 100644 --- a/src/safari/desktop/ViewController.swift +++ b/src/safari/desktop/ViewController.swift @@ -3,7 +3,7 @@ import SafariServices.SFSafariApplication import SafariServices.SFSafariExtensionManager let appName = "desktop" -let extensionBundleIdentifier = "com.bitwarden.desktop.Extension" +let extensionBundleIdentifier = "io.cozy.pass.desktop.Extension" class ViewController: NSViewController { diff --git a/src/safari/safari/Info.plist b/src/safari/safari/Info.plist index fa42edeccca7..c357ac621824 100755 --- a/src/safari/safari/Info.plist +++ b/src/safari/safari/Info.plist @@ -35,7 +35,7 @@ A secure and free password manager for all of your devices. SFSafariAppExtensionBundleIdentifiersToReplace - com.bitwarden.desktop.safari + io.cozy.pass.desktop.safari From 2d6294657a36b354ec193c35955c04083ca432b8 Mon Sep 17 00:00:00 2001 From: Yannick Chiron Date: Thu, 2 Dec 2021 11:57:25 +0100 Subject: [PATCH 05/10] fix: add missing `com.apple.security.network.server` in entitlements This entitlement was present on Bitwarden's project but not on Cozy's project --- src/safari/safari/safari.entitlements | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/safari/safari/safari.entitlements b/src/safari/safari/safari.entitlements index a0463869a929..85c03d7b48aa 100644 --- a/src/safari/safari/safari.entitlements +++ b/src/safari/safari/safari.entitlements @@ -8,5 +8,7 @@ com.apple.security.network.client + com.apple.security.network.server + From 1a04afdc9f590eedd068317e6e949d66881b7cb9 Mon Sep 17 00:00:00 2001 From: Yannick Chiron Date: Thu, 2 Dec 2021 13:10:00 +0100 Subject: [PATCH 06/10] DO_NOT_MERGE: replace `chrome` api by `browser` api `chrome` api seems not to be correctly handled by Safari but `browser` one should I made the replacement on all `inPageMenu` related content scripts (so not the entire code) This fixes some behaviours (localization) but not all (messaging). So I'm not sure that this is the correct thing to do --- src/browser/browserApi.ts | 24 ++++++++++++------------ src/browser/safariApp.ts | 18 +++++++----------- src/content/menuCtrler.js | 10 +++++----- src/inPageMenu/loginMenu.js | 22 +++++++++++----------- src/inPageMenu/menu.js | 14 +++++++------- 5 files changed, 42 insertions(+), 46 deletions(-) diff --git a/src/browser/browserApi.ts b/src/browser/browserApi.ts index 48ee5fa4b50b..21742cf27ad3 100644 --- a/src/browser/browserApi.ts +++ b/src/browser/browserApi.ts @@ -14,7 +14,7 @@ export class BrowserApi { static async getTabFromCurrentWindowId(): Promise { return await BrowserApi.tabsQueryFirst({ active: true, - windowId: chrome.windows.WINDOW_ID_CURRENT, + windowId: browser.windows.WINDOW_ID_CURRENT, }); } @@ -37,7 +37,7 @@ export class BrowserApi { static async tabsQuery(options: any): Promise { return new Promise(resolve => { - chrome.tabs.query(options, (tabs: any[]) => { + browser.tabs.query(options).then((tabs: any[]) => { resolve(tabs); }); }); @@ -70,8 +70,8 @@ export class BrowserApi { } return new Promise(resolve => { - chrome.tabs.sendMessage(tab.id, obj, options, () => { - if (chrome.runtime.lastError) { + browser.tabs.sendMessage(tab.id, obj, options).then(() => { + if (browser.runtime.lastError) { // Some error happened } resolve(); @@ -80,23 +80,23 @@ export class BrowserApi { } static getBackgroundPage(): any { - return chrome.extension.getBackgroundPage(); + return browser.extension.getBackgroundPage(); } static getApplicationVersion(): string { - return chrome.runtime.getManifest().version; + return browser.runtime.getManifest().version; } static async isPopupOpen(): Promise { - return Promise.resolve(chrome.extension.getViews({ type: 'popup' }).length > 0); + return Promise.resolve(browser.extension.getViews({ type: 'popup' }).length > 0); } static createNewTab(url: string, extensionPage: boolean = false, active: boolean = true) { - chrome.tabs.create({ url: url, active: active }); + browser.tabs.create({ url: url, active: active }); } static messageListener(name: string, callback: (message: any, sender: any, response: any) => void) { - chrome.runtime.onMessage.addListener((msg: any, sender: any, response: any) => { + browser.runtime.onMessage.addListener((msg: any, sender: any, response: any) => { callback(msg, sender, response); }); } @@ -146,19 +146,19 @@ export class BrowserApi { } static getUILanguage(win: Window) { - return chrome.i18n.getUILanguage(); + return browser.i18n.getUILanguage(); } static reloadExtension(win: Window) { if (win != null) { return win.location.reload(true); } else { - return chrome.runtime.reload(); + return browser.runtime.reload(); } } static reloadOpenWindows() { - const views = chrome.extension.getViews() as Window[]; + const views = browser.extension.getViews() as Window[]; views.filter(w => w.location.href != null).forEach(w => { w.location.reload(); }); diff --git a/src/browser/safariApp.ts b/src/browser/safariApp.ts index 48a776a3f986..e8b1508606ff 100644 --- a/src/browser/safariApp.ts +++ b/src/browser/safariApp.ts @@ -5,17 +5,13 @@ export class SafariApp { if (!BrowserApi.isSafariApi) { return Promise.resolve(null); } - return new Promise(resolve => { - const now = new Date(); - const messageId = now.getTime().toString() + '_' + Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); - (browser as any).runtime.sendNativeMessage('io.cozy.pass.desktop', { - id: messageId, - command: command, - data: data, - responseData: null, - }, (response: any) => { - resolve(response); - }); + const now = new Date(); + const messageId = now.getTime().toString() + '_' + Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); + return browser.runtime.sendNativeMessage('io.cozy.pass.desktop', { + id: messageId, + command: command, + data: data, + responseData: null, }); } } diff --git a/src/content/menuCtrler.js b/src/content/menuCtrler.js index 5210c15e7983..c7b40fd415ef 100755 --- a/src/content/menuCtrler.js +++ b/src/content/menuCtrler.js @@ -431,7 +431,7 @@ function moveSelection(n) { } state.selectedCipher = newCipherNode - chrome.runtime.sendMessage({ + browser.runtime.sendMessage({ command : 'bgAnswerMenuRequest', subcommand : 'menuMoveSelection', targetCipher : newCipherNode.data.id, @@ -457,7 +457,7 @@ function getPossibleTypesForField(fieldEl) { /* --------------------------------------------------------------------- */ // Submit the currently selected cypher for autofill function submit() { - chrome.runtime.sendMessage({ + browser.runtime.sendMessage({ command : 'bgAnswerMenuRequest', subcommand : 'fillFormWithCipher', sender : 'menuCtrler', @@ -470,7 +470,7 @@ menuCtrler.submit = submit /* --------------------------------------------------------------------- */ // autofill the focused field with the detail of the currently selected cypher function submitDetail() { - chrome.runtime.sendMessage({ + browser.runtime.sendMessage({ command : 'bgAnswerMenuRequest', subcommand : 'askMenuTofillFieldWithData', sender : 'menuCtrler', @@ -576,13 +576,13 @@ function _setIframeURLforMenuType(menuType, isPinLocked, isLocked) { const hash = '#' + encodeURIComponent(JSON.stringify(state.iFrameHash)); const rand = '?' + Math.floor((Math.random()*1000000)+1) if (menuType === 'autofillMenu') { - menuEl.src = chrome.runtime.getURL('inPageMenu/menu.html' + rand) + hash + menuEl.src = browser.runtime.getURL('inPageMenu/menu.html' + rand) + hash } else if (menuType === 'loginMenu') { let searchParams = '' if (isPinLocked) searchParams = 'isPinLocked=true' if (isLocked) searchParams += 'isLocked=true' if (searchParams) searchParams = '?' + searchParams - menuEl.src = chrome.runtime.getURL('inPageMenu/loginMenu.html' + searchParams + rand) + hash + menuEl.src = browser.runtime.getURL('inPageMenu/loginMenu.html' + searchParams + rand) + hash } } diff --git a/src/inPageMenu/loginMenu.js b/src/inPageMenu/loginMenu.js index 2db67e1c00fc..24daffa0e790 100755 --- a/src/inPageMenu/loginMenu.js +++ b/src/inPageMenu/loginMenu.js @@ -36,7 +36,7 @@ var panel , document.addEventListener('DOMContentLoaded', () => { // 0- ask rememberedCozyUrl - chrome.runtime.sendMessage({ + browser.runtime.sendMessage({ command : 'bgAnswerMenuRequest', subcommand: 'getRememberedCozyUrl', sender : 'loginMenu.js', @@ -84,7 +84,7 @@ document.addEventListener('DOMContentLoaded', () => { }, false); } else { // retrieve i18n values and set elements textcontent - const i18nGetMessage = chrome.i18n.getMessage + const i18nGetMessage = browser.i18n.getMessage urlLabelTxt = i18nGetMessage('cozyUrl' ) twoFaLabelTxt = i18nGetMessage('verificationCode' ) visiPwdBtn.title = i18nGetMessage('toggleVisibility' ) @@ -115,17 +115,17 @@ document.addEventListener('DOMContentLoaded', () => { }); // 8- listen to the commands sent by the addon - chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) { + browser.runtime.onMessage.addListener(function (msg, sender, sendResponse) { // console.log('loginMenu heared msg', msg); if (msg.command !== 'menuAnswerRequest') return switch (msg.subcommand) { case 'loginNOK': // console.log("loginNOK heard in loginInPageMenu"); - setError(chrome.i18n.getMessage('inPageMenuLoginError')) + setError(browser.i18n.getMessage('inPageMenuLoginError')) break; case '2faCheckNOK': // console.log("2faCheckNOK heard in loginInPageMenu"); - setError(chrome.i18n.getMessage('inPageMenuLogin2FACheckError')) + setError(browser.i18n.getMessage('inPageMenuLogin2FACheckError')) adjustMenuHeight() break; case 'setRememberedCozyUrl': @@ -189,7 +189,7 @@ document.addEventListener('DOMContentLoaded', () => { function adjustMenuHeight() { if (lastSentHeight === panel.offsetHeight) return lastSentHeight = panel.offsetHeight - chrome.runtime.sendMessage({ + browser.runtime.sendMessage({ command : 'bgAnswerMenuRequest' , subcommand: 'setMenuHeight' , height : lastSentHeight , @@ -227,7 +227,7 @@ async function submit() { subcommand = 'unlock' } - chrome.runtime.sendMessage({ + browser.runtime.sendMessage({ command : 'bgAnswerMenuRequest', subcommand: subcommand , sender : 'loginMenu.js' , @@ -243,9 +243,9 @@ async function submit() { ] if (translatableMessages.includes(e.message)) { - setError(chrome.i18n.getMessage(e.message)) + setError(browser.i18n.getMessage(e.message)) } else { - setError(chrome.i18n.getMessage('errorOccurred')) + setError(browser.i18n.getMessage('errorOccurred')) } } } @@ -262,7 +262,7 @@ async function submit2fa() { return; } - chrome.runtime.sendMessage({ + browser.runtime.sendMessage({ command : 'bgAnswerMenuRequest', subcommand: '2faCheck' , sender : 'loginMenu.js' , @@ -391,7 +391,7 @@ function setFocusOnEmptyField(){ /* --------------------------------------------------------------------- */ // Request the menu controler to close the iframe of the menu function close(force) { - chrome.runtime.sendMessage({ + browser.runtime.sendMessage({ command : 'bgAnswerMenuRequest', force : force, subcommand: 'closeMenu' , diff --git a/src/inPageMenu/menu.js b/src/inPageMenu/menu.js index 1f484f3fe695..3e3410db241f 100755 --- a/src/inPageMenu/menu.js +++ b/src/inPageMenu/menu.js @@ -71,13 +71,13 @@ document.addEventListener('DOMContentLoaded', () => { // }, false); } else { // retrieve i18n values and set elements textcontent - lang = chrome.i18n.getUILanguage(); + lang = browser.i18n.getUILanguage(); i18nGetMessage = chrome.i18n.getMessage titleEl.textContent = i18nGetMessage('inPageMenuSelectAnAccount') } // 3- listen to the commands and ciphers sent by the addon - chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) { + browser.runtime.onMessage.addListener(function (msg, sender, sendResponse) { /* @override by Cozy : this log is very useful for reverse engineering the code, keep it for tests console.log('menu.js HEARD : ', { @@ -134,7 +134,7 @@ document.addEventListener('DOMContentLoaded', () => { }) // 4- request ciphers to the background scripts - chrome.runtime.sendMessage({ + browser.runtime.sendMessage({ command : 'bgAnswerMenuRequest', subcommand: 'getCiphersForTab' , sender : 'menu.js' , @@ -143,7 +143,7 @@ document.addEventListener('DOMContentLoaded', () => { // 5- listen to click on the close menu button const closeIcon = document.querySelector('.close-icon') closeIcon.addEventListener('click',()=>{ - chrome.runtime.sendMessage({ + browser.runtime.sendMessage({ command : 'bgAnswerMenuRequest', subcommand: 'closeMenu' , force : true , @@ -174,7 +174,7 @@ document.addEventListener('DOMContentLoaded', () => { /* --------------------------------------------------------------------- */ // Request the background to autofill the page with a cipher function requestFormFillingWithCipher(cipherId) { - chrome.runtime.sendMessage({ + browser.runtime.sendMessage({ command : 'bgAnswerMenuRequest', subcommand: 'fillFormWithCipher' , cipherId : cipherId , @@ -186,7 +186,7 @@ function requestFormFillingWithCipher(cipherId) { /* --------------------------------------------------------------------- */ // Request the background to autofill the page with a cipher function requestFieldFillingWithData(dataTxt) { - chrome.runtime.sendMessage({ + browser.runtime.sendMessage({ command : 'bgAnswerMenuRequest' , subcommand: 'fieldFillingWithData' , frameId : hostFrameId , @@ -328,7 +328,7 @@ function selectFirstVisibleRow() { function adjustMenuHeight() { if (lastSentHeight === panel.offsetHeight) return lastSentHeight = panel.offsetHeight - chrome.runtime.sendMessage({ + browser.runtime.sendMessage({ command : 'bgAnswerMenuRequest' , subcommand: 'setMenuHeight' , height : lastSentHeight , From 2af4e8550cc27f4b7c831e31462a169f01dc4fa3 Mon Sep 17 00:00:00 2001 From: Yannick Chiron Date: Thu, 2 Dec 2021 13:03:09 +0100 Subject: [PATCH 07/10] fix: avoid using method pointer for i18n Previous code was using a pointer to `browser.i18n.getMessage` to handle multiple calls to translation methods This is not working on Safari, so we have to repeat `browser.i18n.getMessage` each time we want to get translated messages --- src/inPageMenu/loginMenu.js | 19 +++++++++---------- src/inPageMenu/menu.js | 3 +-- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/inPageMenu/loginMenu.js b/src/inPageMenu/loginMenu.js index 24daffa0e790..7a3f6bc3d4b3 100755 --- a/src/inPageMenu/loginMenu.js +++ b/src/inPageMenu/loginMenu.js @@ -84,20 +84,19 @@ document.addEventListener('DOMContentLoaded', () => { }, false); } else { // retrieve i18n values and set elements textcontent - const i18nGetMessage = browser.i18n.getMessage - urlLabelTxt = i18nGetMessage('cozyUrl' ) - twoFaLabelTxt = i18nGetMessage('verificationCode' ) - visiPwdBtn.title = i18nGetMessage('toggleVisibility' ) - visi2faBtn.title = i18nGetMessage('toggleVisibility' ) - submitBtn.textContent = i18nGetMessage('login' ) + urlLabelTxt = browser.i18n.getMessage('cozyUrl' ) + twoFaLabelTxt = browser.i18n.getMessage('verificationCode' ) + visiPwdBtn.title = browser.i18n.getMessage('toggleVisibility' ) + visi2faBtn.title = browser.i18n.getMessage('toggleVisibility' ) + submitBtn.textContent = browser.i18n.getMessage('login' ) if (isPinLocked) { - title.textContent = i18nGetMessage('unlockWithPin' ) - pwdLabelTxt = i18nGetMessage('pin' ) + title.textContent = browser.i18n.getMessage('unlockWithPin' ) + pwdLabelTxt = browser.i18n.getMessage('pin' ) urlInput.disabled = true document.getElementById('url-row').classList.add('disabled') } else { - title.textContent = i18nGetMessage('loginInPageMenuTitle') - pwdLabelTxt = i18nGetMessage('masterPass' ) + title.textContent = browser.i18n.getMessage('loginInPageMenuTitle') + pwdLabelTxt = browser.i18n.getMessage('masterPass' ) } } diff --git a/src/inPageMenu/menu.js b/src/inPageMenu/menu.js index 3e3410db241f..79f74340d4b5 100755 --- a/src/inPageMenu/menu.js +++ b/src/inPageMenu/menu.js @@ -72,8 +72,7 @@ document.addEventListener('DOMContentLoaded', () => { } else { // retrieve i18n values and set elements textcontent lang = browser.i18n.getUILanguage(); - i18nGetMessage = chrome.i18n.getMessage - titleEl.textContent = i18nGetMessage('inPageMenuSelectAnAccount') + titleEl.textContent = browser.i18n.getMessage('inPageMenuSelectAnAccount') } // 3- listen to the commands and ciphers sent by the addon From 137f5d8f1cbb510c18b1436a1c781f1c18c18685 Mon Sep 17 00:00:00 2001 From: Yannick Chiron Date: Thu, 2 Dec 2021 13:09:08 +0100 Subject: [PATCH 08/10] DO_NOT_MERGE: invert `rand` and `search` in generated URLs Previous implementation was generating urls in the form `file.html?params=XXXX?123456789` Problem is that is contains two `?` in the url, which should not be valid By inverting both variables we can generate urls in the form `file.html?123456789¶ms=XXXX` This is an attempt to fix a Safari error stating that resource is missing on server side (when refreshing the extension's iframe) This does not fix this issue, but I would say that the new form is more correct --- src/content/menuCtrler.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/menuCtrler.js b/src/content/menuCtrler.js index c7b40fd415ef..774e5a905792 100755 --- a/src/content/menuCtrler.js +++ b/src/content/menuCtrler.js @@ -581,8 +581,8 @@ function _setIframeURLforMenuType(menuType, isPinLocked, isLocked) { let searchParams = '' if (isPinLocked) searchParams = 'isPinLocked=true' if (isLocked) searchParams += 'isLocked=true' - if (searchParams) searchParams = '?' + searchParams - menuEl.src = browser.runtime.getURL('inPageMenu/loginMenu.html' + searchParams + rand) + hash + if (searchParams) searchParams = '&' + searchParams + menuEl.src = browser.runtime.getURL('inPageMenu/loginMenu.html' + rand + searchParams) + hash } } @@ -594,7 +594,7 @@ function _forceIframeRefresh() { if (!menuEl || !menuEl.src) return const url = new URL(menuEl.src) const rand = '?' + Math.floor((Math.random()*1000000)+1) - menuEl.src = url.origin + url.pathname + url.search + rand + url.hash + menuEl.src = url.origin + url.pathname + rand + url.search + url.hash } From 4a66990b2a6e1a3ce957317c6e00035e8b004a1b Mon Sep 17 00:00:00 2001 From: Yannick Chiron Date: Thu, 2 Dec 2021 13:11:35 +0100 Subject: [PATCH 09/10] DO_NOT_MERGE: add some debug logs --- src/background/runtime.background.ts | 2 ++ src/browser/browserApi.ts | 3 +++ src/browser/safariApp.ts | 2 ++ src/content/menuCtrler.js | 8 +++++++- src/inPageMenu/loginMenu.js | 4 ++++ src/inPageMenu/menu.js | 1 + 6 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/background/runtime.background.ts b/src/background/runtime.background.ts index 22e3ff485678..5a25828aa257 100755 --- a/src/background/runtime.background.ts +++ b/src/background/runtime.background.ts @@ -138,6 +138,7 @@ export default class RuntimeBackground { await this.main.collectPageDetailsForContentScript(sender.tab, msg.sender, sender.frameId); break; case 'bgAnswerMenuRequest': + console.log('received bgAnswerMenuRequest') switch (msg.subcommand) { case 'getCiphersForTab': const logins = await this.cipherService.getAllDecryptedForUrl(sender.tab.url, null); @@ -881,6 +882,7 @@ export default class RuntimeBackground { } private async loggedinAndUnlocked(command: string) { + console.log('loggedinAndUnlocked') await this.main.setIcon(); await this.main.refreshBadgeAndMenu(false); this.notificationsService.init(this.environmentService); diff --git a/src/browser/browserApi.ts b/src/browser/browserApi.ts index 21742cf27ad3..ae38b790cac7 100644 --- a/src/browser/browserApi.ts +++ b/src/browser/browserApi.ts @@ -65,10 +65,12 @@ export class BrowserApi { } static async tabSendMessage(tab: any, obj: any, options: any = null): Promise { + console.log('tabSendMessage') if (!tab || !tab.id) { return; } + console.log('tabSendMessage',tab.id, obj, options) return new Promise(resolve => { browser.tabs.sendMessage(tab.id, obj, options).then(() => { if (browser.runtime.lastError) { @@ -97,6 +99,7 @@ export class BrowserApi { static messageListener(name: string, callback: (message: any, sender: any, response: any) => void) { browser.runtime.onMessage.addListener((msg: any, sender: any, response: any) => { + console.log('messageListenerFrombrowserApi', msg) callback(msg, sender, response); }); } diff --git a/src/browser/safariApp.ts b/src/browser/safariApp.ts index e8b1508606ff..4382f11f1032 100644 --- a/src/browser/safariApp.ts +++ b/src/browser/safariApp.ts @@ -2,7 +2,9 @@ import { BrowserApi } from './browserApi'; export class SafariApp { static sendMessageToApp(command: string, data: any = null, resolveNow = false): Promise { + console.log('sendMessageToApp',command, data) if (!BrowserApi.isSafariApi) { + console.log('resolbe null') return Promise.resolve(null); } const now = new Date(); diff --git a/src/content/menuCtrler.js b/src/content/menuCtrler.js index 774e5a905792..341a65ff66ba 100755 --- a/src/content/menuCtrler.js +++ b/src/content/menuCtrler.js @@ -239,6 +239,7 @@ function _onClick(event) { } else { show(this) } + console.log('end _onCliek') } function _onKeyDown(event) { @@ -291,6 +292,7 @@ function _onKeyDown(event) { // function show(targetEl) { // console.log('menuCtrler.show() '); + console.log('SHOW()') if (state.isFrozen) return if (!state.isHidden && (state.lastFocusedEl === targetEl)) return state.lastFocusedEl = targetEl @@ -520,6 +522,7 @@ menuCtrler.setCiphers = setCiphers // Run this function so that menuCtrler.state.selectedCipher corresponds // to the initial selection within the menu function selectFirstCipherToSuggestFor(fieldEl) { + console.log('selectFirstCipherToSuggestFor') if (state.isHidden) return if (!ciphers || ciphers._length == 0) return if (!fieldEl) return @@ -630,12 +633,15 @@ function _updateHash() { // send informations to the iframe through the url's hash (no reload) // the hash is a Json string function _setApplyFadeInUrl(doApply, fieldTypes) { + console.log('_setApplyFadeInUrl', doApply, fieldTypes) if (!menuEl || !menuEl.src) return const url = new URL(menuEl.src) + console.log('url', url) if (doApply) { fieldTypes = {...{login: false, identity: false, card: false, fieldFormat:false},...fieldTypes} + console.log('setHash') state.iFrameHash = {...state.iFrameHash, ...fieldTypes, applyFadeIn: true} - menuEl.src = url.origin + url.pathname + url.search + '#' + + console.log('end setHash') encodeURIComponent(JSON.stringify(state.iFrameHash)) } else { state.iFrameHash.applyFadeIn = false diff --git a/src/inPageMenu/loginMenu.js b/src/inPageMenu/loginMenu.js index 7a3f6bc3d4b3..7760ccb80aa6 100755 --- a/src/inPageMenu/loginMenu.js +++ b/src/inPageMenu/loginMenu.js @@ -97,6 +97,8 @@ document.addEventListener('DOMContentLoaded', () => { } else { title.textContent = browser.i18n.getMessage('loginInPageMenuTitle') pwdLabelTxt = browser.i18n.getMessage('masterPass' ) + + console.log('title.textContent', browser.i18n.getMessage('loginInPageMenuTitle')) } } @@ -114,7 +116,9 @@ document.addEventListener('DOMContentLoaded', () => { }); // 8- listen to the commands sent by the addon + console.log('addListener') browser.runtime.onMessage.addListener(function (msg, sender, sendResponse) { + console.log('Received message ', msg) // console.log('loginMenu heared msg', msg); if (msg.command !== 'menuAnswerRequest') return switch (msg.subcommand) { diff --git a/src/inPageMenu/menu.js b/src/inPageMenu/menu.js index 79f74340d4b5..97d29c156427 100755 --- a/src/inPageMenu/menu.js +++ b/src/inPageMenu/menu.js @@ -77,6 +77,7 @@ document.addEventListener('DOMContentLoaded', () => { // 3- listen to the commands and ciphers sent by the addon browser.runtime.onMessage.addListener(function (msg, sender, sendResponse) { + console.log('messageListenerFromMenu', msg) /* @override by Cozy : this log is very useful for reverse engineering the code, keep it for tests console.log('menu.js HEARD : ', { From e27fd12a5d363aed5dbeeece0933f5dba419600b Mon Sep 17 00:00:00 2001 From: Yannick Chiron Date: Thu, 2 Dec 2021 13:15:27 +0100 Subject: [PATCH 10/10] DO_NOT_MERGE: try not changing iFrame URL This is for a test while investigating error message when open/closing the inPageMenu When clicking the cloud image in a field, nothing happens expect having an error message on the console stating `Failed to load resource The requested URL was not found on this server` This seems to be related to those line when changing the menuEl.src, then iFrame's url is refreshed and this message appears I still don't understand what prevents the iFrame to refresh, knowing that the first display is based on the same URL (only args are changing) --- src/content/menuCtrler.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/content/menuCtrler.js b/src/content/menuCtrler.js index 341a65ff66ba..bb2349fa3bb5 100755 --- a/src/content/menuCtrler.js +++ b/src/content/menuCtrler.js @@ -642,11 +642,12 @@ function _setApplyFadeInUrl(doApply, fieldTypes) { console.log('setHash') state.iFrameHash = {...state.iFrameHash, ...fieldTypes, applyFadeIn: true} console.log('end setHash') - encodeURIComponent(JSON.stringify(state.iFrameHash)) + menuEl.src = url.origin + url.pathname + url.search + '#' +'%7B%22arrowD%22%3A0%2C%22hostFrameId%22%3A0%7D' + // encodeURIComponent(JSON.stringify(state.iFrameHash)) } else { state.iFrameHash.applyFadeIn = false - menuEl.src = url.origin + url.pathname + url.search + '#' + - encodeURIComponent(JSON.stringify(state.iFrameHash)) + menuEl.src = url.origin + url.pathname + url.search + '#' + '%7B%22arrowD%22%3A0%2C%22hostFrameId%22%3A0%7D' + // encodeURIComponent(JSON.stringify(state.iFrameHash)) } }