Skip to content

Commit e2bce84

Browse files
author
Ioan Moldovan
authored
#2548 Add warning for suspicious message (#2626)
* feat: added warning for suspicious message * fix: machine type * fix: fastlane file * fix: fastlane file * fix: fastlane file * fix: semaphoreci * fix: use xcode 15 image * fix: pr reviews * fix: removed unused test
1 parent e03d802 commit e2bce84

File tree

12 files changed

+173
-7
lines changed

12 files changed

+173
-7
lines changed

.semaphore/semaphore.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,4 @@ after_pipeline:
114114
jobs:
115115
- name: Publish Results
116116
commands:
117-
- test-results gen-pipeline-report
117+
- test-results gen-pipeline-report

FlowCrypt.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@
420420
D2FD0F692453245E00259FF0 /* Either.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FD0F682453245E00259FF0 /* Either.swift */; };
421421
D2FF6966243115EC007182F0 /* SetupImapViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FF6965243115EC007182F0 /* SetupImapViewController.swift */; };
422422
D2FF6968243115F9007182F0 /* SetupImapViewDecorator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FF6967243115F9007182F0 /* SetupImapViewDecorator.swift */; };
423+
D741F9B22CA5661C00E1CAFF /* SecurityWarningNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D741F9B12CA5661400E1CAFF /* SecurityWarningNode.swift */; };
423424
F191F621272511790053833E /* BlurViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F191F620272511790053833E /* BlurViewController.swift */; };
424425
F8678DCC2722143300BB1710 /* GmailService+draft.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8678DCB2722143300BB1710 /* GmailService+draft.swift */; };
425426
F8A72FA12729F82800E4BCAB /* DraftGatewayMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A72FA02729F82800E4BCAB /* DraftGatewayMock.swift */; };
@@ -886,6 +887,7 @@
886887
D2FD0F682453245E00259FF0 /* Either.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Either.swift; sourceTree = "<group>"; };
887888
D2FF6965243115EC007182F0 /* SetupImapViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetupImapViewController.swift; sourceTree = "<group>"; };
888889
D2FF6967243115F9007182F0 /* SetupImapViewDecorator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetupImapViewDecorator.swift; sourceTree = "<group>"; };
890+
D741F9B12CA5661400E1CAFF /* SecurityWarningNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityWarningNode.swift; sourceTree = "<group>"; };
889891
E26D5E20275AA417007B8802 /* BundleExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleExtensions.swift; sourceTree = "<group>"; };
890892
F191F620272511790053833E /* BlurViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurViewController.swift; sourceTree = "<group>"; };
891893
F8678DCB2722143300BB1710 /* GmailService+draft.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GmailService+draft.swift"; sourceTree = "<group>"; };
@@ -2212,6 +2214,7 @@
22122214
D2A1D3D123FD9A9E00D626D6 /* Cell Nodes */ = {
22132215
isa = PBXGroup;
22142216
children = (
2217+
D741F9B12CA5661400E1CAFF /* SecurityWarningNode.swift */,
22152218
9F8D5E61236B04E300186E43 /* CellNode.swift */,
22162219
9F1797652368EE50002BF770 /* SetupTitleNode.swift */,
22172220
5A39F433239EC61C001F4607 /* TitleCellNode.swift */,
@@ -2904,6 +2907,7 @@
29042907
D2CDC3D72404704D002B045F /* RecipientEmailsCellNode.swift in Sources */,
29052908
5165ABCC27B526D100CCC379 /* RecipientEmailTextFieldNode.swift in Sources */,
29062909
51C56BE82901867D00610D12 /* ENSideMenu.swift in Sources */,
2910+
D741F9B22CA5661C00E1CAFF /* SecurityWarningNode.swift in Sources */,
29072911
955475FB2B0650AC00F52076 /* WebNode.swift in Sources */,
29082912
D2717752242567EB00BDA9A9 /* KeyTextCellNode.swift in Sources */,
29092913
511D07E12769FBBA0050417B /* MessageActionCellNode.swift in Sources */,

FlowCrypt/Controllers/Threads/ThreadDetailsViewController+TableView.swift

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ extension ThreadDetailsViewController: ASTableDelegate, ASTableDataSource {
2727
let processedMessage = input[section - 1].processedMessage
2828
let attachmentsCount = processedMessage?.attachments.count ?? 0
2929
let pubkeysCount = processedMessage?.keyDetails.count ?? 0
30-
return Parts.allCases.count + attachmentsCount + pubkeysCount
30+
let securityWarningBlockCount = processedMessage?.message.isSuspicious == true ? 1 : 0
31+
return Parts.allCases.count + attachmentsCount + pubkeysCount + securityWarningBlockCount
3132
}
3233

3334
// swiftlint:disable cyclomatic_complexity function_body_length
@@ -65,10 +66,16 @@ extension ThreadDetailsViewController: ASTableDelegate, ASTableDataSource {
6566
}
6667
}
6768

69+
if message.rawMessage.isSuspicious, row == 1 {
70+
return SecurityWarningNode()
71+
}
72+
6873
guard message.isExpanded, let processedMessage = message.processedMessage
6974
else { return self.dividerNode(indexPath: indexPath) }
7075

71-
guard row > 1 else {
76+
let securityWarningBlockCount = message.rawMessage.isSuspicious == true ? 1 : 0
77+
78+
guard row > 1 + securityWarningBlockCount else {
7279
if processedMessage.text.isHTMLString {
7380
return ThreadDetailWebNode(
7481
input: .init(message: processedMessage.text, quote: processedMessage.quote, index: messageIndex)
@@ -85,7 +92,7 @@ extension ThreadDetailsViewController: ASTableDelegate, ASTableDataSource {
8592
}
8693

8794
let keyCount = processedMessage.keyDetails.count
88-
let keyIndex = row - 2
95+
let keyIndex = row - 2 - securityWarningBlockCount
8996
if keyIndex < keyCount {
9097
let keyDetails = processedMessage.keyDetails[keyIndex]
9198
let node = PublicKeyDetailNode(
@@ -97,7 +104,7 @@ extension ThreadDetailsViewController: ASTableDelegate, ASTableDataSource {
97104
return node
98105
}
99106

100-
let attachmentIndex = row - 2 - keyCount
107+
let attachmentIndex = row - 2 - keyCount - securityWarningBlockCount
101108
if let attachment = processedMessage.attachments[safe: attachmentIndex] {
102109
return AttachmentNode(
103110
input: .init(

FlowCrypt/Functionality/Mail Provider/Gmail/GmailService.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,6 @@ extension String {
6060
static let bcc = "bcc"
6161
static let replyTo = "reply-to"
6262
static let inReplyTo = "in-reply-to"
63+
static let receivedSPF = "received-spf"
6364
static let identifier = "message-id"
6465
}

FlowCrypt/Functionality/Mail Provider/Message Provider/Gmail+MessageExtension.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ extension Message {
4444
var replyTo: String?
4545
var inReplyTo: String?
4646
var rfc822MsgId: String?
47+
var isSuspicious = false
4748

4849
for messageHeader in messageHeaders.compactMap({ $0 }) {
4950
guard let name = messageHeader.name?.lowercased(),
@@ -58,6 +59,7 @@ extension Message {
5859
case .bcc: bcc = value
5960
case .replyTo: replyTo = value
6061
case .inReplyTo: inReplyTo = value
62+
case .receivedSPF: isSuspicious = value.contains("softfail")
6163
case .identifier: rfc822MsgId = value
6264
default: break
6365
}
@@ -81,7 +83,8 @@ extension Message {
8183
cc: cc,
8284
bcc: bcc,
8385
replyTo: replyTo,
84-
inReplyTo: inReplyTo
86+
inReplyTo: inReplyTo,
87+
isSuspicious: isSuspicious
8588
)
8689
}
8790
}

FlowCrypt/Functionality/Mail Provider/MessagesList Provider/Model/Message.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ struct Message: Hashable {
2828
let body: MessageBody
2929
let inReplyTo: String?
3030
let replyToMsgId: String?
31+
let isSuspicious: Bool
3132
private(set) var labels: [MessageLabel]
3233

3334
var isRead: Bool {
@@ -83,7 +84,8 @@ struct Message: Hashable {
8384
bcc: String? = nil,
8485
replyTo: String? = nil,
8586
inReplyTo: String? = nil,
86-
replyToMsgId: String? = nil
87+
replyToMsgId: String? = nil,
88+
isSuspicious: Bool = false
8789
) {
8890
self.identifier = identifier
8991
self.date = date
@@ -104,6 +106,7 @@ struct Message: Hashable {
104106
self.replyTo = Self.parseRecipients(replyTo)
105107
self.inReplyTo = inReplyTo
106108
self.replyToMsgId = replyToMsgId
109+
self.isSuspicious = isSuspicious
107110
}
108111
}
109112

FlowCrypt/Resources/en.lproj/Localizable.strings

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@
7272
"message_mark_read_error" = "Could not mark message as read: %@";
7373
"message_reply_all" = "Reply all";
7474
"message_not_found_in_folder" = "Message not found in folder: ";
75+
"message_security_warning_subject" = "Potentially suspicious message";
76+
"message_security_warning_message" = "It wasn't properly verified by the sender, so its authenticity can't be confirmed.
77+
Be careful - avoid clicking links and downloading attachments, or sharing personal info.";
7578

7679
// Passphrase Anti BruteForce Protection
7780
"passphrase_anti_brute_force_protection_hint" = "To protect you and your data, the next attempt will only be possible after the timer below finishes. Please wait until then before trying again.";
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//
2+
// SecurityWarningNode.swift
3+
// FlowCrypt
4+
//
5+
// Created by Ioan Moldovan on 9/26/24
6+
// Copyright © 2017-present FlowCrypt a. s. All rights reserved.
7+
//
8+
9+
import AsyncDisplayKit
10+
11+
public final class SecurityWarningNode: CellNode {
12+
13+
private lazy var subjectNode: ASTextNode2 = {
14+
let textNode = ASTextNode2()
15+
textNode.attributedText = "message_security_warning_subject".localized.attributed(.bold(18), color: .black, alignment: .left)
16+
textNode.accessibilityIdentifier = "aid-security-warning-subject-node"
17+
return textNode
18+
}()
19+
20+
private lazy var messageNode: ASTextNode2 = {
21+
let textNode = ASTextNode2()
22+
textNode.attributedText = "message_security_warning_message".localized.attributed(.regular(15), color: .black, alignment: .left)
23+
textNode.accessibilityIdentifier = "aid-security-warning-message-node"
24+
return textNode
25+
}()
26+
27+
override public init() {
28+
super.init()
29+
30+
backgroundColor = UIColor(hex: "FABD03")
31+
}
32+
33+
override public func layoutSpecThatFits(_: ASSizeRange) -> ASLayoutSpec {
34+
let stack = ASStackLayoutSpec.vertical()
35+
stack.children = [subjectNode, messageNode]
36+
stack.spacing = 10
37+
38+
return ASInsetLayoutSpec(
39+
insets: .deviceSpecificTextInsets(top: 16, bottom: 16),
40+
child: stack
41+
)
42+
}
43+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
{
2+
"acctEmail": "[email protected]",
3+
"full": {
4+
"id": "1922cd70bf323ea6",
5+
"threadId": "1922cd70bf323ea6",
6+
"labelIds": ["CATEGORY_PERSONAL", "INBOX"],
7+
"snippet": "test -Mart at FlowCrypt",
8+
"payload": {
9+
"partId": "",
10+
"mimeType": "text/plain",
11+
"filename": "",
12+
"headers": [
13+
{
14+
"name": "To",
15+
"value": "[email protected]"
16+
},
17+
{
18+
"name": "Subject",
19+
"value": "Test Spoofed email by Mart"
20+
},
21+
{
22+
"name": "From",
23+
"value": "[email protected]"
24+
},
25+
{
26+
"name": "X-Priority",
27+
"value": "3 (Normal)"
28+
},
29+
{
30+
"name": "Importance",
31+
"value": "Normal"
32+
},
33+
{
34+
"name": "Received-SPF",
35+
"value": "softfail (google.com: domain of transitioning [email protected] does not designate 0.0.0.0 as permitted sender) client-ip=0.0.0.0;"
36+
},
37+
{
38+
"name": "Errors-To",
39+
"value": "[email protected]"
40+
},
41+
{
42+
"name": "Reply-To",
43+
"value": "[email protected]"
44+
},
45+
{
46+
"name": "Content-Type",
47+
"value": "text/plain; charset=utf-8"
48+
},
49+
{
50+
"name": "Date",
51+
"value": "Thu, 26 Sep 2024 07:39:02 +0200 (CEST)"
52+
}
53+
],
54+
"body": {
55+
"size": 28,
56+
"data": "dGVzdA0KDQotTWFydCBhdCBGbG93Q3J5cHQNCg=="
57+
}
58+
},
59+
"sizeEstimate": 3183,
60+
"historyId": "298166",
61+
"internalDate": "1727329142000"
62+
},
63+
"attachments": {},
64+
"raw": {
65+
"id": "1922cd70bf323ea6",
66+
"threadId": "1922cd70bf323ea6",
67+
"labelIds": ["CATEGORY_PERSONAL", "SPAM"],
68+
"snippet": "test -Mart at FlowCrypt",
69+
"sizeEstimate": 3183,
70+
"raw": "RGVsaXZlcmVkLVRvOiBpb2FuQGZsb3djcnlwdC5jb20NClJlY2VpdmVkOiBieSAyMDAyOmEwNTo2MzU5OjQ1OWE6YjA6MWJlOmI4N2E6NDZhNCB3aXRoIFNNVFAgaWQgbm8yNmNzcDE1MDk5MXJ3YjsNCiAgICAgICAgV2VkLCAyNSBTZXAgMjAyNCAyMjozOTowMyAtMDcwMCAoUERUKQ0KWC1Hb29nbGUtU210cC1Tb3VyY2U6IEFHSFQrSUhocFVnem42dE4ycnAyUDc0NkNKQ1JDZ1NXZXEyYndWdVFDNWFpcXFFSThOdGhhSTlER0JJb2V5V3VRTWFQeXVCOUV2WmoNClgtUmVjZWl2ZWQ6IGJ5IDIwMDI6YTE3OjkwYjozMTQ0OmIwOjJkODo3N2NjOjg1ZSB3aXRoIFNNVFAgaWQgOThlNjdlZDU5ZTFkMS0yZTA2YWZlYjc4ZW1yNjMzMTEzMGE5MS4zNy4xNzI3MzI5MTQzNTQ1Ow0KICAgICAgICBXZWQsIDI1IFNlcCAyMDI0IDIyOjM5OjAzIC0wNzAwIChQRFQpDQpBUkMtU2VhbDogaT0xOyBhPXJzYS1zaGEyNTY7IHQ9MTcyNzMyOTE0MzsgY3Y9bm9uZTsNCiAgICAgICAgZD1nb29nbGUuY29tOyBzPWFyYy0yMDI0MDYwNTsNCiAgICAgICAgYj1TOVRyZzluaUsyQURsQWQrWnYwZE9CbnhBVStvYlN5RkUyUkgvVFFucS9ZL2M2VmNCd3pkcmM4d3A4Y3BJL1ZUUWsNCiAgICAgICAgIDJjc3F6TEIzczRCQjBTMFB0U0pFd0VJTUUvd2J1SWtTUWl5RkpjOURsY3R2VFBST1RhSmNHc0xKTmQvWlBvRzhMQTJCDQogICAgICAgICBpZVJ6YlpsbWs2TmpKMFFPVURNZlVzYU8reXp0dzcwSmU1OWgwbjZQVUoyWTloNW5UdXFpYzFzbmpqZVc5b0dPcDF3Mg0KICAgICAgICAgWWJGQzFrK09GbjkyZElxeFZkNHZsNnp5blBrZytxSFoyQi9HSTE1ZHRjaFIyZFpXOEJlcWh3cU00TXIvdFFpVE9TQmgNCiAgICAgICAgIDRSdjBzTm1yam5LSVJCR2JPRWVBMHNMTndWam5kTWJjaDMwVGdIb1Y1NEoxakcyQVZnY1F0aDFTTjVuc0ovOVJoL0d3DQogICAgICAgICB6VWp3PT0NCkFSQy1NZXNzYWdlLVNpZ25hdHVyZTogaT0xOyBhPXJzYS1zaGEyNTY7IGM9cmVsYXhlZC9yZWxheGVkOyBkPWdvb2dsZS5jb207IHM9YXJjLTIwMjQwNjA1Ow0KICAgICAgICBoPWRhdGU6bWVzc2FnZS1pZDpyZXBseS10bzplcnJvcnMtdG86aW1wb3J0YW5jZTpmcm9tOnN1YmplY3Q6dG87DQogICAgICAgIGJoPWNXY3VTNmxuVTE4VTU4YTUwT3dqelFzMGEwK3FsNGxZbnBDSEZoZ3Yxalk9Ow0KICAgICAgICBmaD1yVjZaTXJhY21nOVg1TUdtam9YdVJ6YmZ4dGpEUldSZkEzWkZLQTNRZC9jPTsNCiAgICAgICAgYj1MaTRxMjRuNXUxajFPWEFqUG1JN0RDNlFXOVJTd2tSOUFjaHd6bEJkb0ZLbXYwdmpXclo3dVFQS2UyMUVGZnlJUVQNCiAgICAgICAgIFk5M3pQbWg5U1RacVFaV3FGTS9SaXJGTFlRRjV2UGpZTzdVRWpiSkoyS05lYlFtS3lNT1ZDN2UydlNxdzRsWVQ1bUh6DQogICAgICAgICAwUEpmbzNUK2cvWUE2UU0zbldmbjIzU1pONHRTS3hIU1c2VXh6N3F0S3FCNXFtQjJSalFrUFZod0FGMEw3SFEva0RWNA0KICAgICAgICAgWk1QaDVuMUR2SHdqWDlxRURWUmk1d3NQdGg4Y1NRbEY2dnFSdXZjZzhyVjdGajZnRzA1QVFyeFp2bTQ2TVVMU0t0ckINCiAgICAgICAgIG5NYjhQYmpreEdJUHdBQ1gyODNzbDRKWEh3Q1ZiTVdYRHEzeDZPck01a2tKdmxJcGdLd2l6UEhOOGs2cW9Ud1pmbHV2DQogICAgICAgICBvMjNnPT07DQogICAgICAgIGRhcmE9Z29vZ2xlLmNvbQ0KQVJDLUF1dGhlbnRpY2F0aW9uLVJlc3VsdHM6IGk9MTsgbXguZ29vZ2xlLmNvbTsNCiAgICAgICBzcGY9c29mdGZhaWwgKGdvb2dsZS5jb206IGRvbWFpbiBvZiB0cmFuc2l0aW9uaW5nIGhhY2tlckBnbWFpbC5jb20gZG9lcyBub3QgZGVzaWduYXRlIDExNC4yOS4yMzYuMjQ3IGFzIHBlcm1pdHRlZCBzZW5kZXIpIHNtdHAubWFpbGZyb209aGFja2VyQGdtYWlsLmNvbTsNCiAgICAgICBkbWFyYz1mYWlsIChwPU5PTkUgc3A9UVVBUkFOVElORSBkaXM9Tk9ORSkgaGVhZGVyLmZyb209Z21haWwuY29tDQpSZXR1cm4tUGF0aDogPGhhY2tlckBnbWFpbC5jb20-DQpSZWNlaXZlZDogZnJvbSBlbWtlaS5jeiAoZW1rZWkuY3ouIFsxMTQuMjkuMjM2LjI0N10pDQogICAgICAgIGJ5IG14Lmdvb2dsZS5jb20gd2l0aCBFU01UUFMgaWQgOThlNjdlZDU5ZTFkMS0yZTA2ZTJmMjQ2Y3NpMzAzNTc1NWE5MS4xNTkuMjAyNC4wOS4yNS4yMi4zOS4wMw0KICAgICAgICBmb3IgPGlvYW5AZmxvd2NyeXB0LmNvbT4NCiAgICAgICAgKHZlcnNpb249VExTMV8zIGNpcGhlcj1UTFNfQUVTXzI1Nl9HQ01fU0hBMzg0IGJpdHM9MjU2LzI1Nik7DQogICAgICAgIFdlZCwgMjUgU2VwIDIwMjQgMjI6Mzk6MDMgLTA3MDAgKFBEVCkNClJlY2VpdmVkLVNQRjogc29mdGZhaWwgKGdvb2dsZS5jb206IGRvbWFpbiBvZiB0cmFuc2l0aW9uaW5nIGhhY2tlckBnbWFpbC5jb20gZG9lcyBub3QgZGVzaWduYXRlIDExNC4yOS4yMzYuMjQ3IGFzIHBlcm1pdHRlZCBzZW5kZXIpIGNsaWVudC1pcD0xMTQuMjkuMjM2LjI0NzsNCkF1dGhlbnRpY2F0aW9uLVJlc3VsdHM6IG14Lmdvb2dsZS5jb207DQogICAgICAgc3BmPXNvZnRmYWlsIChnb29nbGUuY29tOiBkb21haW4gb2YgdHJhbnNpdGlvbmluZyBoYWNrZXJAZ21haWwuY29tIGRvZXMgbm90IGRlc2lnbmF0ZSAxMTQuMjkuMjM2LjI0NyBhcyBwZXJtaXR0ZWQgc2VuZGVyKSBzbXRwLm1haWxmcm9tPWhhY2tlckBnbWFpbC5jb207DQogICAgICAgZG1hcmM9ZmFpbCAocD1OT05FIHNwPVFVQVJBTlRJTkUgZGlzPU5PTkUpIGhlYWRlci5mcm9tPWdtYWlsLmNvbQ0KUmVjZWl2ZWQ6IGJ5IGVta2VpLmN6IChQb3N0Zml4LCBmcm9tIHVzZXJpZCAzMykNCglpZCA0NzU5QzFGMDk7IFRodSwgMjYgU2VwIDIwMjQgMDc6Mzk6MDIgKzAyMDAgKENFU1QpDQpUbzogaW9hbkBmbG93Y3J5cHQuY29tDQpTdWJqZWN0OiBUZXN0IFNwb29mZWQgZW1haWwgYnkgTWFydA0KRnJvbTogIkFkbWluaXN0cmF0b3IiIDxoYWNrZXJAZ21haWwuY29tPg0KWC1Qcmlvcml0eTogMyAoTm9ybWFsKQ0KSW1wb3J0YW5jZTogTm9ybWFsDQpFcnJvcnMtVG86IGhhY2tlckBnbWFpbC5jb20NClJlcGx5LVRvOiBoYWNrZXJAZ21haWwuY29tDQpDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9dXRmLTgNCk1lc3NhZ2UtSWQ6IDwyMDI0MDkyNjA1MzkwMi40NzU5QzFGMDlAZW1rZWkuY3o-DQpEYXRlOiBUaHUsIDI2IFNlcCAyMDI0IDA3OjM5OjAyICswMjAwIChDRVNUKQ0KDQp0ZXN0DQoNCi1NYXJ0IGF0IEZsb3dDcnlwdA0K",
71+
"historyId": "298166",
72+
"internalDate": "1727329142000"
73+
}
74+
}

appium/api-mocks/apis/google/google-messages.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,5 @@ export type GoogleMockMessage =
3131
| 'Encrypted email with public key attached'
3232
| 'Email with another user public key attached'
3333
| 'Test remote images #2414'
34+
| 'Test Spoofed email by Mart'
3435
| 'Test encrypted message sent via encrypted contact page with attachment';

0 commit comments

Comments
 (0)