From acdea2efdfb356d30153e306865a2be85ab65194 Mon Sep 17 00:00:00 2001 From: martgil Date: Wed, 9 Oct 2024 17:30:25 +0800 Subject: [PATCH 1/6] Use Manifest V2 for Thunderbird Port --- tooling/build-types-and-manifests.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tooling/build-types-and-manifests.ts b/tooling/build-types-and-manifests.ts index a32b4a6e41a..e24f7957216 100644 --- a/tooling/build-types-and-manifests.ts +++ b/tooling/build-types-and-manifests.ts @@ -47,10 +47,19 @@ addManifest('firefox-consumer', manifest => { addManifest( 'thunderbird-consumer', manifest => { - (manifest.action as messenger._manifest._WebExtensionManifestAction).default_title = 'FlowCrypt'; + // we can continue using Manifest V2 for Thunderbird MailExtension - https://github.com/FlowCrypt/flowcrypt-browser/issues/5848 + manifest.manifest_version = 2; manifest.name = 'FlowCrypt Encryption for Thunderbird'; manifest.description = 'Simple end-to-end encryption to secure email and attachments on Thunderbird'; manifest.permissions = [...(manifest.permissions ?? []), 'compose', 'messagesRead', 'messagesUpdate', 'messagesModify', 'accountsRead']; + const manifestV3 = manifest as chrome.runtime.ManifestV3; + manifest.web_accessible_resources = manifestV3.web_accessible_resources?.[0].resources; + manifest.content_security_policy = manifestV3.content_security_policy?.extension_pages; + manifest.permissions = [...(manifestV3.permissions ?? []), ...(manifestV3.host_permissions ?? [])]; + delete manifest.host_permissions; + manifest.browser_action = manifestV3.action; + (manifest.browser_action as messenger._manifest._WebExtensionManifestAction).default_title = 'FlowCrypt'; + delete manifest.action; manifest.compose_action = { default_title: 'Secure Compose', // eslint-disable-line @typescript-eslint/naming-convention default_icon: '/img/logo/flowcrypt-logo-64-64.png', // eslint-disable-line @typescript-eslint/naming-convention @@ -59,6 +68,7 @@ addManifest( default_title: 'Secure Compose', // eslint-disable-line @typescript-eslint/naming-convention default_icon: '/img/logo/flowcrypt-logo-64-64.png', // eslint-disable-line @typescript-eslint/naming-convention }; + delete manifest.minimum_chrome_version; (manifest.browser_specific_settings as messenger._manifest.FirefoxSpecificProperties).strict_min_version = '102.0'; manifest.background = { type: 'module', From be775dbc51cf9f00d9cf82572e7c3e26896cefea Mon Sep 17 00:00:00 2001 From: martgil Date: Thu, 10 Oct 2024 10:16:19 +0800 Subject: [PATCH 2/6] remove content_scripts for Gmail --- tooling/build-types-and-manifests.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tooling/build-types-and-manifests.ts b/tooling/build-types-and-manifests.ts index e24f7957216..d6852fb12c0 100644 --- a/tooling/build-types-and-manifests.ts +++ b/tooling/build-types-and-manifests.ts @@ -74,6 +74,7 @@ addManifest( type: 'module', scripts: ['/js/service_worker/background.js'], }; + manifest.content_scripts?.splice(0, 1); }, 'firefox-consumer' ); From 3a82fa0e4aa7f1ff57bfe989f186006792ece43e Mon Sep 17 00:00:00 2001 From: martgil Date: Thu, 10 Oct 2024 10:35:25 +0800 Subject: [PATCH 3/6] added test for Thunderbird manifest file --- test/source/patterns.ts | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/test/source/patterns.ts b/test/source/patterns.ts index 6b363a27e1e..dc43ddea643 100644 --- a/test/source/patterns.ts +++ b/test/source/patterns.ts @@ -81,11 +81,12 @@ for (const srcFilePath of getAllFilesInDir('./extension', /\.ts$/)) { const expectedPermissions: chrome.runtime.ManifestPermissions[] = ['alarms', 'scripting', 'storage', 'tabs', 'unlimitedStorage']; const expectedConsumerHostPermissions = ['https://*.google.com/*', 'https://www.googleapis.com/*', 'https://flowcrypt.com/*']; const expectedEnterpriseHostPermissions = ['https://*.google.com/*', 'https://*.googleapis.com/*', 'https://flowcrypt.com/*']; -for (const buildType of ['chrome-consumer', 'chrome-enterprise']) { +for (const buildType of ['chrome-consumer', 'chrome-enterprise', 'thunderbird-consumer', 'firefox-consumer']) { const manifest = JSON.parse(readFileSync(`./build/${buildType}/manifest.json`).toString()) as chrome.runtime.Manifest; + const webBrowserBuilds = buildType.includes('chrome') || buildType.includes('firefox'); const expectedHostPermissions = buildType.includes('consumer') ? expectedConsumerHostPermissions : expectedEnterpriseHostPermissions; for (const expectedHostPermission of expectedHostPermissions) { - if (!manifest.host_permissions.includes(expectedHostPermission)) { + if (webBrowserBuilds && !manifest.host_permissions.includes(expectedHostPermission)) { console.error(`Missing host permission '${expectedHostPermission}' in ${buildType}/manifest.json`); errsFound++; } @@ -98,10 +99,26 @@ for (const buildType of ['chrome-consumer', 'chrome-enterprise']) { } } } - const gmailCs = manifest.content_scripts?.find(cs => cs.matches?.includes('https://mail.google.com/*')); - if (!gmailCs?.css?.length || !gmailCs.js?.length) { - console.error(`Missing content_scripts declaration for Gmail in ${buildType}/manifest.json`); - errsFound++; + if (buildType === 'thunderbird-consumer') { + if (manifest.manifest_version !== 2) { + console.error(`${buildType} - Manifest version is not 2`); + errsFound++; + } + if (!Array.isArray(manifest.web_accessible_resources)) { + console.error(`${buildType} - web_accessible_resources should be an array`); + errsFound++; + } + if (typeof manifest.content_security_policy !== 'string') { + console.error(`${buildType} - content_security_policy should be a string`); + errsFound++; + } + } + if (webBrowserBuilds) { + const gmailCs = manifest.content_scripts?.find(cs => cs.matches?.includes('https://mail.google.com/*')); + if (!gmailCs?.css?.length || !gmailCs.js?.length) { + console.error(`Missing content_scripts declaration for Gmail in ${buildType}/manifest.json`); + errsFound++; + } } } From baf4d35eed917473aa099eab84ef5695a0f25257 Mon Sep 17 00:00:00 2001 From: martgil Date: Fri, 11 Oct 2024 13:19:30 +0800 Subject: [PATCH 4/6] revert changes --- tooling/build-types-and-manifests.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/tooling/build-types-and-manifests.ts b/tooling/build-types-and-manifests.ts index d6852fb12c0..e24f7957216 100644 --- a/tooling/build-types-and-manifests.ts +++ b/tooling/build-types-and-manifests.ts @@ -74,7 +74,6 @@ addManifest( type: 'module', scripts: ['/js/service_worker/background.js'], }; - manifest.content_scripts?.splice(0, 1); }, 'firefox-consumer' ); From 65f1fbedbc4b8b569316fbc48e8f666f24984401 Mon Sep 17 00:00:00 2001 From: martgil Date: Mon, 14 Oct 2024 17:35:22 +0800 Subject: [PATCH 5/6] refactor --- test/source/patterns.ts | 48 +++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/test/source/patterns.ts b/test/source/patterns.ts index dc43ddea643..2a0bdc66c84 100644 --- a/test/source/patterns.ts +++ b/test/source/patterns.ts @@ -83,10 +83,10 @@ const expectedConsumerHostPermissions = ['https://*.google.com/*', 'https://www. const expectedEnterpriseHostPermissions = ['https://*.google.com/*', 'https://*.googleapis.com/*', 'https://flowcrypt.com/*']; for (const buildType of ['chrome-consumer', 'chrome-enterprise', 'thunderbird-consumer', 'firefox-consumer']) { const manifest = JSON.parse(readFileSync(`./build/${buildType}/manifest.json`).toString()) as chrome.runtime.Manifest; - const webBrowserBuilds = buildType.includes('chrome') || buildType.includes('firefox'); + const isManifestV3Build = buildType.includes('chrome') || buildType.includes('firefox'); const expectedHostPermissions = buildType.includes('consumer') ? expectedConsumerHostPermissions : expectedEnterpriseHostPermissions; for (const expectedHostPermission of expectedHostPermissions) { - if (webBrowserBuilds && !manifest.host_permissions.includes(expectedHostPermission)) { + if (isManifestV3Build && !manifest.host_permissions.includes(expectedHostPermission)) { console.error(`Missing host permission '${expectedHostPermission}' in ${buildType}/manifest.json`); errsFound++; } @@ -101,25 +101,51 @@ for (const buildType of ['chrome-consumer', 'chrome-enterprise', 'thunderbird-co } if (buildType === 'thunderbird-consumer') { if (manifest.manifest_version !== 2) { - console.error(`${buildType} - Manifest version is not 2`); + console.error(`${buildType} - The manifest version is not 2`); errsFound++; } if (!Array.isArray(manifest.web_accessible_resources)) { - console.error(`${buildType} - web_accessible_resources should be an array`); + console.error(`${buildType} - The web_accessible_resources should be an array`); errsFound++; } if (typeof manifest.content_security_policy !== 'string') { - console.error(`${buildType} - content_security_policy should be a string`); + console.error(`${buildType} - The content_security_policy should be a string`); errsFound++; } - } - if (webBrowserBuilds) { - const gmailCs = manifest.content_scripts?.find(cs => cs.matches?.includes('https://mail.google.com/*')); - if (!gmailCs?.css?.length || !gmailCs.js?.length) { - console.error(`Missing content_scripts declaration for Gmail in ${buildType}/manifest.json`); - errsFound++; + const expectedHostPermissions = [ + 'alarms', + 'storage', + 'tabs', + 'scripting', + 'unlimitedStorage', + 'identity', + 'compose', + 'messagesRead', + 'messagesUpdate', + 'messagesModify', + 'accountsRead', + 'https://flowcrypt.com/*', + 'https://*.google.com/*', + 'https://outlook.live.com/*', + 'https://outlook.office365.com/*', + 'https://outlook.office.com/*', + 'https://graph.microsoft.com/*', + 'https://login.microsoftonline.com/*', + 'https://www.googleapis.com/*', + ]; + const buildHostPermissions = isManifestV3Build ? manifest.host_permissions : manifest.permissions; + for (const expectedHostPermission of expectedHostPermissions) { + if (!buildHostPermissions?.includes(expectedHostPermission)) { + console.error(`${buildType} - Missing permission ${expectedHostPermission} in ${buildType}/manifest.json`); + errsFound++; + } } } + const extensionContentScript = manifest.content_scripts?.find(cs => cs.matches?.includes('https://mail.google.com/*')); + if (!extensionContentScript?.css?.length || !extensionContentScript.js?.length) { + console.error(`Missing content_scripts declaration for the extension in ${buildType}/manifest.json`); + errsFound++; + } } if (errsFound) { From 8287f855b45e6fed4bf2e3bc31354104ee0ce4b6 Mon Sep 17 00:00:00 2001 From: martgil Date: Tue, 15 Oct 2024 18:41:55 +0800 Subject: [PATCH 6/6] test permissions exclusive only for Thunderbird --- test/source/patterns.ts | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/test/source/patterns.ts b/test/source/patterns.ts index 2a0bdc66c84..bfa686ffa51 100644 --- a/test/source/patterns.ts +++ b/test/source/patterns.ts @@ -112,29 +112,9 @@ for (const buildType of ['chrome-consumer', 'chrome-enterprise', 'thunderbird-co console.error(`${buildType} - The content_security_policy should be a string`); errsFound++; } - const expectedHostPermissions = [ - 'alarms', - 'storage', - 'tabs', - 'scripting', - 'unlimitedStorage', - 'identity', - 'compose', - 'messagesRead', - 'messagesUpdate', - 'messagesModify', - 'accountsRead', - 'https://flowcrypt.com/*', - 'https://*.google.com/*', - 'https://outlook.live.com/*', - 'https://outlook.office365.com/*', - 'https://outlook.office.com/*', - 'https://graph.microsoft.com/*', - 'https://login.microsoftonline.com/*', - 'https://www.googleapis.com/*', - ]; + const thunderbirdExpectedPermissions = ['compose', 'messagesRead', 'messagesUpdate', 'messagesModify', 'accountsRead']; const buildHostPermissions = isManifestV3Build ? manifest.host_permissions : manifest.permissions; - for (const expectedHostPermission of expectedHostPermissions) { + for (const expectedHostPermission of thunderbirdExpectedPermissions) { if (!buildHostPermissions?.includes(expectedHostPermission)) { console.error(`${buildType} - Missing permission ${expectedHostPermission} in ${buildType}/manifest.json`); errsFound++;