Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
11d8a76
use OpenPGP.js from web content script - wip
Mar 14, 2023
3346597
firefox fix
Mar 14, 2023
7a7651e
use processAndStoreKeysFromEkmLocally() directly
Mar 14, 2023
48fb7f2
simplify
Mar 15, 2023
3dfd68b
Merge remote-tracking branch 'origin/master' into issue-4906-openpgp-…
Mar 15, 2023
6c8da84
added link to external PR
Mar 16, 2023
a2c989f
Merge remote-tracking branch 'origin/master' into issue-4906-openpgp-…
Mar 16, 2023
fe9bb59
web-stream-tools support in content script (development setup)
Mar 18, 2023
7ff645f
production mode in webpack bundling
Mar 20, 2023
6a1af63
testing OpenPGP/Stream operations from content script
Mar 20, 2023
1fa81d9
Merge remote-tracking branch 'origin/master' into issue-4906-openpgp-…
Mar 20, 2023
7dff2be
lint fix
Mar 20, 2023
4e33580
build for manual testing of content script in Firefox
Mar 20, 2023
6d2ec20
more debug configurations for VSCode
Mar 20, 2023
8d4a3ab
removed duplicate
Mar 21, 2023
4298b1d
Merge remote-tracking branch 'origin/master' into issue-4906-openpgp-…
Mar 21, 2023
9598bb0
fix
Mar 21, 2023
a72e748
fix
Mar 21, 2023
aa5c6ac
allow multiple test result divs
Mar 22, 2023
3fb4257
Merge remote-tracking branch 'origin/master' into issue-4906-openpgp-…
Mar 22, 2023
710f27d
clearer test output
Mar 22, 2023
70dc59c
niceties
Mar 22, 2023
d7df2bc
fix Uint8Array problem in Firefox
Mar 23, 2023
d971da2
Merge remote-tracking branch 'origin/master' into issue-4906-openpgp-…
Mar 24, 2023
4d88425
updated comment
Mar 24, 2023
3efd2e7
Merge remote-tracking branch 'origin/master' into issue-4906-openpgp-…
Mar 24, 2023
e53a17d
Merge remote-tracking branch 'origin/master' into issue-4906-openpgp-…
Mar 25, 2023
2dd0237
globally patch Uint8Array.subarray()
Mar 26, 2023
18dc1ab
fix
Mar 26, 2023
2a0c078
patch Uint8Array.slice
Mar 26, 2023
9deb31a
Added a test for KeyUtil.readBinary()
Mar 26, 2023
97396e1
increase ava cli timeout values
Mar 26, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .semaphore/semaphore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ blocks:
- name: consumer mock - flaky test group
commands:
- npm run-script test_ci_chrome_consumer_flaky
- name: content script tests
commands:
- npm run-script test_ci_chrome_content_scripts
- name: enterprise mock - standard test group
commands:
- npm run-script test_ci_chrome_enterprise
Expand Down
24 changes: 24 additions & 0 deletions conf/webpack.config.js
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was really a lot of work done only to be able to call web-stream-tools readToEnd function, with different approaches for unit test code, extension pages and content script. May it be possible to convince OpenPGP.js developers to simply re-export this helper function from their library, @tomholub ?

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//webpack.config.js
//bundle the web version of @openpgp/web-stream-tools for content script
const path = require('path');

module.exports = {
mode: 'production',
entry: {
main: '../build/generic-extension-wip/lib/streams/streams.js',
},
output: {
library: {
name: 'Stream',
type: 'var',
},
path: path.resolve('../build/generic-extension-wip/lib'),
filename: 'streams_web.js', // <--- Will be compiled to this single file
},
resolve: {
fallback: {
stream: false,
},
extensions: ['.js'],
},
};
3 changes: 0 additions & 3 deletions extension/js/background_page/background_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { Bm, BrowserMsg } from '../common/browser/browser-msg.js';
import { emailKeyIndex } from '../common/core/common.js';
import { VERSION } from '../common/core/const.js';
import { ExpirationCache } from '../common/core/expiration-cache.js';
import { processAndStoreKeysFromEkmLocally, getLocalKeyExpiration } from '../common/helpers.js';
import { Catch } from '../common/platform/catch.js';
import { AcctStore } from '../common/platform/store/acct-store.js';
import { ContactStore } from '../common/platform/store/contact-store.js';
Expand Down Expand Up @@ -60,8 +59,6 @@ console.info('background_process.js starting');
BrowserMsg.bgAddListener('storeGlobalSet', (r: Bm.StoreGlobalSet) => GlobalStore.set(r.values));
BrowserMsg.bgAddListener('storeAcctGet', (r: Bm.StoreAcctGet) => AcctStore.get(r.acctEmail, r.keys));
BrowserMsg.bgAddListener('storeAcctSet', (r: Bm.StoreAcctSet) => AcctStore.set(r.acctEmail, r.values));
BrowserMsg.bgAddListener('processAndStoreKeysFromEkmLocally', processAndStoreKeysFromEkmLocally);
BrowserMsg.bgAddListener('getLocalKeyExpiration', getLocalKeyExpiration);

// todo - when https://github.com/FlowCrypt/flowcrypt-browser/issues/2560
// is fixed, this can be moved to the gmail content script, and some may be removed
Comment on lines -63 to 64
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also BrowserMsg.addPgpListeners(); could be removed from below, and added to content script message listener instead.

Then pgp_block can be updated to call content script instead of background script.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I do this in this PR?
I thought after #5022 we may no longer need some of these messages, e.g. pgpMsgDecrypt or pgpMsgVerifyDetached

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i see. then it doesn't have to be in this pr.

Expand Down
18 changes: 1 addition & 17 deletions extension/js/common/browser/browser-msg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,6 @@ export namespace Bm {
export type ShowAttachmentPreview = { iframeUrl: string };
export type ReRenderRecipient = { email: string };
export type SaveFetchedPubkeys = { email: string; pubkeys: string[] };
export type ProcessAndStoreKeysFromEkmLocally = { acctEmail: string; decryptedPrivateKeys: string[] };
export type GetLocalKeyExpiration = { acctEmail: string };

export namespace Res {
export type GetActiveTabInfo = {
Expand All @@ -107,12 +105,6 @@ export namespace Bm {
export type AjaxGmailAttachmentGetChunk = { chunk: Buf };
export type _tab_ = { tabId: string | null | undefined }; // eslint-disable-line @typescript-eslint/naming-convention
export type SaveFetchedPubkeys = boolean;
export type GetLocalKeyExpiration = number | undefined;
export type ProcessAndStoreKeysFromEkmLocally = {
needPassphrase?: boolean;
updateCount?: number;
noKeysSetup?: boolean;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type Db = any; // not included in Any below
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand All @@ -134,9 +126,7 @@ export namespace Bm {
| StoreGlobalSet
| AjaxGmailAttachmentGetChunk
| SaveFetchedPubkeys
| ProcessAndStoreKeysFromEkmLocally
| PgpKeyBinaryToArmored
| GetLocalKeyExpiration;
| PgpKeyBinaryToArmored;
}

export type AnyRequest =
Expand Down Expand Up @@ -176,8 +166,6 @@ export namespace Bm {
| ShowAttachmentPreview
| ReRenderRecipient
| SaveFetchedPubkeys
| ProcessAndStoreKeysFromEkmLocally
| GetLocalKeyExpiration
| PgpKeyBinaryToArmored
| AuthWindowResult;

Expand Down Expand Up @@ -244,10 +232,6 @@ export class BrowserMsg {
BrowserMsg.sendAwait(undefined, 'pgpKeyBinaryToArmored', bm, true) as Promise<Bm.Res.PgpKeyBinaryToArmored>,
saveFetchedPubkeys: (bm: Bm.SaveFetchedPubkeys) =>
BrowserMsg.sendAwait(undefined, 'saveFetchedPubkeys', bm, true) as Promise<Bm.Res.SaveFetchedPubkeys>,
processAndStoreKeysFromEkmLocally: (bm: Bm.ProcessAndStoreKeysFromEkmLocally) =>
BrowserMsg.sendAwait(undefined, 'processAndStoreKeysFromEkmLocally', bm, true) as Promise<Bm.Res.ProcessAndStoreKeysFromEkmLocally>,
getLocalKeyExpiration: (bm: Bm.GetLocalKeyExpiration) =>
BrowserMsg.sendAwait(undefined, 'getLocalKeyExpiration', bm, true) as Promise<Bm.Res.GetLocalKeyExpiration>,
},
},
passphraseEntry: (dest: Bm.Dest, bm: Bm.PassphraseEntry) => BrowserMsg.sendCatch(dest, 'passphrase_entry', bm),
Expand Down
9 changes: 5 additions & 4 deletions extension/js/common/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { ClientConfiguration } from './client-configuration.js';
import { ContactStore } from './platform/store/contact-store.js';
import { KeyStore } from './platform/store/key-store.js';
import { PassphraseStore } from './platform/store/passphrase-store.js';
import { Bm } from './browser/browser-msg.js';
import { PgpPwd } from './core/crypto/pgp/pgp-password.js';

export const isCustomerUrlFesUsed = async (acctEmail: string) => {
Expand Down Expand Up @@ -111,9 +110,11 @@ export const processAndStoreKeysFromEkmLocally = async ({
acctEmail,
decryptedPrivateKeys,
ppOptions: originalOptions,
}: Bm.ProcessAndStoreKeysFromEkmLocally & {
}: {
acctEmail: string;
decryptedPrivateKeys: string[];
ppOptions?: PassphraseOptions;
}): Promise<Bm.Res.ProcessAndStoreKeysFromEkmLocally> => {
}) => {
const { unencryptedPrvs } = await parseAndCheckPrivateKeys(decryptedPrivateKeys);
const existingKeys = await KeyStore.get(acctEmail);
let { keysToRetain, newUnencryptedKeysToSave } = await filterKeysToSave(unencryptedPrvs, existingKeys);
Expand Down Expand Up @@ -175,7 +176,7 @@ export const processAndStoreKeysFromEkmLocally = async ({
};
};

export const getLocalKeyExpiration = async ({ acctEmail }: Bm.GetLocalKeyExpiration): Promise<Bm.Res.GetLocalKeyExpiration> => {
export const getLocalKeyExpiration = async (acctEmail: string): Promise<number> => {
const kis = await KeyStore.get(acctEmail);
const expirations = await Promise.all(kis.map(async ki => (await KeyUtil.parse(ki.public))?.expiration ?? Number.MAX_SAFE_INTEGER));
return Math.max(...expirations);
Expand Down
2 changes: 1 addition & 1 deletion extension/js/common/platform/require.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type Codec = {
};

export const requireOpenpgp = (): typeof OpenPGP => {
return (window as unknown as { openpgp: typeof OpenPGP }).openpgp;
return (globalThis as unknown as { openpgp: typeof OpenPGP }).openpgp;
};

export const requireMimeParser = (): typeof MimeParser => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { Gmail } from '../../common/api/email-provider/gmail/gmail.js';
import { Injector } from '../../common/inject.js';
import { PubLookup } from '../../common/api/pub-lookup.js';
import { Notifications } from '../../common/notifications.js';
// note: only types are supported for OpenPGP.js or web-stream-tools, their function calls will fail
import { PgpArmor } from '../../common/core/crypto/pgp/pgp-armor.js';
import { Ui } from '../../common/browser/ui.js';
import { WebmailCommon } from '../../common/webmail.js';
Expand Down Expand Up @@ -391,7 +390,7 @@ export class GmailElementReplacer implements WebmailElementReplacer {
if (this.debug) {
console.debug('processNewPgpAttachments() -> msgGet may take some time');
}
const msg = await this.gmail.msgGet(msgId, 'full');
const msg = await this.gmail.msgGet(msgId, 'full'); // todo: cache or thoroughly refactor in #5022
if (this.debug) {
console.debug('processNewPgpAttachments() -> msgGet done -> processAttachments', msg);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Ui } from '../../common/browser/ui.js';
import { ClientConfiguration, ClientConfigurationError } from '../../common/client-configuration.js';
import { Str, Url } from '../../common/core/common.js';
import { InMemoryStoreKeys, VERSION } from '../../common/core/const.js';
import { getLocalKeyExpiration, processAndStoreKeysFromEkmLocally } from '../../common/helpers.js';
import { Injector } from '../../common/inject.js';
import { Lang } from '../../common/lang.js';
import { Notifications } from '../../common/notifications.js';
Expand Down Expand Up @@ -291,7 +292,7 @@ export const contentScriptSetupIfVacant = async (webmailSpecific: WebmailSpecifi
ppEvent: { entered?: boolean }
) => {
try {
const { needPassphrase, updateCount, noKeysSetup } = await BrowserMsg.send.bg.await.processAndStoreKeysFromEkmLocally({
const { needPassphrase, updateCount, noKeysSetup } = await processAndStoreKeysFromEkmLocally({
acctEmail,
decryptedPrivateKeys,
});
Expand Down Expand Up @@ -382,7 +383,7 @@ export const contentScriptSetupIfVacant = async (webmailSpecific: WebmailSpecifi
};

const notifyExpiringKeys = async (acctEmail: string, clientConfiguration: ClientConfiguration, notifications: Notifications) => {
const expiration = await BrowserMsg.send.bg.await.getLocalKeyExpiration({ acctEmail });
const expiration = await getLocalKeyExpiration(acctEmail);
if (expiration === undefined) {
return;
}
Expand Down
22 changes: 8 additions & 14 deletions extension/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,21 @@
],
"content_scripts": [
{
"matches": [
"https://mail.google.com/*"
],
"css": [
"/css/webmail.css",
"/css/sweetalert2.css"
],
"matches": ["https://mail.google.com/*"],
"css": ["/css/webmail.css", "/css/sweetalert2.css"],
"js": [
"/lib/purify.js",
"/lib/jquery.min.js",
"/lib/openpgp.js",
"/lib/sweetalert2.js",
"/lib/jquery.min.js",
"/lib/streams_web.js",
"/js/content_scripts/webmail_bundle.js"
]
},
{
"matches": [
"https://www.google.com/robots.txt*"
],
"js": [
"/js/common/oauth2/oauth2_inject.js"
],
"matches": ["https://www.google.com/robots.txt*"],
"js": ["/js/common/oauth2/oauth2_inject.js"],
"run_at": "document_start"
}
],
Expand Down Expand Up @@ -93,4 +87,4 @@
],
"minimum_chrome_version": "96",
"content_security_policy": "upgrade-insecure-requests; script-src 'self'; frame-ancestors https://mail.google.com 'self'; img-src 'self' https://* data: blob:; frame-src 'self' blob:; worker-src 'self'; form-action 'none'; media-src 'none'; font-src 'none'; manifest-src 'none'; object-src 'none'; base-uri 'self'"
}
}
Loading