Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion extension/chrome/settings/modules/add_key.htm
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ <h1>Add Private Key <span id="spinner_container"></span></h1>
</div>
<div class="line">
<label>
<input type="checkbox" value="" name="check" class="input_passphrase_save" checked="">
<input type="checkbox" value="" name="check" class="input_passphrase_save" data-test="input-save-passphrase" disabled="disabled">
Remember Pass Phrase after closing browser.
</label>
</div>
Expand Down
11 changes: 9 additions & 2 deletions extension/chrome/settings/modules/add_key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@ import { initPassphraseToggle } from '../../../js/common/ui/passphrase-ui.js';
import { PassphraseStore } from '../../../js/common/platform/store/passphrase-store.js';
import { KeyStore } from '../../../js/common/platform/store/key-store.js';
import { UnexpectedKeyTypeError } from '../../../js/common/core/crypto/key.js';
import { OrgRules } from '../../../js/common/org-rules.js';
import { StorageType } from '../../../js/common/platform/store/abstract-store.js';

View.run(class AddKeyView extends View {

private readonly acctEmail: string;
private readonly parentTabId: string;
private readonly keyImportUi = new KeyImportUi({ rejectKnown: true });
private readonly gmail: Gmail;
private orgRules!: OrgRules;

constructor() {
super();
Expand All @@ -33,6 +36,10 @@ View.run(class AddKeyView extends View {
}

public render = async () => {
this.orgRules = await OrgRules.newInstance(this.acctEmail);
if (!this.orgRules.forbidStoringPassPhrase()) {
$('.input_passphrase_save').prop('checked', true).prop('disabled', false);
}
await initPassphraseToggle(['input_passphrase']);
this.keyImportUi.initPrvImportSrcForm(this.acctEmail, this.parentTabId);
Xss.sanitizeRender('#spinner_container', Ui.spinner('green') + ' loading..');
Expand Down Expand Up @@ -76,8 +83,8 @@ View.run(class AddKeyView extends View {
const checked = await this.keyImportUi.checkPrv(this.acctEmail, String($('.input_private_key').val()), String($('.input_passphrase').val()));
if (checked) {
await KeyStore.add(this.acctEmail, checked.encrypted); // resulting new_key checked above
await PassphraseStore.set($('.input_passphrase_save').prop('checked') ? 'local' : 'session', this.acctEmail,
checked.fingerprint, checked.passphrase);
const storageType: StorageType = ($('.input_passphrase_save').prop('checked') && !this.orgRules.forbidStoringPassPhrase()) ? 'local' : 'session';
await PassphraseStore.set(storageType, this.acctEmail, checked.fingerprint, checked.passphrase);
BrowserMsg.send.reload(this.parentTabId, { advanced: true });
}
} catch (e) {
Expand Down
3 changes: 2 additions & 1 deletion test/source/tests/flaky.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ export const defineFlakyTests = (testVariant: TestVariant, testWithBrowser: Test

ava.default('standalone - different send from, new signed message, verification in mock', testWithBrowser('compatibility', async (t, browser) => {
const key = Config.key('flowcryptcompatibility.from.address');
await SettingsPageRecipe.addKeyTest(t, browser, 'flowcrypt.compatibility@gmail.com', key.armored!, key.passphrase!);
await SettingsPageRecipe.addKeyTest(t, browser, 'flowcrypt.compatibility@gmail.com', key.armored!, key.passphrase!,
{ isSavePassphraseChecked: true, isSavePassphraseDisabled: false });
const composePage = await ComposePageRecipe.openStandalone(t, browser, 'compatibility');
await composePage.selectOption('@input-from', 'flowcryptcompatibility@gmail.com');
await ComposePageRecipe.fillMsg(composePage, { to: 'human@flowcrypt.com' }, 'New Signed Message (Mock Test)', { encrypt: false });
Expand Down
13 changes: 12 additions & 1 deletion test/source/tests/page-recipe/settings-page-recipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import { TestUrls } from '../../browser/test-urls';
import { Xss } from '../../platform/xss';
import { KeyUtil } from '../../core/crypto/key';

export type SavePassphraseChecks = {
isSavePassphraseDisabled?: boolean | undefined,
isSavePassphraseChecked?: boolean | undefined
};

export class SettingsPageRecipe extends PageRecipe {

public static ready = async (settingsPage: ControllablePage) => {
Expand Down Expand Up @@ -105,12 +110,18 @@ export class SettingsPageRecipe extends PageRecipe {
await settingsPage.waitTillGone('@dialog');
}

public static addKeyTest = async (t: AvaContext, browser: BrowserHandle, acctEmail: string, armoredPrvKey: string, passphrase: string) => {
public static addKeyTest = async (t: AvaContext, browser: BrowserHandle, acctEmail: string, armoredPrvKey: string, passphrase: string, checks: SavePassphraseChecks = {}) => {
const addPrvPage = await browser.newPage(t, `/chrome/settings/modules/add_key.htm?acctEmail=${Xss.escape(acctEmail)}&parent_tab_id=0`);
await addPrvPage.waitAndClick('#source_paste');
await addPrvPage.waitAndType('.input_private_key', armoredPrvKey);
await addPrvPage.waitAndClick('#toggle_input_passphrase');
await addPrvPage.waitAndType('#input_passphrase', passphrase);
if (checks.isSavePassphraseDisabled !== undefined) {
expect(await PageRecipe.isElementDisabled(await addPrvPage.waitAny('@input-save-passphrase'))).to.equal(checks.isSavePassphraseDisabled);
}
if (checks.isSavePassphraseChecked !== undefined) {
expect(await PageRecipe.isElementChecked(await addPrvPage.waitAny('@input-save-passphrase'))).to.equal(checks.isSavePassphraseChecked);
}
await addPrvPage.waitAndClick('.action_add_private_key', { delay: 1 });
await addPrvPage.waitTillGone('.swal2-container'); // dialog closed
await Util.sleep(1);
Expand Down
16 changes: 3 additions & 13 deletions test/source/tests/page-recipe/setup-page-recipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Config, Util } from '../../util';

import { ControllablePage } from '../../browser';
import { PageRecipe } from './abstract-page-recipe';
import { SettingsPageRecipe } from './settings-page-recipe';
import { SavePassphraseChecks, SettingsPageRecipe } from './settings-page-recipe';
import { expect } from 'chai';

type ManualEnterOpts = {
Expand All @@ -22,31 +22,21 @@ type ManualEnterOpts = {
key?: { title: string, passphrase: string, armored: string | null, longid: string | null, filePath?: string }
};

type ManualEnterChecks = {
isSavePassphraseDisabled?: boolean | undefined,
isSavePassphraseChecked?: boolean | undefined
};

type CreateKeyOpts = {
key?: { passphrase: string },
usedPgpBefore?: boolean,
submitPubkey?: boolean,
enforcedAlgo?: string | boolean,
};

type CreateKeyChecks = {
isSavePassphraseDisabled?: boolean | undefined,
isSavePassphraseChecked?: boolean | undefined
};

export class SetupPageRecipe extends PageRecipe {

public static createKey = async (
settingsPage: ControllablePage,
keyTitle: string,
backup: 'none' | 'email' | 'file' | 'disabled',
{ usedPgpBefore = false, submitPubkey = false, enforcedAlgo = false, key }: CreateKeyOpts = {},
checks: CreateKeyChecks = {}
checks: SavePassphraseChecks = {}
) => {
await SetupPageRecipe.createBegin(settingsPage, keyTitle, { key, usedPgpBefore });
if (enforcedAlgo) {
Expand Down Expand Up @@ -108,7 +98,7 @@ export class SetupPageRecipe extends PageRecipe {
noPubSubmitRule = false,
key,
}: ManualEnterOpts = {},
checks: ManualEnterChecks = {}
checks: SavePassphraseChecks = {}
) {
if (!noPrvCreateOrgRule) {
if (usedPgpBefore) {
Expand Down
24 changes: 22 additions & 2 deletions test/source/tests/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,8 @@ export let defineSettingsTests = (testVariant: TestVariant, testWithBrowser: Tes
}));

ava.default('settings - add unprotected key', testWithBrowser('ci.tests.gmail', async (t, browser) => {
await SettingsPageRecipe.addKeyTest(t, browser, 'ci.tests.gmail@flowcrypt.test', testConstants.unprotectedPrvKey, 'this is a new passphrase to protect previously unprotected key');
await SettingsPageRecipe.addKeyTest(t, browser, 'ci.tests.gmail@flowcrypt.test', testConstants.unprotectedPrvKey, 'this is a new passphrase to protect previously unprotected key',
{ isSavePassphraseChecked: true, isSavePassphraseDisabled: false });
}));

ava.default('settings - error modal when page parameter invalid', testWithBrowser('ci.tests.gmail', async (t, browser) => {
Expand All @@ -448,7 +449,8 @@ export let defineSettingsTests = (testVariant: TestVariant, testWithBrowser: Tes
}, { isSavePassphraseChecked: false, isSavePassphraseDisabled: false });
await settingsPage1.close();

await SettingsPageRecipe.addKeyTest(t, browser, acctEmail, testConstants.testKeyMultiple98acfa1eadab5b92, '1234');
await SettingsPageRecipe.addKeyTest(t, browser, acctEmail, testConstants.testKeyMultiple98acfa1eadab5b92, '1234',
{ isSavePassphraseChecked: true, isSavePassphraseDisabled: false });

const settingsPage = await browser.newPage(t, TestUrls.extensionSettings(acctEmail));
await SettingsPageRecipe.toggleScreen(settingsPage, 'additional');
Expand Down Expand Up @@ -579,6 +581,24 @@ export let defineSettingsTests = (testVariant: TestVariant, testWithBrowser: Tes
await settingsPage.close();
}));

ava.default('settings - adding a key honors FORBID_STORING_PASS_PHRASE OrgRule', testWithBrowser(undefined, async (t, browser) => {
const { acctEmail, settingsPage } = await BrowserRecipe.setUpFcForbidPpStoringAcct(t, browser);
const { cryptup_userforbidstoringpassphraseorgruleflowcrypttest_passphrase_B8F687BCDE14435A: savedPassphrase1,
cryptup_userforbidstoringpassphraseorgruleflowcrypttest_keys: keys1 }
= await settingsPage.getFromLocalStorage(['cryptup_userforbidstoringpassphraseorgruleflowcrypttest_passphrase_B8F687BCDE14435A',
'cryptup_userforbidstoringpassphraseorgruleflowcrypttest_keys']);
expect((keys1 as KeyInfo[])[0].longid).to.equal('B8F687BCDE14435A');
expect(savedPassphrase1).to.be.an('undefined');
await SettingsPageRecipe.addKeyTest(t, browser, acctEmail, testConstants.testKeyMultiple98acfa1eadab5b92, '1234',
{ isSavePassphraseChecked: false, isSavePassphraseDisabled: true });
const { cryptup_userforbidstoringpassphraseorgruleflowcrypttest_passphrase_98ACFA1EADAB5B92: savedPassphrase2,
cryptup_userforbidstoringpassphraseorgruleflowcrypttest_keys: keys2 }
= await settingsPage.getFromLocalStorage(['cryptup_userforbidstoringpassphraseorgruleflowcrypttest_passphrase_98ACFA1EADAB5B92',
'cryptup_userforbidstoringpassphraseorgruleflowcrypttest_keys']);
expect((keys2 as KeyInfo[]).map(ki => ki.longid)).to.include.members(['B8F687BCDE14435A', '98ACFA1EADAB5B92']);
expect(savedPassphrase2).to.be.an('undefined');
}));

ava.todo('settings - change passphrase - mismatch curent pp');

ava.todo('settings - change passphrase - mismatch new pp');
Expand Down