Skip to content

Commit

Permalink
fix: missing backup query (#2296)
Browse files Browse the repository at this point in the history
  • Loading branch information
ioanmo226 authored Jul 25, 2023
1 parent d319eef commit b907686
Show file tree
Hide file tree
Showing 15 changed files with 15,771 additions and 64,217 deletions.
9 changes: 0 additions & 9 deletions Core/source/core/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,3 @@ export const GMAIL_RECOVERY_EMAIL_SUBJECTS = [
'All you need to know about CryptUP (contains a backup)',
'CryptUP Account Backup',
];

export const gmailBackupSearchQuery = (acctEmail: string) => {
return [
'from:' + acctEmail,
'to:' + acctEmail,
'(subject:"' + GMAIL_RECOVERY_EMAIL_SUBJECTS.join('" OR subject: "') + '")',
'-is:spam',
].join(' ');
};
6 changes: 0 additions & 6 deletions Core/source/mobile-interface/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { Str } from '../core/common';
import { VERSION } from '../core/const';
import { ValidateInput, readArmoredKeyOrThrow, NodeRequest } from './validate-input';
import { Xss } from '../platform/xss';
import { gmailBackupSearchQuery } from '../core/const';
import { config, encryptKey, Key, PrivateKey, readKey, readKeys } from 'openpgp';

export class Endpoints {
Expand Down Expand Up @@ -354,11 +353,6 @@ export class Endpoints {
}
};

public gmailBackupSearch = async (uncheckedReq: unknown): Promise<EndpointRes> => {
const { acctEmail } = ValidateInput.gmailBackupSearch(uncheckedReq);
return fmtRes({ query: gmailBackupSearchQuery(acctEmail) });
};

public parseKeys = async (_uncheckedReq: unknown, data: Buffers): Promise<EndpointRes> => {
const keyDetails: KeyDetails[] = [];
const allData = Buf.concat(data);
Expand Down
8 changes: 0 additions & 8 deletions Core/source/mobile-interface/validate-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ export namespace NodeRequest {
guesses: undefined;
// eslint-disable-next-line @typescript-eslint/indent
};
export type gmailBackupSearch = { acctEmail: string };
export type isEmailValid = { email: string };
export type decryptKey = { armored: string; passphrases: string[] };
export type encryptKey = { armored: string; passphrase: string };
Expand Down Expand Up @@ -186,13 +185,6 @@ export class ValidateInput {
throw new Error('Wrong request structure for NodeRequest.zxcvbnStrengthBar');
};

public static gmailBackupSearch = (v: unknown): NodeRequest.gmailBackupSearch => {
if (isObj(v) && hasProp(v, 'acctEmail', 'string')) {
return v as NodeRequest.gmailBackupSearch;
}
throw new Error('Wrong request structure for NodeRequest.gmailBackupSearchQuery');
};

public static isEmailValid = (v: unknown): NodeRequest.isEmailValid => {
if (isObj(v) && hasProp(v, 'email', 'string')) {
return v as NodeRequest.isEmailValid;
Expand Down
12 changes: 0 additions & 12 deletions Core/source/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -466,18 +466,6 @@ for (const keypairName of allKeypairNames.filter(name => name !== 'expired' && n
});
}

test('gmailBackupSearch', async t => {
const { data, json } = await endpoints.gmailBackupSearch({ acctEmail: '[email protected]' });
expect(json).to.deep.equal({
query:
'from:[email protected] to:[email protected] (subject:"Your FlowCrypt Backup" OR subject: ' +
'"Your CryptUp Backup" OR subject: "All you need to know about CryptUP (contains a backup)"' +
' OR subject: "CryptUP Account Backup") -is:spam',
});
expectNoData(data);
t.pass();
});

test('isEmailValid - true', async t => {
const { data, json } = await endpoints.isEmailValid({ email: '[email protected]' });
expect(json).to.deep.equal({ valid: true });
Expand Down
4 changes: 0 additions & 4 deletions FlowCrypt.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@
9F17976D2368EEBD002BF770 /* SetupViewDecorator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F17976C2368EEBD002BF770 /* SetupViewDecorator.swift */; };
9F23EA50237217140017DFED /* ComposeViewDecorator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F23EA4F237217140017DFED /* ComposeViewDecorator.swift */; };
9F268891237DC55600428A94 /* SetupManuallyImportKeyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F268890237DC55600428A94 /* SetupManuallyImportKeyViewController.swift */; };
9F2AC5B1267BDED100F6149B /* GmailBackupSearchQueryProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F2AC5B0267BDED100F6149B /* GmailBackupSearchQueryProvider.swift */; };
9F31AB8C23298B3F00CF87EA /* Imap+retry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F31AB8B23298B3F00CF87EA /* Imap+retry.swift */; };
9F31AB8E23298BCF00CF87EA /* Imap+folders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F31AB8D23298BCF00CF87EA /* Imap+folders.swift */; };
9F31AB91232993F500CF87EA /* Imap+session.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F31AB90232993F500CF87EA /* Imap+session.swift */; };
Expand Down Expand Up @@ -656,7 +655,6 @@
9F23EA4D237216FA0017DFED /* TextViewCellNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewCellNode.swift; sourceTree = "<group>"; };
9F23EA4F237217140017DFED /* ComposeViewDecorator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeViewDecorator.swift; sourceTree = "<group>"; };
9F268890237DC55600428A94 /* SetupManuallyImportKeyViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetupManuallyImportKeyViewController.swift; sourceTree = "<group>"; };
9F2AC5B0267BDED100F6149B /* GmailBackupSearchQueryProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GmailBackupSearchQueryProvider.swift; sourceTree = "<group>"; };
9F2AC5C6267BE99E00F6149B /* FlowCryptAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FlowCryptAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
9F2AC5CA267BE99E00F6149B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9F31AB8B23298B3F00CF87EA /* Imap+retry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Imap+retry.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1716,7 +1714,6 @@
9FC411202595EA12001180A8 /* MessageSearchApiClient.swift */,
9FC4112D2595EA8B001180A8 /* Gmail+Search.swift */,
9FC411342595EA94001180A8 /* Imap+Search.swift */,
9F2AC5B0267BDED100F6149B /* GmailBackupSearchQueryProvider.swift */,
);
path = "SearchMessage Provider";
sourceTree = "<group>";
Expand Down Expand Up @@ -2827,7 +2824,6 @@
2CAF25322756C37E005C7C7C /* AppContext.swift in Sources */,
514C34DD276CE1C000FCAB79 /* ComposeMessageRecipient.swift in Sources */,
2CAF25342756C3A6005C7C7C /* ImapSessionProvider.swift in Sources */,
9F2AC5B1267BDED100F6149B /* GmailBackupSearchQueryProvider.swift in Sources */,
040FDF1227EDFC5C00CB936A /* IdTokenUtils.swift in Sources */,
9F953E09238310D500AEB98B /* KeyMethods.swift in Sources */,
5137CB1427F8E0A900AEF895 /* EnterpriseServerApiHelper.swift in Sources */,
Expand Down
6 changes: 6 additions & 0 deletions FlowCrypt/App/GeneralConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ enum GeneralConstants {
static let contactsScope: [GoogleScope] = mailScope + [.contacts, .otherContacts]
// Empty pass is For All MAIL
static let standardGmailPaths = ["INBOX", "CHAT", "SENT", "IMPORTANT", "TRASH", "DRAFT", "SPAM", "STARRED", "UNREAD", ""]
static let gmailRecoveryEmailSubjects = [
"Your FlowCrypt Backup",
"Your CryptUp Backup",
"All you need to know about CryptUP (contains a backup)",
"CryptUP Account Backup"
]
}

enum Global {
Expand Down
10 changes: 0 additions & 10 deletions FlowCrypt/Core/Core.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ class Core: KeyDecrypter, KeyParser, CoreComposeMessageType {
let data: Data
}

private struct GmailBackupSearchResponse: Decodable {
let query: String
}

private struct AttachmentTreatAsResponse: Decodable {
let atts: [CoreRes.AttachmentTreatAs]
}
Expand Down Expand Up @@ -250,12 +246,6 @@ class Core: KeyDecrypter, KeyParser, CoreComposeMessageType {
return try r.json.decodeJson(as: CoreRes.ZxcvbnStrengthBar.self)
}

func gmailBackupSearch(for email: String) async throws -> String {
let response = try await call("gmailBackupSearch", params: ["acctEmail": email])
let result = try response.json.decodeJson(as: GmailBackupSearchResponse.self)
return result.query
}

// MARK: Private calls
@discardableResult
private func call(_ endpoint: String, params: [String: Any?] = [:], data: Data = Data(), retryAttempt: Int = 0) async throws -> RawRes {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ extension GmailService: BackupApiClient {
func searchBackups(for email: String) async throws -> Data {
do {
logger.logVerbose("will begin searching for backups")
let query = try await backupSearchQueryProvider.makeBackupQuery(for: email)
let query = makeBackupQuery(acctEmail: email)
let backupMessages = try await searchExpression(using: MessageSearchContext(expression: query))
logger.logVerbose("searching done, found \(backupMessages.count) backup messages")
let uniqueMessages = Set(backupMessages)
Expand All @@ -36,10 +36,20 @@ extension GmailService: BackupApiClient {
logger.logVerbose("downloaded \(attachments.count) attachments that contain \(data.count / 1024)kB of data")
return data
} catch {
throw GmailApiError.missingBackupQuery(error)
throw GmailApiError.searchBackup(error)
}
}

func makeBackupQuery(acctEmail: String) -> String {
var subjectQueryComponents: [String] = []
for subject in GeneralConstants.Gmail.gmailRecoveryEmailSubjects {
subjectQueryComponents.append("subject:\"\(subject)\"")
}
let subjectQuery = subjectQueryComponents.joined(separator: " OR ")
let searchQuery = "from:\(acctEmail) to:\(acctEmail) \(subjectQuery) -is:spam"
return searchQuery
}

func findAttachment(_ context: (messageId: String, attachmentId: String)) async throws -> Data {
let query = GTLRGmailQuery_UsersMessagesAttachmentsGet.query(
withUserId: .me,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ enum GmailApiError: Error {
case missingMessageInfo(String)
/// Provider Error
case providerError(Error)
/// Empty or invalid backup search query
case missingBackupQuery(Error)
/// Search backup error
case searchBackup(Error)
/// Pagination Error
case paginationError(MessagesListPagination?)
/// Invalid auth grant
Expand All @@ -42,8 +42,8 @@ extension GmailApiError: LocalizedError {
return "gmail_service_provider_error_error_message".localizeWithArguments(error.localizedDescription)
case let .paginationError(pagination):
return "gmail_service_pagination_error".localizeWithArguments(String(describing: pagination))
case let .missingBackupQuery(error):
return "gmail_service_missing_back_query_error_message".localizeWithArguments(error.localizedDescription)
case let .searchBackup(error):
return "gmail_service_search_backup_error_message".localizeWithArguments(error.localizedDescription)
case .invalidGrant:
return "gmail_service_invalid_grant_error_message".localized
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ class GmailService: MailServiceProvider {
let currentUserEmail: String
let mailServiceProviderType = MailServiceProviderType.gmail
let googleAuthManager: GoogleAuthManagerType
let backupSearchQueryProvider: GmailBackupSearchQueryProviderType

let logger = Logger.nested("GmailService")
var gmailService: GTLRService {
Expand Down Expand Up @@ -43,12 +42,10 @@ class GmailService: MailServiceProvider {

init(
currentUserEmail: String,
googleAuthManager: GoogleAuthManagerType,
backupSearchQueryProvider: GmailBackupSearchQueryProviderType = GmailBackupSearchQueryProvider()
googleAuthManager: GoogleAuthManagerType
) {
self.currentUserEmail = currentUserEmail
self.googleAuthManager = googleAuthManager
self.backupSearchQueryProvider = backupSearchQueryProvider
}
}

Expand Down

This file was deleted.

2 changes: 1 addition & 1 deletion FlowCrypt/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@
"gmail_service_provider_error_error_message" = "Gmail provider error:\n%@";
"gmail_service_invalid_grant_error_message" = "Access to %@ account was revoked.\n\nPlease reconnect the app to Gmail";
"gmail_service_pagination_error" = "Pagination %@ is not supported for this provider";
"gmail_service_missing_back_query_error_message" = "Missing backup query: %@";
"gmail_service_search_backup_error_message" = "Error while fetching backups. Error: %@";
"gmail_service_no_access_to_account_message" = "Google login successful.\nNow connect your inbox on the next screen. The grant is stored locally on your device, never shared with anyone.";

// Google User Service errors
Expand Down
Loading

0 comments on commit b907686

Please sign in to comment.