diff --git a/extension/chrome/settings/modules/add_key.htm b/extension/chrome/settings/modules/add_key.htm
index ed83aad4edc..770a105099c 100644
--- a/extension/chrome/settings/modules/add_key.htm
+++ b/extension/chrome/settings/modules/add_key.htm
@@ -50,7 +50,7 @@
Add Private Key
diff --git a/extension/chrome/settings/modules/add_key.ts b/extension/chrome/settings/modules/add_key.ts
index 5d4aa834b71..b2f45cc94e8 100644
--- a/extension/chrome/settings/modules/add_key.ts
+++ b/extension/chrome/settings/modules/add_key.ts
@@ -16,6 +16,8 @@ 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 {
@@ -23,6 +25,7 @@ View.run(class AddKeyView extends View {
private readonly parentTabId: string;
private readonly keyImportUi = new KeyImportUi({ rejectKnown: true });
private readonly gmail: Gmail;
+ private orgRules!: OrgRules;
constructor() {
super();
@@ -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..');
@@ -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) {
diff --git a/test/source/tests/flaky.ts b/test/source/tests/flaky.ts
index 2484dbee4e9..55dc0ec413f 100644
--- a/test/source/tests/flaky.ts
+++ b/test/source/tests/flaky.ts
@@ -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 });
diff --git a/test/source/tests/page-recipe/settings-page-recipe.ts b/test/source/tests/page-recipe/settings-page-recipe.ts
index 09ca797e605..bbac65d3226 100644
--- a/test/source/tests/page-recipe/settings-page-recipe.ts
+++ b/test/source/tests/page-recipe/settings-page-recipe.ts
@@ -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) => {
@@ -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);
diff --git a/test/source/tests/page-recipe/setup-page-recipe.ts b/test/source/tests/page-recipe/setup-page-recipe.ts
index c45222b328e..2ee47bc3872 100644
--- a/test/source/tests/page-recipe/setup-page-recipe.ts
+++ b/test/source/tests/page-recipe/setup-page-recipe.ts
@@ -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 = {
@@ -22,11 +22,6 @@ 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,
@@ -34,11 +29,6 @@ type CreateKeyOpts = {
enforcedAlgo?: string | boolean,
};
-type CreateKeyChecks = {
- isSavePassphraseDisabled?: boolean | undefined,
- isSavePassphraseChecked?: boolean | undefined
-};
-
export class SetupPageRecipe extends PageRecipe {
public static createKey = async (
@@ -46,7 +36,7 @@ export class SetupPageRecipe extends PageRecipe {
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) {
@@ -108,7 +98,7 @@ export class SetupPageRecipe extends PageRecipe {
noPubSubmitRule = false,
key,
}: ManualEnterOpts = {},
- checks: ManualEnterChecks = {}
+ checks: SavePassphraseChecks = {}
) {
if (!noPrvCreateOrgRule) {
if (usedPgpBefore) {
diff --git a/test/source/tests/settings.ts b/test/source/tests/settings.ts
index 4df274b1000..7cc65c1f66a 100644
--- a/test/source/tests/settings.ts
+++ b/test/source/tests/settings.ts
@@ -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) => {
@@ -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');
@@ -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');