From a7c8b163713c9b6600c648d528f728d1f998a170 Mon Sep 17 00:00:00 2001 From: Roma Sosnovsky Date: Fri, 21 Jan 2022 17:09:51 +0200 Subject: [PATCH 01/12] #1618 add message password validation --- .../Compose/ComposeViewController.swift | 3 +- .../ComposeMessageError.swift | 9 +++++ .../ComposeMessageService.swift | 40 +++++++++++++++++++ .../Resources/en.lproj/Localizable.strings | 3 ++ .../Extensions/StringExtensions.swift | 2 +- 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/FlowCrypt/Controllers/Compose/ComposeViewController.swift b/FlowCrypt/Controllers/Compose/ComposeViewController.swift index 5c33fb595..905e9ec21 100644 --- a/FlowCrypt/Controllers/Compose/ComposeViewController.swift +++ b/FlowCrypt/Controllers/Compose/ComposeViewController.swift @@ -118,7 +118,8 @@ final class ComposeViewController: TableNodeViewController { self.composeMessageService = composeMessageService ?? ComposeMessageService( clientConfiguration: clientConfiguration, encryptedStorage: appContext.encryptedStorage, - messageGateway: appContext.getRequiredMailProvider().messageSender + messageGateway: appContext.getRequiredMailProvider().messageSender, + passPhraseService: appContext.passPhraseService ) self.filesManager = filesManager self.photosManager = photosManager diff --git a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageError.swift b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageError.swift index c464947aa..6ec7bd56b 100644 --- a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageError.swift +++ b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageError.swift @@ -12,6 +12,9 @@ enum MessageValidationError: Error, CustomStringConvertible, Equatable { case emptyRecipient case emptySubject case emptyMessage + case weakPassword + case subjectContainsPassword + case notUniquePassword case missedPublicKey case noPubRecipients case revokedKeyRecipients @@ -27,6 +30,12 @@ enum MessageValidationError: Error, CustomStringConvertible, Equatable { return "compose_enter_subject".localized case .emptyMessage: return "compose_enter_secure".localized + case .weakPassword: + return "compose_password_weak".localized + case .subjectContainsPassword: + return "compose_password_subject_error".localized + case .notUniquePassword: + return "compose_password_passphrase_error".localized case .missedPublicKey: return "compose_no_pub_sender".localized case .noPubRecipients: diff --git a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift index b36bca7e4..fad3567d0 100644 --- a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift +++ b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift @@ -22,6 +22,7 @@ protocol CoreComposeMessageType { final class ComposeMessageService { private let messageGateway: MessageGateway + private let passPhraseService: PassPhraseServiceType private let storage: EncryptedStorageType private let contactsService: ContactsServiceType private let core: CoreComposeMessageType & KeyParser @@ -40,12 +41,14 @@ final class ComposeMessageService { clientConfiguration: ClientConfiguration, encryptedStorage: EncryptedStorageType, messageGateway: MessageGateway, + passPhraseService: PassPhraseServiceType, draftGateway: DraftGateway? = nil, contactsService: ContactsServiceType? = nil, core: CoreComposeMessageType & KeyParser = Core.shared, enterpriseServer: EnterpriseServerApiType = EnterpriseServerApi() ) { self.messageGateway = messageGateway + self.passPhraseService = passPhraseService self.draftGateway = draftGateway self.storage = encryptedStorage self.contactsService = contactsService ?? ContactsService( @@ -114,6 +117,21 @@ final class ComposeMessageService { let replyToMimeMsg = input.replyToMime .flatMap { String(data: $0, encoding: .utf8) } + if let password = contextToSend.messagePassword, password.isNotEmpty { + if !isMessagePasswordStrong(pwd: password, isFesUsed: true) { + throw MessageValidationError.weakPassword + } + + if subject.lowercased().contains(password.lowercased()) { + throw MessageValidationError.subjectContainsPassword + } + + let storedPassphrases = passPhraseService.getPassPhrases().map(\.value) + if storedPassphrases.contains(password) { + throw MessageValidationError.notUniquePassword + } + } + return SendableMsg( text: text, html: nil, @@ -338,4 +356,26 @@ extension ComposeMessageService { return SendableMsgBody(text: text, html: html) } + + private func isMessagePasswordStrong(pwd: String, isFesUsed: Bool) -> Bool { + let minLength = 8 + + guard isFesUsed else { + // consumers - just 8 chars requirement + return pwd.count >= minLength + } + + // enterprise FES - use common corporate password rules + let predicate = NSPredicate( + format: "SELF MATCHES %@ ", [ + "(?=.*[a-z])", // 1 lowercase character + "(?=.*[A-Z])", // 1 uppercase character + "(?=.*[0-9])", // 1 number + "(?=.*[\\-@$#!%*?&_,;:'()\"])", // 1 special symbol + ".{\(minLength),}$" // minimum 8 characters + ].joined() + ) + + return predicate.evaluate(with: pwd) + } } diff --git a/FlowCrypt/Resources/en.lproj/Localizable.strings b/FlowCrypt/Resources/en.lproj/Localizable.strings index 22f6bf49a..b7d0d3e2d 100644 --- a/FlowCrypt/Resources/en.lproj/Localizable.strings +++ b/FlowCrypt/Resources/en.lproj/Localizable.strings @@ -82,6 +82,9 @@ "compose_recipient_revoked" = "One or more of your recipients have revoked public keys (marked in red).\n\nPlease ask them to send you a new public key. If this is an enterprise installation, please ask your systems admin."; "compose_recipient_expired" = "One or more of your recipients have expired public keys (marked in orange).\n\nPlease ask them to send you updated public key. If this is an enterprise installation, please ask your systems admin."; "compose_recipient_invalid_email" = "One or more of your recipients have invalid email address (marked in red)"; +"compose_password_weak" = "Password didn't comply with company policy, which requires at least:\n\n- one uppercase\n- one lowercase\n- one number\n- one special character eg &\"#-'_%-@,;:!*()\n- 8 characters length\n\nPlease update the password and re-send."; +"compose_password_passphrase_error" = "Please do not use your private key pass phrase as a password for this message.\n\nYou should come up with some other unique password that you can share with recipient."; +"compose_password_subject_error" = "Please do not include the password in the email subject. Sharing password over email undermines password based encryption.\n\nYou can ask the recipient to also install FlowCrypt, messages between FlowCrypt users don't need a password."; "compose_password_placeholder" = "Tap to add password for recipients who don't have encryption set up."; "compose_password_set_message" = "Web portal password added"; "compose_password_modal_title" = "Set web portal password"; diff --git a/FlowCryptCommon/Extensions/StringExtensions.swift b/FlowCryptCommon/Extensions/StringExtensions.swift index bae4bdd32..d75c20202 100644 --- a/FlowCryptCommon/Extensions/StringExtensions.swift +++ b/FlowCryptCommon/Extensions/StringExtensions.swift @@ -6,7 +6,7 @@ import Foundation public extension String { var hasContent: Bool { - trimmingCharacters(in: .whitespaces).isEmpty == false + !trimmingCharacters(in: .whitespacesAndNewlines).isEmpty } var trimLeadingSlash: String { From 993fcff0137484a3bce0ef2f4ac7db5817bdfd57 Mon Sep 17 00:00:00 2001 From: Roma Sosnovsky Date: Mon, 24 Jan 2022 14:02:32 +0200 Subject: [PATCH 02/12] #1618 update ui test for new password errors --- .../Compose/ComposeViewController.swift | 13 +++++++++-- .../ComposeMessageService.swift | 11 +++++---- .../Resources/en.lproj/Localizable.strings | 2 +- appium/tests/data/index.ts | 6 ++++- ...ndEmailToRecipientWithoutPublicKey.spec.ts | 23 +++++++++++++++++++ 5 files changed, 46 insertions(+), 9 deletions(-) diff --git a/FlowCrypt/Controllers/Compose/ComposeViewController.swift b/FlowCrypt/Controllers/Compose/ComposeViewController.swift index 905e9ec21..b423a64e5 100644 --- a/FlowCrypt/Controllers/Compose/ComposeViewController.swift +++ b/FlowCrypt/Controllers/Compose/ComposeViewController.swift @@ -522,8 +522,17 @@ extension ComposeViewController { DispatchQueue.main.asyncAfter(deadline: .now() + hideSpinnerAnimationDuration) { [weak self] in guard let self = self else { return } - if case MessageValidationError.noPubRecipients = error, self.isMessagePasswordSupported { - self.setMessagePassword() + if self.isMessagePasswordSupported { + switch error { + case MessageValidationError.noPubRecipients: + self.setMessagePassword() + case MessageValidationError.notUniquePassword, + MessageValidationError.subjectContainsPassword, + MessageValidationError.weakPassword: + self.showAlert(message: error.errorMessage) + default: + self.showAlert(message: "compose_error".localized + "\n\n" + error.errorMessage) + } } else { self.showAlert(message: "compose_error".localized + "\n\n" + error.errorMessage) } diff --git a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift index fad3567d0..8fb73acaa 100644 --- a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift +++ b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift @@ -118,18 +118,19 @@ final class ComposeMessageService { .flatMap { String(data: $0, encoding: .utf8) } if let password = contextToSend.messagePassword, password.isNotEmpty { - if !isMessagePasswordStrong(pwd: password, isFesUsed: true) { - throw MessageValidationError.weakPassword - } - if subject.lowercased().contains(password.lowercased()) { throw MessageValidationError.subjectContainsPassword } - + let storedPassphrases = passPhraseService.getPassPhrases().map(\.value) if storedPassphrases.contains(password) { throw MessageValidationError.notUniquePassword } + + // TODO: Add FES check + if !isMessagePasswordStrong(pwd: password, isFesUsed: true) { + throw MessageValidationError.weakPassword + } } return SendableMsg( diff --git a/FlowCrypt/Resources/en.lproj/Localizable.strings b/FlowCrypt/Resources/en.lproj/Localizable.strings index b7d0d3e2d..87b1de62a 100644 --- a/FlowCrypt/Resources/en.lproj/Localizable.strings +++ b/FlowCrypt/Resources/en.lproj/Localizable.strings @@ -82,7 +82,7 @@ "compose_recipient_revoked" = "One or more of your recipients have revoked public keys (marked in red).\n\nPlease ask them to send you a new public key. If this is an enterprise installation, please ask your systems admin."; "compose_recipient_expired" = "One or more of your recipients have expired public keys (marked in orange).\n\nPlease ask them to send you updated public key. If this is an enterprise installation, please ask your systems admin."; "compose_recipient_invalid_email" = "One or more of your recipients have invalid email address (marked in red)"; -"compose_password_weak" = "Password didn't comply with company policy, which requires at least:\n\n- one uppercase\n- one lowercase\n- one number\n- one special character eg &\"#-'_%-@,;:!*()\n- 8 characters length\n\nPlease update the password and re-send."; +"compose_password_weak" = "Password didn't comply with company policy, which requires at least:\n\n- one uppercase\n- one lowercase\n- one number\n- one special character eg &/#\"-'_%-@,;:!*()\n- 8 characters length\n\nPlease update the password and re-send."; "compose_password_passphrase_error" = "Please do not use your private key pass phrase as a password for this message.\n\nYou should come up with some other unique password that you can share with recipient."; "compose_password_subject_error" = "Please do not include the password in the email subject. Sharing password over email undermines password based encryption.\n\nYou can ask the recipient to also install FlowCrypt, messages between FlowCrypt users don't need a password."; "compose_password_placeholder" = "Tap to add password for recipients who don't have encryption set up."; diff --git a/appium/tests/data/index.ts b/appium/tests/data/index.ts index 322ef4edc..0e1e268ab 100644 --- a/appium/tests/data/index.ts +++ b/appium/tests/data/index.ts @@ -107,10 +107,14 @@ export const CommonData = { }, recipientWithoutPublicKey: { email: 'no.publickey@flowcrypt.com', - password: '123456', + weakPassword: '123aaBBc', + password: 'abcABC1*', modalMessage: `Set web portal password\nThe recipients will receive a link to read your message on a web portal, where they will need to enter this password.\n\nYou are responsible for sharing this password with recipients (use other medium to share the password - not email)`, emptyPasswordMessage: 'Tap to add password for recipients who don\'t have encryption set up.', addedPasswordMessage: 'Web portal password added', + weakPasswordMessage: 'Error\nPassword didn\'t comply with company policy, which requires at least:\n\n- one uppercase - one lowercase - one number - one special character eg &/#"-\'_%-@,;:!*() - 8 characters length\n\nPlease update the password and re-send.', + passphrasePasswordErrorMessage: 'Error\nPlease do not use your private key pass phrase as a password for this message.\n\nYou should come up with some other unique password that you can share with recipient.', + subjectPasswordErrorMessage: 'Error\nPlease do not include the password in the email subject. Sharing password over email undermines password based encryption.\n\nYou can ask the recipient to also install FlowCrypt, messages between FlowCrypt users don\'t need a password.' }, recipientWithExpiredPublicKey: { email: 'expired@flowcrypt.com' diff --git a/appium/tests/specs/live/composeEmail/SendEmailToRecipientWithoutPublicKey.spec.ts b/appium/tests/specs/live/composeEmail/SendEmailToRecipientWithoutPublicKey.spec.ts index 85cd96577..935d3bc63 100644 --- a/appium/tests/specs/live/composeEmail/SendEmailToRecipientWithoutPublicKey.spec.ts +++ b/appium/tests/specs/live/composeEmail/SendEmailToRecipientWithoutPublicKey.spec.ts @@ -15,10 +15,15 @@ describe('COMPOSE EMAIL: ', () => { const recipient = CommonData.recipientWithoutPublicKey.email; const emailSubject = CommonData.simpleEmail.subject; const emailText = CommonData.simpleEmail.message; + const emailWeakPassword = CommonData.recipientWithoutPublicKey.weakPassword; const emailPassword = CommonData.recipientWithoutPublicKey.password; + const passphrase = CommonData.account.passPhrase; const passwordModalMessage = CommonData.recipientWithoutPublicKey.modalMessage; const emptyPasswordMessage = CommonData.recipientWithoutPublicKey.emptyPasswordMessage; + const weakPasswordMessage = CommonData.recipientWithoutPublicKey.weakPasswordMessage; + const passphrasePasswordErrorMessage = CommonData.recipientWithoutPublicKey.passphrasePasswordErrorMessage; + const subjectPasswordErrorMessage = CommonData.recipientWithoutPublicKey.subjectPasswordErrorMessage; const addedPasswordMessage = CommonData.recipientWithoutPublicKey.addedPasswordMessage; await SplashScreen.login(); @@ -41,6 +46,24 @@ describe('COMPOSE EMAIL: ', () => { await NewMessageScreen.clickCancelButton(); await NewMessageScreen.checkPasswordCell(emptyPasswordMessage); + await NewMessageScreen.clickPasswordCell(); + await NewMessageScreen.setMessagePassword(emailSubject); + await NewMessageScreen.clickSendButton(); + await BaseScreen.checkModalMessage(subjectPasswordErrorMessage); + await BaseScreen.clickOkButtonOnError(); + + await NewMessageScreen.clickPasswordCell(); + await NewMessageScreen.setMessagePassword(passphrase); + await NewMessageScreen.clickSendButton(); + await BaseScreen.checkModalMessage(passphrasePasswordErrorMessage); + await BaseScreen.clickOkButtonOnError(); + + await NewMessageScreen.clickPasswordCell(); + await NewMessageScreen.setMessagePassword(emailWeakPassword); + await NewMessageScreen.clickSendButton(); + await BaseScreen.checkModalMessage(weakPasswordMessage); + await BaseScreen.clickOkButtonOnError(); + await NewMessageScreen.clickPasswordCell(); await NewMessageScreen.setMessagePassword(emailPassword); await NewMessageScreen.checkPasswordCell(addedPasswordMessage); From c20e16ff95a8894f9e1019aed4b48d02bb03da85 Mon Sep 17 00:00:00 2001 From: Roma Sosnovsky Date: Mon, 24 Jan 2022 14:37:28 +0200 Subject: [PATCH 03/12] #1618 add fes check --- FlowCrypt/Controllers/Compose/ComposeViewController.swift | 7 ++++--- .../Compose Message Service/ComposeMessageService.swift | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/FlowCrypt/Controllers/Compose/ComposeViewController.swift b/FlowCrypt/Controllers/Compose/ComposeViewController.swift index b423a64e5..0c7fd1fa5 100644 --- a/FlowCrypt/Controllers/Compose/ComposeViewController.swift +++ b/FlowCrypt/Controllers/Compose/ComposeViewController.swift @@ -966,9 +966,10 @@ extension ComposeViewController { } } - private func handleEvaluation(for recipient: ComposeMessageRecipient, - with state: RecipientState, - keyState: PubKeyState?) { + private func handleEvaluation( + for recipient: ComposeMessageRecipient, + with state: RecipientState, + keyState: PubKeyState?) { updateRecipientWithNew( state: state, keyState: keyState, diff --git a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift index 8fb73acaa..8086317af 100644 --- a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift +++ b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift @@ -127,8 +127,9 @@ final class ComposeMessageService { throw MessageValidationError.notUniquePassword } - // TODO: Add FES check - if !isMessagePasswordStrong(pwd: password, isFesUsed: true) { + let fesUrl = try await enterpriseServer.getActiveFesUrl(for: email) + let isFesUsed = fesUrl != nil + if !isMessagePasswordStrong(pwd: password, isFesUsed: isFesUsed) { throw MessageValidationError.weakPassword } } From fb31c4f919ab6fa59d270d7570748f517c692416 Mon Sep 17 00:00:00 2001 From: Roma Sosnovsky Date: Mon, 24 Jan 2022 15:27:42 +0200 Subject: [PATCH 04/12] fix unit tests --- .../ComposeMessageService.swift | 1 + FlowCryptAppTests/ExtensionTests.swift | 10 ++++++---- .../Services/ComposeMessageServiceTests.swift | 1 + 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift index 8086317af..72de393b0 100644 --- a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift +++ b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift @@ -362,6 +362,7 @@ extension ComposeMessageService { private func isMessagePasswordStrong(pwd: String, isFesUsed: Bool) -> Bool { let minLength = 8 + // currently password-protected messages are supported only with FES on iOS guard isFesUsed else { // consumers - just 8 chars requirement return pwd.count >= minLength diff --git a/FlowCryptAppTests/ExtensionTests.swift b/FlowCryptAppTests/ExtensionTests.swift index 667482586..f16663e97 100644 --- a/FlowCryptAppTests/ExtensionTests.swift +++ b/FlowCryptAppTests/ExtensionTests.swift @@ -82,19 +82,21 @@ extension ExtensionTests { dateFormatter.dateFormat = "HH:mm" let today = Date() - let year = Calendar.current.dateComponents([.year], from: today).year + let components = Calendar.current.dateComponents([.year, .day], from: today) + let day = components.day == 24 ? 23 : components.day! + let sameYearDate = try XCTUnwrap(DateComponents( calendar: .current, timeZone: .current, - year: year, + year: components.year, month: 1, - day: 24 + day: day ).date) // Jan 24, 2020 let otherYearDate = Date(timeIntervalSince1970: 1579883652) XCTAssertTrue(dateFormatter.date(from: DateFormatter().formatDate(sameDayDate)) != nil) - XCTAssertEqual(DateFormatter().formatDate(sameYearDate), "Jan 24") + XCTAssertEqual(DateFormatter().formatDate(sameYearDate), "Jan \(day)") XCTAssertEqual(DateFormatter().formatDate(otherYearDate), "Jan 24, 2020") } } diff --git a/FlowCryptAppTests/Functionality/Services/ComposeMessageServiceTests.swift b/FlowCryptAppTests/Functionality/Services/ComposeMessageServiceTests.swift index 95c86847e..dbe106b18 100644 --- a/FlowCryptAppTests/Functionality/Services/ComposeMessageServiceTests.swift +++ b/FlowCryptAppTests/Functionality/Services/ComposeMessageServiceTests.swift @@ -43,6 +43,7 @@ class ComposeMessageServiceTests: XCTestCase { ), encryptedStorage: encryptedStorage, messageGateway: MessageGatewayMock(), + passPhraseService: PassPhraseServiceMock(), draftGateway: DraftGatewayMock(), contactsService: contactsService, core: core From 4f1db12dfdb7ab8bd4ed0b86140170e9326a4a3b Mon Sep 17 00:00:00 2001 From: Roma Sosnovsky Date: Tue, 25 Jan 2022 15:51:54 +0200 Subject: [PATCH 05/12] #1618 check password strength on typing --- .../Compose/ComposeViewController.swift | 9 +++--- .../Error Handling/ErrorHandler.swift | 2 +- .../ComposeMessageService.swift | 29 +++++++++---------- .../Resources/en.lproj/Localizable.strings | 2 +- FlowCryptAppTests/ExtensionTests.swift | 1 - .../Services/ComposeMessageServiceTests.swift | 16 +--------- appium/tests/data/index.ts | 3 +- .../tests/screenobjects/new-message.screen.ts | 5 ++++ ...ndEmailToRecipientWithoutPublicKey.spec.ts | 16 ++-------- 9 files changed, 30 insertions(+), 53 deletions(-) diff --git a/FlowCrypt/Controllers/Compose/ComposeViewController.swift b/FlowCrypt/Controllers/Compose/ComposeViewController.swift index 0c7fd1fa5..7c9a0b4cb 100644 --- a/FlowCrypt/Controllers/Compose/ComposeViewController.swift +++ b/FlowCrypt/Controllers/Compose/ComposeViewController.swift @@ -119,7 +119,8 @@ final class ComposeViewController: TableNodeViewController { clientConfiguration: clientConfiguration, encryptedStorage: appContext.encryptedStorage, messageGateway: appContext.getRequiredMailProvider().messageSender, - passPhraseService: appContext.passPhraseService + passPhraseService: appContext.passPhraseService, + sender: email ) self.filesManager = filesManager self.photosManager = photosManager @@ -266,7 +267,6 @@ extension ComposeViewController { let sendableMsg = try await composeMessageService.validateAndProduceSendableMsg( input: input, contextToSend: contextToSend, - email: email, includeAttachments: false, signingPrv: signingPrv ) @@ -502,7 +502,6 @@ extension ComposeViewController { let sendableMsg = try await self.composeMessageService.validateAndProduceSendableMsg( input: self.input, contextToSend: self.contextToSend, - email: self.email, signingPrv: signingKey ) UIApplication.shared.isIdleTimerDisabled = true @@ -1097,7 +1096,9 @@ extension ComposeViewController { } @objc private func messagePasswordTextFieldDidChange(_ sender: UITextField) { - messagePasswordAlertController?.actions[1].isEnabled = (sender.text ?? "").isNotEmpty + let password = sender.text ?? "" + let isPasswordStrong = composeMessageService.isMessagePasswordStrong(pwd: password) + messagePasswordAlertController?.actions[1].isEnabled = isPasswordStrong } } diff --git a/FlowCrypt/Functionality/Error Handling/ErrorHandler.swift b/FlowCrypt/Functionality/Error Handling/ErrorHandler.swift index ea0988f16..96a21ac13 100644 --- a/FlowCrypt/Functionality/Error Handling/ErrorHandler.swift +++ b/FlowCrypt/Functionality/Error Handling/ErrorHandler.swift @@ -34,7 +34,7 @@ private struct ComposedErrorHandler: ErrorHandler { static let shared: ComposedErrorHandler = ComposedErrorHandler( handlers: [ KeyServiceErrorHandler(), - BackupServiceErrorHandler(), + BackupServiceErrorHandler() ] ) diff --git a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift index 72de393b0..2a38c2a42 100644 --- a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift +++ b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift @@ -30,6 +30,8 @@ final class ComposeMessageService { private let draftGateway: DraftGateway? private lazy var logger: Logger = Logger.nested(Self.self) + private let sender: String + private struct ReplyInfo: Encodable { let sender: String let recipient: [String] @@ -44,6 +46,7 @@ final class ComposeMessageService { passPhraseService: PassPhraseServiceType, draftGateway: DraftGateway? = nil, contactsService: ContactsServiceType? = nil, + sender: String, core: CoreComposeMessageType & KeyParser = Core.shared, enterpriseServer: EnterpriseServerApiType = EnterpriseServerApi() ) { @@ -57,6 +60,7 @@ final class ComposeMessageService { ) self.core = core self.enterpriseServer = enterpriseServer + self.sender = sender self.logger = Logger.nested(in: Self.self, with: "ComposeMessageService") } @@ -69,7 +73,6 @@ final class ComposeMessageService { func validateAndProduceSendableMsg( input: ComposeMessageInput, contextToSend: ComposeMessageContext, - email: String, includeAttachments: Bool = true, signingPrv: PrvKeyInfo? ) async throws -> SendableMsg { @@ -101,7 +104,7 @@ final class ComposeMessageService { let subject = contextToSend.subject ?? "(no subject)" - guard let myPubKey = storage.getKeypairs(by: email).map(\.public).first else { + guard let myPubKey = storage.getKeypairs(by: sender).map(\.public).first else { throw MessageValidationError.missedPublicKey } @@ -122,16 +125,10 @@ final class ComposeMessageService { throw MessageValidationError.subjectContainsPassword } - let storedPassphrases = passPhraseService.getPassPhrases().map(\.value) - if storedPassphrases.contains(password) { + let allAvailablePassPhrases = passPhraseService.getPassPhrases().map(\.value) + if allAvailablePassPhrases.contains(password) { throw MessageValidationError.notUniquePassword } - - let fesUrl = try await enterpriseServer.getActiveFesUrl(for: email) - let isFesUsed = fesUrl != nil - if !isMessagePasswordStrong(pwd: password, isFesUsed: isFesUsed) { - throw MessageValidationError.weakPassword - } } return SendableMsg( @@ -140,7 +137,7 @@ final class ComposeMessageService { to: recipients.map(\.email), cc: [], bcc: [], - from: email, + from: sender, subject: subject, replyToMimeMsg: replyToMimeMsg, atts: sendableAttachments, @@ -359,14 +356,14 @@ extension ComposeMessageService { return SendableMsgBody(text: text, html: html) } - private func isMessagePasswordStrong(pwd: String, isFesUsed: Bool) -> Bool { + func isMessagePasswordStrong(pwd: String) -> Bool { let minLength = 8 // currently password-protected messages are supported only with FES on iOS - guard isFesUsed else { - // consumers - just 8 chars requirement - return pwd.count >= minLength - } + // guard enterpriseServer.isFesUsed else { + // // consumers - just 8 chars requirement + // return pwd.count >= minLength + // } // enterprise FES - use common corporate password rules let predicate = NSPredicate( diff --git a/FlowCrypt/Resources/en.lproj/Localizable.strings b/FlowCrypt/Resources/en.lproj/Localizable.strings index 1880c6876..d4d9b4842 100644 --- a/FlowCrypt/Resources/en.lproj/Localizable.strings +++ b/FlowCrypt/Resources/en.lproj/Localizable.strings @@ -88,7 +88,7 @@ "compose_password_placeholder" = "Tap to add password for recipients who don't have encryption set up."; "compose_password_set_message" = "Web portal password added"; "compose_password_modal_title" = "Set web portal password"; -"compose_password_modal_message" = "The recipients will receive a link to read your message on a web portal, where they will need to enter this password.\n\nYou are responsible for sharing this password with recipients (use other medium to share the password - not email)"; +"compose_password_modal_message" = "The recipients will receive a link to read your message on a web portal, where they will need to enter this password.\n\nYou are responsible for sharing this password with recipients (use other medium to share the password - not email)\n\nPassword should include:\n- one uppercase\n- one lowercase\n- one number\n- one special character eg &/#\"-'_%-@,;:!*()\n- min 8 characters length"; "compose_error" = "Could not compose message"; "compose_reply_successful" = "Reply successfully sent"; "compose_quote_from" = "On %@ at %@ %@ wrote:"; // Date, time, sender diff --git a/FlowCryptAppTests/ExtensionTests.swift b/FlowCryptAppTests/ExtensionTests.swift index 9344128b5..22a12e6c7 100644 --- a/FlowCryptAppTests/ExtensionTests.swift +++ b/FlowCryptAppTests/ExtensionTests.swift @@ -83,7 +83,6 @@ extension ExtensionTests { let today = Date() let components = Calendar.current.dateComponents([.year, .day], from: today) - let day = components.day == 24 ? 23 : components.day! let sameYearDate = try XCTUnwrap(DateComponents( calendar: .current, diff --git a/FlowCryptAppTests/Functionality/Services/ComposeMessageServiceTests.swift b/FlowCryptAppTests/Functionality/Services/ComposeMessageServiceTests.swift index dbe106b18..e980e3d51 100644 --- a/FlowCryptAppTests/Functionality/Services/ComposeMessageServiceTests.swift +++ b/FlowCryptAppTests/Functionality/Services/ComposeMessageServiceTests.swift @@ -46,6 +46,7 @@ class ComposeMessageServiceTests: XCTestCase { passPhraseService: PassPhraseServiceMock(), draftGateway: DraftGatewayMock(), contactsService: contactsService, + sender: "some@gmail.com", core: core ) @@ -66,7 +67,6 @@ class ComposeMessageServiceTests: XCTestCase { recipients: [], subject: nil ), - email: "some@gmail.com", signingPrv: nil ) XCTFail("expected to throw above") @@ -89,7 +89,6 @@ class ComposeMessageServiceTests: XCTestCase { recipients: recipients, subject: nil ), - email: "some@gmail.com", signingPrv: nil ) XCTFail("expected to throw above") @@ -107,7 +106,6 @@ class ComposeMessageServiceTests: XCTestCase { recipients: recipients, subject: nil ), - email: "some@gmail.com", signingPrv: nil ) XCTFail("expected to throw above") @@ -122,7 +120,6 @@ class ComposeMessageServiceTests: XCTestCase { recipients: recipients, subject: "" ), - email: "some@gmail.com", signingPrv: nil ) XCTFail("expected to throw above") @@ -137,7 +134,6 @@ class ComposeMessageServiceTests: XCTestCase { recipients: recipients, subject: " " ), - email: "some@gmail.com", signingPrv: nil ) XCTFail("expected to throw above") @@ -155,7 +151,6 @@ class ComposeMessageServiceTests: XCTestCase { recipients: recipients, subject: "Some subject" ), - email: "some@gmail.com", signingPrv: nil ) XCTFail("expected to throw above") @@ -170,7 +165,6 @@ class ComposeMessageServiceTests: XCTestCase { recipients: recipients, subject: "Some subject" ), - email: "some@gmail.com", signingPrv: nil ) XCTFail("expected to throw above") @@ -185,7 +179,6 @@ class ComposeMessageServiceTests: XCTestCase { recipients: recipients, subject: "Some subject" ), - email: "some@gmail.com", signingPrv: nil ) XCTFail("expected to throw above") @@ -204,7 +197,6 @@ class ComposeMessageServiceTests: XCTestCase { recipients: recipients, subject: "Some subject" ), - email: "some@gmail.com", signingPrv: nil ) XCTFail("expected to throw above") @@ -228,7 +220,6 @@ class ComposeMessageServiceTests: XCTestCase { recipients: recipients, subject: "Some subject" ), - email: "some@gmail.com", signingPrv: nil ) XCTFail("expected to throw above") @@ -256,7 +247,6 @@ class ComposeMessageServiceTests: XCTestCase { recipients: recipients, subject: "Some subject" ), - email: "some@gmail.com", signingPrv: nil ) XCTFail("expected to throw above") @@ -284,7 +274,6 @@ class ComposeMessageServiceTests: XCTestCase { recipients: recipients, subject: "Some subject" ), - email: "some@gmail.com", signingPrv: nil ) XCTFail("expected to throw above") @@ -328,7 +317,6 @@ class ComposeMessageServiceTests: XCTestCase { recipients: recipients, subject: subject ), - email: email, signingPrv: nil ) @@ -375,7 +363,6 @@ class ComposeMessageServiceTests: XCTestCase { recipients: recipients, subject: "Some subject" ), - email: "some@gmail.com", signingPrv: nil ) XCTFail("expected to throw above") @@ -403,7 +390,6 @@ class ComposeMessageServiceTests: XCTestCase { recipients: recipients, subject: subject ), - email: email, signingPrv: nil ) diff --git a/appium/tests/data/index.ts b/appium/tests/data/index.ts index 0e1e268ab..83fb0a0be 100644 --- a/appium/tests/data/index.ts +++ b/appium/tests/data/index.ts @@ -107,9 +107,10 @@ export const CommonData = { }, recipientWithoutPublicKey: { email: 'no.publickey@flowcrypt.com', + subject: 'Test subject 1*', weakPassword: '123aaBBc', password: 'abcABC1*', - modalMessage: `Set web portal password\nThe recipients will receive a link to read your message on a web portal, where they will need to enter this password.\n\nYou are responsible for sharing this password with recipients (use other medium to share the password - not email)`, + modalMessage: `Set web portal password\nThe recipients will receive a link to read your message on a web portal, where they will need to enter this password.\n\nYou are responsible for sharing this password with recipients (use other medium to share the password - not email)\n\nPassword should include: - one uppercase - one lowercase - one number - one special character eg &/#\"-'_%-@,;:!*() - min 8 characters length`, emptyPasswordMessage: 'Tap to add password for recipients who don\'t have encryption set up.', addedPasswordMessage: 'Web portal password added', weakPasswordMessage: 'Error\nPassword didn\'t comply with company policy, which requires at least:\n\n- one uppercase - one lowercase - one number - one special character eg &/#"-\'_%-@,;:!*() - 8 characters length\n\nPlease update the password and re-send.', diff --git a/appium/tests/screenobjects/new-message.screen.ts b/appium/tests/screenobjects/new-message.screen.ts index 1d57140a0..4d607e7ac 100644 --- a/appium/tests/screenobjects/new-message.screen.ts +++ b/appium/tests/screenobjects/new-message.screen.ts @@ -199,6 +199,11 @@ class NewMessageScreen extends BaseScreen { await ElementHelper.waitAndClick(await this.cancelButton); } + checkSetPasswordButton = async(isEnabled: boolean) => { + const el = await this.setPasswordButton; + expect(await el.isEnabled()).toBe(isEnabled); + } + checkPasswordCell = async (text: string) => { await ElementHelper.waitElementVisible(await this.passwordCell); await ElementHelper.checkStaticText(await this.passwordCell, text); diff --git a/appium/tests/specs/live/composeEmail/SendEmailToRecipientWithoutPublicKey.spec.ts b/appium/tests/specs/live/composeEmail/SendEmailToRecipientWithoutPublicKey.spec.ts index 935d3bc63..cff6052bb 100644 --- a/appium/tests/specs/live/composeEmail/SendEmailToRecipientWithoutPublicKey.spec.ts +++ b/appium/tests/specs/live/composeEmail/SendEmailToRecipientWithoutPublicKey.spec.ts @@ -13,16 +13,13 @@ describe('COMPOSE EMAIL: ', () => { it('sending message to user without public key produces password modal', async () => { const recipient = CommonData.recipientWithoutPublicKey.email; - const emailSubject = CommonData.simpleEmail.subject; + const emailSubject = CommonData.recipientWithoutPublicKey.subject; const emailText = CommonData.simpleEmail.message; const emailWeakPassword = CommonData.recipientWithoutPublicKey.weakPassword; const emailPassword = CommonData.recipientWithoutPublicKey.password; - const passphrase = CommonData.account.passPhrase; const passwordModalMessage = CommonData.recipientWithoutPublicKey.modalMessage; const emptyPasswordMessage = CommonData.recipientWithoutPublicKey.emptyPasswordMessage; - const weakPasswordMessage = CommonData.recipientWithoutPublicKey.weakPasswordMessage; - const passphrasePasswordErrorMessage = CommonData.recipientWithoutPublicKey.passphrasePasswordErrorMessage; const subjectPasswordErrorMessage = CommonData.recipientWithoutPublicKey.subjectPasswordErrorMessage; const addedPasswordMessage = CommonData.recipientWithoutPublicKey.addedPasswordMessage; @@ -52,19 +49,10 @@ describe('COMPOSE EMAIL: ', () => { await BaseScreen.checkModalMessage(subjectPasswordErrorMessage); await BaseScreen.clickOkButtonOnError(); - await NewMessageScreen.clickPasswordCell(); - await NewMessageScreen.setMessagePassword(passphrase); - await NewMessageScreen.clickSendButton(); - await BaseScreen.checkModalMessage(passphrasePasswordErrorMessage); - await BaseScreen.clickOkButtonOnError(); - await NewMessageScreen.clickPasswordCell(); await NewMessageScreen.setMessagePassword(emailWeakPassword); - await NewMessageScreen.clickSendButton(); - await BaseScreen.checkModalMessage(weakPasswordMessage); - await BaseScreen.clickOkButtonOnError(); + await NewMessageScreen.checkSetPasswordButton(false); - await NewMessageScreen.clickPasswordCell(); await NewMessageScreen.setMessagePassword(emailPassword); await NewMessageScreen.checkPasswordCell(addedPasswordMessage); }); From f6e471abb205547f63e99598c73af791353d965b Mon Sep 17 00:00:00 2001 From: Roma Sosnovsky Date: Tue, 25 Jan 2022 16:33:04 +0200 Subject: [PATCH 06/12] remove unneeded escape character --- .../xcshareddata/swiftpm/Package.resolved | 8 ++++---- Gemfile.lock | 8 ++++---- Podfile.lock | 4 ++-- appium/tests/data/index.ts | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/FlowCrypt.xcworkspace/xcshareddata/swiftpm/Package.resolved b/FlowCrypt.xcworkspace/xcshareddata/swiftpm/Package.resolved index 6528023d1..9b379cb07 100644 --- a/FlowCrypt.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/FlowCrypt.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -87,8 +87,8 @@ "repositoryURL": "https://github.com/realm/realm-cocoa", "state": { "branch": null, - "revision": "39177714b95bb5b1b29fffe28f1c7da77eef8e8b", - "version": "10.21.1" + "revision": "9dff9f2862240d521ad6ad599541269177ddb993", + "version": "10.22.0" } }, { @@ -96,8 +96,8 @@ "repositoryURL": "https://github.com/realm/realm-core", "state": { "branch": null, - "revision": "f1976f0d96d9b06fbe0afbd60090b1c3966b1e23", - "version": "11.8.0" + "revision": "6b81f1a7a2d421f9e0b9e7f04e76bcf736a54409", + "version": "11.9.0" } }, { diff --git a/Gemfile.lock b/Gemfile.lock index fb0bc06aa..e51f6de72 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,7 +18,7 @@ GEM atomos (0.1.3) aws-eventstream (1.2.0) aws-partitions (1.549.0) - aws-sdk-core (3.125.4) + aws-sdk-core (3.125.5) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.525.0) aws-sigv4 (~> 1.1) @@ -26,7 +26,7 @@ GEM aws-sdk-kms (1.53.0) aws-sdk-core (~> 3, >= 3.125.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.111.1) + aws-sdk-s3 (1.111.3) aws-sdk-core (~> 3, >= 3.125.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.4) @@ -116,7 +116,7 @@ GEM faraday_middleware (1.2.0) faraday (~> 1.0) fastimage (2.2.6) - fastlane (2.200.0) + fastlane (2.201.2) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -162,7 +162,7 @@ GEM gh_inspector (1.1.3) google-apis-androidpublisher_v3 (0.15.0) google-apis-core (>= 0.4, < 2.a) - google-apis-core (0.4.1) + google-apis-core (0.4.2) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) httpclient (>= 2.8.1, < 3.a) diff --git a/Podfile.lock b/Podfile.lock index c9ee828b6..4cbc19c1a 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -16,7 +16,7 @@ PODS: - PINCache (~> 3.0.3) - PINRemoteImage/Core - SwiftFormat/CLI (0.49.2) - - SwiftLint (0.45.1) + - SwiftLint (0.46.1) - SwiftyRSA (1.7.0): - SwiftyRSA/ObjC (= 1.7.0) - SwiftyRSA/ObjC (1.7.0) @@ -65,7 +65,7 @@ SPEC CHECKSUMS: PINOperation: 00c935935f1e8cf0d1e2d6b542e75b88fc3e5e20 PINRemoteImage: f1295b29f8c5e640e25335a1b2bd9d805171bd01 SwiftFormat: dca5803d3e2120aed5614f1653d252e62ac33be1 - SwiftLint: 06ac37e4d38c7068e0935bb30cda95f093bec761 + SwiftLint: aaa29a9f649316095a9079595cb60906bd899353 SwiftyRSA: 8c6dd1ea7db1b8dc4fb517a202f88bb1354bc2c6 Texture: 2e8ab2519452515f7f5a520f5a8f7e0a413abfa3 diff --git a/appium/tests/data/index.ts b/appium/tests/data/index.ts index 83fb0a0be..7490e429c 100644 --- a/appium/tests/data/index.ts +++ b/appium/tests/data/index.ts @@ -110,7 +110,7 @@ export const CommonData = { subject: 'Test subject 1*', weakPassword: '123aaBBc', password: 'abcABC1*', - modalMessage: `Set web portal password\nThe recipients will receive a link to read your message on a web portal, where they will need to enter this password.\n\nYou are responsible for sharing this password with recipients (use other medium to share the password - not email)\n\nPassword should include: - one uppercase - one lowercase - one number - one special character eg &/#\"-'_%-@,;:!*() - min 8 characters length`, + modalMessage: `Set web portal password\nThe recipients will receive a link to read your message on a web portal, where they will need to enter this password.\n\nYou are responsible for sharing this password with recipients (use other medium to share the password - not email)\n\nPassword should include: - one uppercase - one lowercase - one number - one special character eg &/#"-'_%-@,;:!*() - min 8 characters length`, emptyPasswordMessage: 'Tap to add password for recipients who don\'t have encryption set up.', addedPasswordMessage: 'Web portal password added', weakPasswordMessage: 'Error\nPassword didn\'t comply with company policy, which requires at least:\n\n- one uppercase - one lowercase - one number - one special character eg &/#"-\'_%-@,;:!*() - 8 characters length\n\nPlease update the password and re-send.', From dba399a7496d56b390333202b14d32a40ef3870c Mon Sep 17 00:00:00 2001 From: Roma Sosnovsky Date: Wed, 26 Jan 2022 11:15:33 +0200 Subject: [PATCH 07/12] rename missedPublicKey error --- .../Compose Message Service/ComposeMessageError.swift | 4 ++-- .../Compose Message Service/ComposeMessageService.swift | 2 +- .../Functionality/Services/ComposeMessageServiceTests.swift | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageError.swift b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageError.swift index 6ec7bd56b..e8eda540c 100644 --- a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageError.swift +++ b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageError.swift @@ -15,7 +15,7 @@ enum MessageValidationError: Error, CustomStringConvertible, Equatable { case weakPassword case subjectContainsPassword case notUniquePassword - case missedPublicKey + case missingPublicKey case noPubRecipients case revokedKeyRecipients case expiredKeyRecipients @@ -36,7 +36,7 @@ enum MessageValidationError: Error, CustomStringConvertible, Equatable { return "compose_password_subject_error".localized case .notUniquePassword: return "compose_password_passphrase_error".localized - case .missedPublicKey: + case .missingPublicKey: return "compose_no_pub_sender".localized case .noPubRecipients: return "compose_recipient_no_pub".localized diff --git a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift index 2a38c2a42..2b2141ba7 100644 --- a/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift +++ b/FlowCrypt/Functionality/Services/Compose Message Service/ComposeMessageService.swift @@ -105,7 +105,7 @@ final class ComposeMessageService { let subject = contextToSend.subject ?? "(no subject)" guard let myPubKey = storage.getKeypairs(by: sender).map(\.public).first else { - throw MessageValidationError.missedPublicKey + throw MessageValidationError.missingPublicKey } let sendableAttachments: [SendableMsg.Attachment] = includeAttachments diff --git a/FlowCryptAppTests/Functionality/Services/ComposeMessageServiceTests.swift b/FlowCryptAppTests/Functionality/Services/ComposeMessageServiceTests.swift index e980e3d51..da644e63b 100644 --- a/FlowCryptAppTests/Functionality/Services/ComposeMessageServiceTests.swift +++ b/FlowCryptAppTests/Functionality/Services/ComposeMessageServiceTests.swift @@ -201,7 +201,7 @@ class ComposeMessageServiceTests: XCTestCase { ) XCTFail("expected to throw above") } catch { - XCTAssertEqual(error as? MessageValidationError, MessageValidationError.missedPublicKey) + XCTAssertEqual(error as? MessageValidationError, MessageValidationError.missingPublicKey) } } From 72cb100b47a7b28424eee2eaec6fc2e58555e824 Mon Sep 17 00:00:00 2001 From: Roma Sosnovsky Date: Wed, 26 Jan 2022 16:01:51 +0200 Subject: [PATCH 08/12] fix typo --- appium/tests/screenobjects/splash.screen.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appium/tests/screenobjects/splash.screen.ts b/appium/tests/screenobjects/splash.screen.ts index 0ec5f25d1..09577e756 100644 --- a/appium/tests/screenobjects/splash.screen.ts +++ b/appium/tests/screenobjects/splash.screen.ts @@ -84,7 +84,7 @@ class SplashScreen extends BaseScreen { return $(SELECTORS.SIGN_IN_WITH_GMAIL); } - get useAnotherAcoount() { + get useAnotherAccount() { return $(SELECTORS.USE_ANOTHER_ACCOUNT); } @@ -147,7 +147,7 @@ class SplashScreen extends BaseScreen { await browser.pause(1000); // stability sleep for language change if (await (await $(emailSelector)).isDisplayed()) { await ElementHelper.waitAndClick(await $(emailSelector)); - await (await this.useAnotherAcoount).waitForDisplayed({ timeout: 5000, reverse: true }); + await (await this.useAnotherAccount).waitForDisplayed({ timeout: 5000, reverse: true }); if (await (await this.passwordField).isDisplayed()) { await this.fillPassword(password); await this.clickNextBtn(); From 5c85d91d19dcebd101ad9477a833da1ca4977784 Mon Sep 17 00:00:00 2001 From: Roma Sosnovsky Date: Wed, 26 Jan 2022 21:17:37 +0200 Subject: [PATCH 09/12] update semaphore.yml --- .semaphore/semaphore.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index 07b890a36..cf8cf8bd7 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -5,7 +5,7 @@ agent: type: a1-standard-4 os_image: macos-xcode13 execution_time_limit: - minutes: 90 + minutes: 100 auto_cancel: running: when: branch != 'master' @@ -15,7 +15,7 @@ blocks: run: when: 'change_in(''/'', {exclude: [''/Core/package.json'', ''/Core/package-lock.json'']})' execution_time_limit: - minutes: 85 + minutes: 95 task: secrets: - name: flowcrypt-ios-ci-secrets From 289aae4fdbd6c59ae48a03323863f48df9a7e058 Mon Sep 17 00:00:00 2001 From: Roma Sosnovsky Date: Wed, 26 Jan 2022 22:50:51 +0200 Subject: [PATCH 10/12] increase semaphore execution_time_limit --- .semaphore/semaphore.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index cf8cf8bd7..d6dcf92de 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -5,7 +5,7 @@ agent: type: a1-standard-4 os_image: macos-xcode13 execution_time_limit: - minutes: 100 + minutes: 120 auto_cancel: running: when: branch != 'master' @@ -15,7 +15,7 @@ blocks: run: when: 'change_in(''/'', {exclude: [''/Core/package.json'', ''/Core/package-lock.json'']})' execution_time_limit: - minutes: 95 + minutes: 115 task: secrets: - name: flowcrypt-ios-ci-secrets From f75c075b80a5bf32759c86b3ea8ad2170bf1542c Mon Sep 17 00:00:00 2001 From: Roma Sosnovsky Date: Thu, 27 Jan 2022 13:24:47 +0200 Subject: [PATCH 11/12] update composeEmail test helper --- appium/tests/screenobjects/new-message.screen.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appium/tests/screenobjects/new-message.screen.ts b/appium/tests/screenobjects/new-message.screen.ts index 4d607e7ac..175ddde68 100644 --- a/appium/tests/screenobjects/new-message.screen.ts +++ b/appium/tests/screenobjects/new-message.screen.ts @@ -116,8 +116,8 @@ class NewMessageScreen extends BaseScreen { composeEmail = async (recipient: string, subject: string, message: string) => { await this.setAddRecipient(recipient); - await this.setSubject(subject); await this.setComposeSecurityMessage(message); + await this.setSubject(subject); }; setAddRecipientByName = async (name: string, email: string) => { From 0b67c59f1adc95f8092e854dac7beef16ad767eb Mon Sep 17 00:00:00 2001 From: Roma Sosnovsky Date: Thu, 27 Jan 2022 16:22:14 +0200 Subject: [PATCH 12/12] fix CheckComposeEmailAfterReopening --- .../live/composeEmail/CheckComposeEmailAfterReopening.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appium/tests/specs/live/composeEmail/CheckComposeEmailAfterReopening.spec.ts b/appium/tests/specs/live/composeEmail/CheckComposeEmailAfterReopening.spec.ts index 06e7a4468..5ea5b72bc 100644 --- a/appium/tests/specs/live/composeEmail/CheckComposeEmailAfterReopening.spec.ts +++ b/appium/tests/specs/live/composeEmail/CheckComposeEmailAfterReopening.spec.ts @@ -21,7 +21,7 @@ describe('COMPOSE EMAIL: ', () => { await MailFolderScreen.checkInboxScreen(); await MailFolderScreen.clickCreateEmail(); - await NewMessageScreen.composeEmail('', '', longEmailText); + await NewMessageScreen.setComposeSecurityMessage(longEmailText); await NewMessageScreen.checkRecipientsTextFieldIsInvisible(); await NewMessageScreen.clickBackButton();