Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into issue-3324-openpgp-v5
Browse files Browse the repository at this point in the history
  • Loading branch information
Roman Shevchenko committed Dec 21, 2022
2 parents 5197b5a + f560490 commit 45c2d40
Show file tree
Hide file tree
Showing 127 changed files with 3,781 additions and 1,945 deletions.
43 changes: 13 additions & 30 deletions .semaphore/semaphore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@ agent:
machine:
type: e1-standard-8
os_image: ubuntu1804

auto_cancel: # cancel running CI for older commits on same branch if new commits are added
auto_cancel:
running:
when: "branch != 'master'"

when: branch != 'master'
blocks:

- name: Tests
dependencies: []
execution_time_limit:
Expand All @@ -28,53 +25,37 @@ blocks:
- mkdir ~/git && checkout && mv ~/test-secrets.json ~/git/flowcrypt-browser/test/test-secrets.json
- cd ~/git/flowcrypt-browser
- npm install
- echo "NODE=$(node --version), NPM=$(npm --version), TSC=$( ./node_modules/typescript/bin/tsc --version)"
- 'echo "NODE=$(node --version), NPM=$(npm --version), TSC=$( ./node_modules/typescript/bin/tsc --version)"'
- npm run-script pretest
- sudo sh -c "echo '209.250.232.81 cron.flowcrypt.com' >> /etc/hosts"
- sudo sh -c "echo '127.0.0.1 fes.google.mock.flowcryptlocal.test' >> /etc/hosts"
- sudo sh -c "echo '127.0.0.1 google.mock.flowcryptlocal.test' >> /etc/hosts"
- sudo sh -c "echo '127.0.0.1 fes.standardsubdomainfes.test' >> /etc/hosts"
- sudo sh -c "echo '127.0.0.1 standardsubdomainfes.test' >> /etc/hosts"
- sudo sh -c "echo '127.0.0.1 fes.disablefesaccesstoken.test' >> /etc/hosts"

jobs:

- name: code quality
commands:
- npm run-script test_tslint
- npm run-script test_eslint
- npm run-script test_stylelint
- npm run-script test_patterns

- name: internals
commands:
- npm run-script test_async_stack
- npm run-script test_buf

- name: consumer mock - unit tests
commands:
- npm run-script test_local_unit_consumer

- name: consumer mock - standard test group
commands:
- npm -v
- node -v
- npm run-script test_ci_chrome_consumer

- name: consumer mock - flaky test group
commands:
- npm run-script test_ci_chrome_consumer_flaky

- name: enterprise mock - unit tests
commands:
- npm run-script test_local_unit_enterprise

- name: enterprise mock - standard test group
commands:
- npm run-script test_ci_chrome_enterprise
- cd ./build && zip -r ~/chrome-enterprise.zip ./chrome-enterprise/* && cd ~
# - if [ "$SEMAPHORE_GIT_BRANCH" = master ]; artifact push project chrome-enterprise.zip --force; fi

epilogue:
on_fail:
commands:
Expand All @@ -86,7 +67,7 @@ blocks:
- name: Live Gmail tests
dependencies: []
run:
when: "branch = 'master' OR branch =~ 'live-test' OR branch =~ 'gmail-test'"
when: branch = 'master' OR branch =~ 'live-test' OR branch =~ 'gmail-test'
execution_time_limit:
minutes: 20
task:
Expand All @@ -102,15 +83,17 @@ blocks:
- npm install -g [email protected] && mkdir ~/git && checkout && mv ~/test-secrets.json ~/git/flowcrypt-browser/test/test-secrets.json
- cd ~/git/flowcrypt-browser
- npm install
- echo "NODE=$(node --version), NPM=$(npm --version), TSC=$( ./node_modules/typescript/bin/tsc --version)"
- 'echo "NODE=$(node --version), NPM=$(npm --version), TSC=$( ./node_modules/typescript/bin/tsc --version)"'
- npm run-script pretest
- sudo sh -c "echo '209.250.232.81 cron.flowcrypt.com' >> /etc/hosts"
- sudo sh -c "echo '127.0.0.1 fes.google.mock.flowcryptlocal.test' >> /etc/hosts"
- sudo sh -c "echo '127.0.0.1 google.mock.flowcryptlocal.test' >> /etc/hosts"
- sudo sh -c "echo '127.0.0.1 fes.standardsubdomainfes.test' >> /etc/hosts"
- sudo sh -c "echo '127.0.0.1 standardsubdomainfes.test' >> /etc/hosts"
- sudo sh -c "echo '127.0.0.1 fes.disablefesaccesstoken.test' >> /etc/hosts"
jobs:
- name: Live Gmail tests
commands:
- npm run-script test_ci_chrome_consumer_live_gmail
epilogue:
on_fail:
commands:
- |
if [ -f build/test/test/debugArtifacts/debugHtmlAttachment-0.html ]; then
echo "Uploading debug files as job artifacts..."
artifact push job build/test/test/debugArtifacts/debugHtmlAttachment-0.html
fi
4 changes: 4 additions & 0 deletions extension/changelog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<div class="lightboxed">

version 8.4.0 on November 18, 2022: : <a href="https://github.com/FlowCrypt/flowcrypt-browser/milestone/463?closed=1" target="_blank">Pwd msg prompt fix, add self-sig key</a>

version 8.3.9 on November 8, 2022: : <a href="https://github.com/FlowCrypt/flowcrypt-browser/milestone/464?closed=1" target="_blank">Reply improvements</a>

version 8.3.8 on September 22, 2022: <a href="https://github.com/FlowCrypt/flowcrypt-browser/milestone/461?closed=1" target="_blank">Stop using legacy pub submit</a>

version 8.3.7 on September 20, 2022: <a href="https://github.com/FlowCrypt/flowcrypt-browser/milestone/462?closed=1" target="_blank">Reauth fix, EKM removals, configurable pp session</a>
Expand Down
6 changes: 3 additions & 3 deletions extension/chrome/elements/add_pubkey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ View.run(class AddPubkeyView extends View {
Xss.sanitizeAppend('select.copy_from_email', `<option value="${escapedEmail}">${escapedEmail}</option>`);
}
this.fetchKeyUi.handleOnPaste($('.pubkey'));
$('.action_settings').click(this.setHandler(async () => await Browser.openSettingsPage('index.htm', this.acctEmail, '/chrome/settings/modules/contacts.htm')));
$('.action_settings').on('click', this.setHandler(async () => await Browser.openSettingsPage('index.htm', this.acctEmail, '/chrome/settings/modules/contacts.htm')));
};

public setHandlers = () => {
Expand All @@ -68,8 +68,8 @@ View.run(class AddPubkeyView extends View {
}
});
$('select.copy_from_email').change(this.setHandler((el) => this.copyFromEmailHandler(el)));
$('.action_ok').click(this.setHandler(() => this.submitHandler()));
$('.action_close').click(this.setHandler(() => this.closeDialog()));
$('.action_ok').on('click', this.setHandler(() => this.submitHandler()));
$('.action_close').on('click', this.setHandler(() => this.closeDialog()));
};

private closeDialog = () => {
Expand Down
8 changes: 4 additions & 4 deletions extension/chrome/elements/attachment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ export class AttachmentDownloadView extends View {
public setHandlers = () => {
Ui.event.protect();
if (this.canClickOnAttachment) {
this.downloadButton.click(this.setHandlerPrevent('double', () => this.downloadButtonClickedHandler()));
this.downloadButton.click((e) => e.stopPropagation());
$('body').click(async () => {
this.downloadButton.on('click', this.setHandlerPrevent('double', () => this.downloadButtonClickedHandler()));
this.downloadButton.on('click', (e) => e.stopPropagation());
$('body').on('click', async () => {
if ($('body').attr('id') !== 'attachment-preview' && !$('body').hasClass('error-occured')) {
await this.previewAttachmentClickedHandler();
}
Expand Down Expand Up @@ -285,7 +285,7 @@ export class AttachmentDownloadView extends View {
.html(`<div>Failed to decrypt:</div><a href="#" data-test="decrypt-error-details" class="see-error-details">see error details</a><br><div>Downloading original…`) // xss-escaped
.addClass('error-occured')
.attr('title', '');
$('.see-error-details').click(async () => {
$('.see-error-details').on('click', async () => {
await this.previewAttachmentClickedHandler(true);
});
const name = this.attachment.name;
Expand Down
4 changes: 2 additions & 2 deletions extension/chrome/elements/attachment_preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ View.run(class AttachmentPreviewView extends AttachmentDownloadView {
$('.attachment-preview-unavailable').prepend('No preview available'); // xss-escaped
$('#attachment-preview-download').appendTo('.attachment-preview-unavailable');
}
$('body').click((e) => {
$('body').on('click', (e) => {
if (e.target === document.body || $('body').children().toArray().indexOf(e.target) !== -1) {
BrowserMsg.send.closeDialog(this.parentTabId);
}
});
$('#attachment-preview-download').css('display', 'flex').click((e) => {
$('#attachment-preview-download').css('display', 'flex').on('click', (e) => {
e.stopPropagation();
Browser.saveToDownloads(attachmentForSave);
});
Expand Down
2 changes: 1 addition & 1 deletion extension/chrome/elements/backup.htm
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<div class="line">This backup is protected by your pass phrase. Please make sure
to note your pass phrase down or you may lose access to your encrypted emails!</div>
<div class="line">
<input class="input_pass_phrase" type="password" id="pass_phrase" placeholder="Enter your pass phrase..." />
<input class="input_pass_phrase" type="password" id="pass_phrase" placeholder="Enter your pass phrase..." maxlength="256" />
<button class="button green action_test_pass">Test your Passphrase</button>
</div>
<div class="line fingerprints hide_if_compact">Key Fingerprint: <span class="fingerprint good"></span></div>
Expand Down
4 changes: 2 additions & 2 deletions extension/chrome/elements/backup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ View.run(class BackupView extends View {

public setHandlers = () => {
if (!this.storedPrvWithMatchingLongid) {
$("#action_import_key").click(this.setHandler(async () => await Browser.openSettingsPage('index.htm', this.acctEmail, '/chrome/settings/modules/add_key.htm')));
$("#action_import_key").on('click', this.setHandler(async () => await Browser.openSettingsPage('index.htm', this.acctEmail, '/chrome/settings/modules/add_key.htm')));
}
$('.action_test_pass').click(this.setHandler(async () => this.testPassphraseHandler()));
$('.action_test_pass').on('click', this.setHandler(async () => this.testPassphraseHandler()));
$('#pass_phrase').keydown(this.setEnterHandlerThatClicks('.action_test_pass'));
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class ComposeDraftModule extends ViewModule<ComposeView> {
}

public setHandlers = () => {
$('.delete_draft').click(this.view.setHandler(() => this.deleteDraftClickHandler(), this.view.errModule.handle('delete draft')));
$('.delete_draft').on('click', this.view.setHandler(() => this.deleteDraftClickHandler(), this.view.errModule.handle('delete draft')));
this.view.recipientsModule.onRecipientAdded(async () => await this.draftSave(true));
};

Expand Down Expand Up @@ -363,10 +363,10 @@ export class ComposeDraftModule extends ViewModule<ComposeView> {
`).css({ display: 'flex', height: '100%' });
BrowserMsg.send.setActiveWindow(this.view.parentTabId, { frameId: this.view.frameId });
}
this.view.S.cached('prompt').find('.action_open_passphrase_dialog').click(this.view.setHandler(async () => {
this.view.S.cached('prompt').find('.action_open_passphrase_dialog').on('click', this.view.setHandler(async () => {
BrowserMsg.send.passphraseDialog(this.view.parentTabId, { type: 'draft', longids });
})).focus();
this.view.S.cached('prompt').find('.action_close').click(this.view.setHandler(() => this.view.renderModule.closeMsg()));
this.view.S.cached('prompt').find('.action_close').on('click', this.view.setHandler(() => this.view.renderModule.closeMsg()));
const setActiveWindow = this.view.setHandler(async () => { BrowserMsg.send.setActiveWindow(this.view.parentTabId, { frameId: this.view.frameId }); });
this.view.S.cached('prompt').on('click', setActiveWindow).trigger('click');
await PassphraseStore.waitUntilPassphraseChanged(this.view.acctEmail, longids, 1000, this.view.ppChangedPromiseCancellation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export class ComposeErrModule extends ViewModule<ComposeView> {
await Ui.modal.error(netErrMsg, true);
} else if (ApiErr.isAuthErr(e)) {
BrowserMsg.send.notificationShowAuthPopupNeeded(this.view.parentTabId, { acctEmail: this.view.acctEmail });
Settings.offerToLoginWithPopupShowModalOnErr(this.view.acctEmail);
Settings.offerToLoginWithPopupShowModalOnErr(this.view.acctEmail, () => this.view.sendBtnModule.extractProcessSendMsg());
} else if (ApiErr.isReqTooLarge(e)) {
await Ui.modal.error(`Could not send: message or attachments too large.`);
} else if (ApiErr.isBadReq(e)) {
Expand Down Expand Up @@ -151,7 +151,11 @@ export class ComposeErrModule extends ViewModule<ComposeView> {
}
};

public throwIfEncryptionPasswordInvalid = async ({ subject, pwd }: { subject: string, pwd?: string }) => {
public throwIfEncryptionPasswordInvalidOrDisabled = async ({ subject, pwd }: { subject: string, pwd?: string }) => {
// When DISABLE_FLOWCRYPT_HOSTED_PASSWORD_MESSAGES present, and recipients are missing a public key, and the user is using flowcrypt.com/api (not FES)
if (this.view.clientConfiguration.shouldDisablePasswordMessages() && !this.view.isFesUsed()) {
throw new ComposerUserError(Lang.compose.addMissingRecipientPubkeys);
}
if (pwd) {
if (await this.view.storageModule.isPwdMatchingPassphrase(pwd)) {
throw new ComposerUserError('Please do not use your private key pass phrase as a password for this message.\n\n' +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class ComposeInputModule extends ViewModule<ComposeView> {
public squire = new window.Squire(this.view.S.cached('input_text').get(0));

public setHandlers = () => {
this.view.S.cached('add_intro').click(this.view.setHandler(el => this.actionAddIntroHandler(el), this.view.errModule.handle(`add intro`)));
this.view.S.cached('add_intro').on('click', this.view.setHandler(el => this.actionAddIntroHandler(el), this.view.errModule.handle(`add intro`)));
this.handlePaste();
this.handlePasteImages();
this.initShortcuts();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class ComposeMyPubkeyModule extends ViewModule<ComposeView> {

public setHandlers = () => {
this.view.S.cached('icon_pubkey').attr('title', Lang.compose.includePubkeyIconTitle);
this.view.S.cached('icon_pubkey').click(this.view.setHandler((el) => this.iconPubkeyClickHandler(el), this.view.errModule.handle(`set/unset pub attachment`)));
this.view.S.cached('icon_pubkey').on('click', this.view.setHandler((el) => this.iconPubkeyClickHandler(el), this.view.errModule.handle(`set/unset pub attachment`)));
};

public iconPubkeyClickHandler = (target: HTMLElement) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,27 @@ export class ComposePwdOrPubkeyContainerModule extends ViewModule<ComposeView> {
}

public setHandlers = () => {
this.view.S.cached('input_password').keyup(this.view.setHandlerPrevent('spree', () => this.showHideContainerAndColorSendBtn()));
this.view.S.cached('input_password').focus(this.view.setHandlerPrevent('spree', () => this.inputPwdFocusHandler()));
this.view.S.cached('input_password').blur(this.view.setHandler(() => this.inputPwdBlurHandler()));
this.view.S.cached('expiration_note').find('#expiration_note_settings_link').click(this.view.setHandler(async (el, e) => {
e.preventDefault();
await this.view.renderModule.openSettingsWithDialog('security');
}, this.view.errModule.handle(`render settings dialog`)));
this.view.S.cached('input_password').on('focus', this.view.setHandlerPrevent('spree', () => this.inputPwdFocusHandler()));
this.view.S.cached('input_password').on('blur', this.view.setHandler(() => this.inputPwdBlurHandler()));
this.view.S.cached('expiration_note').find('#expiration_note_settings_link').on(
'click',
this.view.setHandler(async (el, e) => {
e.preventDefault();
await this.view.renderModule.openSettingsWithDialog('security');
}, this.view.errModule.handle(`render settings dialog`))
);
};

public inputPwdFocusHandler = () => {
const passwordContainerHeight = this.view.S.cached('password_or_pubkey').outerHeight() || 0;
this.view.S.cached('expiration_note').css({ bottom: passwordContainerHeight });
this.view.S.cached('expiration_note').fadeIn();
this.showHideContainerAndColorSendBtn(); // tslint:disable-line:no-floating-promises
};

public inputPwdBlurHandler = () => {
Catch.setHandledTimeout(() => { // timeout here is needed so <a> will be visible once clicked
this.view.S.cached('expiration_note').fadeOut();
}, 100);
this.showHideContainerAndColorSendBtn(); // tslint:disable-line:no-floating-promises
};

public showHideContainerAndColorSendBtn = async () => {
Expand Down Expand Up @@ -99,47 +99,46 @@ export class ComposePwdOrPubkeyContainerModule extends ViewModule<ComposeView> {
return true;
};

private initExpirationText = async () => {
// Init expiration text element
const expirationTextEl = this.view.S.cached('expiration_note').find('#expiration_note_message_expire');
const pwdPolicy = this.view.fesUrl ? Lang.compose.enterprisePasswordPolicy : Lang.compose.consumerPasswordPolicy;
$('#password-policy-container').html(Xss.htmlSanitize(pwdPolicy.split('\n').join('<br />'))); // xss-sanitized
if (!this.view.acctEmail) {
expirationTextEl.text(Str.pluralize(this.MSG_EXPIRE_DAYS_DEFAULT, 'day'));
} else {
try {
const response = await this.view.acctServer.accountGetAndUpdateLocalStore();
expirationTextEl.text(Str.pluralize(response.account.default_message_expire, 'day'));
} catch (e) {
ApiErr.reportIfSignificant(e);
expirationTextEl.text(`(unknown days: ${ApiErr.eli5(e)})`);
}
}
};

private showMsgPwdUiAndColorBtn = async (anyNopgp: boolean, anyRevoked: boolean) => {
const isPasswordMessageDisabled = this.view.clientConfiguration.shouldDisablePasswordMessages() && !this.view.isFesUsed();
if (!this.isVisible()) {
const expirationTextEl = this.view.S.cached('expiration_note').find('#expiration_note_message_expire');
const pwdPolicy = this.view.fesUrl ? Lang.compose.enterprisePasswordPolicy : Lang.compose.consumerPasswordPolicy;
$('#password-policy-container').html(Xss.htmlSanitize(pwdPolicy.split('\n').join('<br />'))); // xss-sanitized
if (!this.view.acctEmail) {
expirationTextEl.text(Str.pluralize(this.MSG_EXPIRE_DAYS_DEFAULT, 'day'));
} else {
try {
const response = await this.view.acctServer.accountGetAndUpdateLocalStore();
expirationTextEl.text(Str.pluralize(response.account.default_message_expire, 'day'));
} catch (e) {
ApiErr.reportIfSignificant(e);
expirationTextEl.text(`(unknown days: ${ApiErr.eli5(e)})`);
}
}
await this.initExpirationText();
this.view.S.cached('password_or_pubkey').css('display', 'table-row');
}
if (this.view.S.cached('input_password').val() || this.view.S.cached('input_password').is(':focus')) {
this.view.S.cached('password_label').css('display', 'inline-block');
this.view.S.cached('input_password').attr('placeholder', '');
} else {
this.view.S.cached('password_label').css('display', 'none');
this.view.S.cached('input_password').attr('placeholder', 'message password');
}
if (this.view.S.cached('input_intro').is(':visible')) {
this.view.S.cached('add_intro').css('display', 'none');
if (isPasswordMessageDisabled) {
this.view.S.cached('password_input_container').hide();
} else {
this.view.S.cached('add_intro').css('display', 'block');
this.view.S.cached('add_intro').show();
}
this.view.S.cached('warning_nopgp').css('display', anyNopgp ? 'inline-block' : 'none');
this.view.S.cached('warning_revoked').css('display', anyRevoked ? 'inline-block' : 'none');
this.view.sizeModule.setInputTextHeightManuallyIfNeeded();
};

private hideMsgPwdUi = () => {
this.view.S.cached('password_or_pubkey').css('display', 'none');
this.view.S.cached('password_or_pubkey').hide();
this.view.S.cached('input_password').val('');
this.view.S.cached('add_intro').css('display', 'none');
this.view.S.cached('add_intro').hide();
this.view.S.cached('input_intro').text('');
this.view.S.cached('intro_container').css('display', 'none');
this.view.S.cached('intro_container').hide();
this.view.sizeModule.setInputTextHeightManuallyIfNeeded();
};

Expand Down
Loading

0 comments on commit 45c2d40

Please sign in to comment.