2024-08-07 08:38:58 +02:00
|
|
|
import type { InboxRule, Mail, MailFolder, MoveMailData } from "../../../common/api/entities/tutanota/TypeRefs.js"
|
2024-07-01 17:56:41 +02:00
|
|
|
import { createMoveMailData } from "../../../common/api/entities/tutanota/TypeRefs.js"
|
2024-08-07 08:38:58 +02:00
|
|
|
import { InboxRuleType, MailSetKind, MAX_NBR_MOVE_DELETE_MAIL_SERVICE } from "../../../common/api/common/TutanotaConstants"
|
2024-07-01 17:56:41 +02:00
|
|
|
import { isDomainName, isRegularExpression } from "../../../common/misc/FormatValidator"
|
2025-02-10 16:07:25 +01:00
|
|
|
import { assertNotNull, asyncFind, ofClass, promiseMap, splitInChunks } from "@tutao/tutanota-utils"
|
2024-07-01 17:56:41 +02:00
|
|
|
import { lang } from "../../../common/misc/LanguageViewModel"
|
2024-08-07 16:29:40 +02:00
|
|
|
import type { MailboxDetail } from "../../../common/mailFunctionality/MailboxModel.js"
|
2024-07-01 17:56:41 +02:00
|
|
|
import { LockedError, PreconditionFailedError } from "../../../common/api/common/error/RestError"
|
|
|
|
|
import type { SelectorItemList } from "../../../common/gui/base/DropDownSelector.js"
|
2024-08-07 08:38:58 +02:00
|
|
|
import { elementIdPart, isSameId } from "../../../common/api/common/utils/EntityUtils"
|
2024-07-01 17:56:41 +02:00
|
|
|
import { assertMainOrNode } from "../../../common/api/common/Env"
|
|
|
|
|
import { MailFacade } from "../../../common/api/worker/facades/lazy/MailFacade.js"
|
|
|
|
|
import { LoginController } from "../../../common/api/main/LoginController.js"
|
2024-09-12 15:34:25 +02:00
|
|
|
import { throttle } from "@tutao/tutanota-utils/dist/Utils.js"
|
2024-08-07 16:29:40 +02:00
|
|
|
import { mailLocator } from "../../mailLocator.js"
|
2024-08-14 11:40:16 +02:00
|
|
|
import { getMailHeaders } from "./MailUtils.js"
|
2022-01-07 15:58:30 +01:00
|
|
|
|
2017-08-15 13:54:22 +02:00
|
|
|
assertMainOrNode()
|
2020-09-28 14:50:34 +02:00
|
|
|
const moveMailDataPerFolder: MoveMailData[] = []
|
|
|
|
|
const DEBOUNCE_FIRST_MOVE_MAIL_REQUEST_MS = 200
|
|
|
|
|
let applyingRules = false // used to avoid concurrent application of rules (-> requests to locked service)
|
|
|
|
|
|
2022-03-09 17:43:29 +01:00
|
|
|
async function sendMoveMailRequest(mailFacade: MailFacade): Promise<void> {
|
2022-01-07 15:58:30 +01:00
|
|
|
if (moveMailDataPerFolder.length) {
|
|
|
|
|
const moveToTargetFolder = assertNotNull(moveMailDataPerFolder.shift())
|
|
|
|
|
const mailChunks = splitInChunks(MAX_NBR_MOVE_DELETE_MAIL_SERVICE, moveToTargetFolder.mails)
|
2022-12-27 15:37:40 +01:00
|
|
|
await promiseMap(mailChunks, (mailChunk) => {
|
2022-01-07 15:58:30 +01:00
|
|
|
moveToTargetFolder.mails = mailChunk
|
2025-02-17 15:34:28 +01:00
|
|
|
return mailFacade.moveMails(mailChunk, moveToTargetFolder.targetFolder, null)
|
2022-01-07 15:58:30 +01:00
|
|
|
})
|
|
|
|
|
.catch(
|
2022-12-27 15:37:40 +01:00
|
|
|
ofClass(LockedError, (e) => {
|
2022-01-07 15:58:30 +01:00
|
|
|
//LockedError should no longer be thrown!?!
|
|
|
|
|
console.log("moving mail failed", e, moveToTargetFolder)
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
.catch(
|
2022-12-27 15:37:40 +01:00
|
|
|
ofClass(PreconditionFailedError, (e) => {
|
2022-01-07 15:58:30 +01:00
|
|
|
// move mail operation may have been locked by other process
|
|
|
|
|
console.log("moving mail failed", e, moveToTargetFolder)
|
|
|
|
|
}),
|
|
|
|
|
)
|
|
|
|
|
.finally(() => {
|
2022-03-09 17:43:29 +01:00
|
|
|
return sendMoveMailRequest(mailFacade)
|
2022-01-07 15:58:30 +01:00
|
|
|
})
|
|
|
|
|
} //We are done and unlock for future requests
|
2020-09-28 14:50:34 +02:00
|
|
|
}
|
|
|
|
|
|
2024-09-12 15:34:25 +02:00
|
|
|
// We throttle the moveMail requests to a rate of 200ms
|
2020-09-28 14:50:34 +02:00
|
|
|
// Each target folder requires one request
|
2024-09-12 15:34:25 +02:00
|
|
|
const applyMatchingRules = throttle(DEBOUNCE_FIRST_MOVE_MAIL_REQUEST_MS, (mailFacade: MailFacade) => {
|
2022-01-07 15:58:30 +01:00
|
|
|
if (applyingRules) return
|
|
|
|
|
// We lock to avoid concurrent requests
|
|
|
|
|
applyingRules = true
|
2022-03-09 17:43:29 +01:00
|
|
|
sendMoveMailRequest(mailFacade).finally(() => {
|
2022-01-07 15:58:30 +01:00
|
|
|
applyingRules = false
|
|
|
|
|
})
|
2020-09-28 14:50:34 +02:00
|
|
|
})
|
2022-01-07 15:58:30 +01:00
|
|
|
|
2019-08-22 18:24:32 +02:00
|
|
|
export function getInboxRuleTypeNameMapping(): SelectorItemList<string> {
|
2022-01-07 15:58:30 +01:00
|
|
|
return [
|
|
|
|
|
{
|
|
|
|
|
value: InboxRuleType.FROM_EQUALS,
|
|
|
|
|
name: lang.get("inboxRuleSenderEquals_action"),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
value: InboxRuleType.RECIPIENT_TO_EQUALS,
|
|
|
|
|
name: lang.get("inboxRuleToRecipientEquals_action"),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
value: InboxRuleType.RECIPIENT_CC_EQUALS,
|
|
|
|
|
name: lang.get("inboxRuleCCRecipientEquals_action"),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
value: InboxRuleType.RECIPIENT_BCC_EQUALS,
|
|
|
|
|
name: lang.get("inboxRuleBCCRecipientEquals_action"),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
value: InboxRuleType.SUBJECT_CONTAINS,
|
|
|
|
|
name: lang.get("inboxRuleSubjectContains_action"),
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
value: InboxRuleType.MAIL_HEADER_CONTAINS,
|
|
|
|
|
name: lang.get("inboxRuleMailHeaderContains_action"),
|
|
|
|
|
},
|
|
|
|
|
]
|
2017-08-15 13:54:22 +02:00
|
|
|
}
|
2022-01-07 15:58:30 +01:00
|
|
|
|
2017-08-15 13:54:22 +02:00
|
|
|
export function getInboxRuleTypeName(type: string): string {
|
2022-12-27 15:37:40 +01:00
|
|
|
let typeNameMapping = getInboxRuleTypeNameMapping().find((t) => t.value === type)
|
2022-01-07 15:58:30 +01:00
|
|
|
return typeNameMapping != null ? typeNameMapping.name : ""
|
2017-08-15 13:54:22 +02:00
|
|
|
}
|
|
|
|
|
|
2023-05-17 16:49:56 +02:00
|
|
|
export class InboxRuleHandler {
|
Remove LegacyMailWrapper (legacy mail bodies) and cleanup TutanotaModel
Prior to starting implementing static MailIds and MailSets, we
want to clean up the current TutanotaModel. Therefore, this commit
removes a lot of legacy metamodel definitions that are not used any
longer, including removing the LegacyMailWrapper (legacy mail bodies).
Additionally, this commit inter alia includes:
* removing types no longer needed after migrating to MailDetails, e.g.
the "body", "toRecipients", "ccRecipients", "bccRecipients",
"replyTos", "sentDate" and "headers" references / values from MAIL_TYPE
* removing "mails" reference form MAIL_BOX_TYPE
* removing "subFolders" reference from MAIL_FOLDER
* removing the legacy types MAIL_BODY_TYPE and MAIL_HEADERS
* removing Value.OLD_OWNER_GROUP_NAME, and Value.OLD_AREA_ID_NAME from
FILE_TYPE and CONTACT_TYPE
Closes #7255
Co-authored-by: sug <sug@tutao.de>
2024-07-23 10:05:35 +02:00
|
|
|
constructor(private readonly mailFacade: MailFacade, private readonly logins: LoginController) {}
|
2023-05-17 16:49:56 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Checks the mail for an existing inbox rule and moves the mail to the target folder of the rule.
|
|
|
|
|
* @returns true if a rule matches otherwise false
|
|
|
|
|
*/
|
2025-02-17 15:34:28 +01:00
|
|
|
async findAndApplyMatchingRule(
|
|
|
|
|
mailboxDetail: MailboxDetail,
|
|
|
|
|
mail: Mail,
|
|
|
|
|
applyRulesOnServer: boolean,
|
2025-05-06 15:09:16 +02:00
|
|
|
applyIfRead: boolean,
|
2025-02-17 15:34:28 +01:00
|
|
|
): Promise<{
|
|
|
|
|
folder: MailFolder
|
|
|
|
|
mail: Mail
|
|
|
|
|
} | null> {
|
2025-05-06 15:09:16 +02:00
|
|
|
const shouldApply = applyIfRead || mail.unread
|
|
|
|
|
|
2024-08-07 16:29:40 +02:00
|
|
|
if (
|
|
|
|
|
mail._errors ||
|
2025-05-06 15:09:16 +02:00
|
|
|
!shouldApply ||
|
2024-10-08 18:30:24 +02:00
|
|
|
!(await isInboxFolder(mailboxDetail, mail)) ||
|
2025-01-03 15:54:45 +01:00
|
|
|
!this.logins.getUserController().isPaidAccount() ||
|
2024-08-07 16:29:40 +02:00
|
|
|
mailboxDetail.mailbox.folders == null
|
|
|
|
|
) {
|
2023-05-17 16:49:56 +02:00
|
|
|
return null
|
|
|
|
|
}
|
2022-01-07 15:58:30 +01:00
|
|
|
|
Remove LegacyMailWrapper (legacy mail bodies) and cleanup TutanotaModel
Prior to starting implementing static MailIds and MailSets, we
want to clean up the current TutanotaModel. Therefore, this commit
removes a lot of legacy metamodel definitions that are not used any
longer, including removing the LegacyMailWrapper (legacy mail bodies).
Additionally, this commit inter alia includes:
* removing types no longer needed after migrating to MailDetails, e.g.
the "body", "toRecipients", "ccRecipients", "bccRecipients",
"replyTos", "sentDate" and "headers" references / values from MAIL_TYPE
* removing "mails" reference form MAIL_BOX_TYPE
* removing "subFolders" reference from MAIL_FOLDER
* removing the legacy types MAIL_BODY_TYPE and MAIL_HEADERS
* removing Value.OLD_OWNER_GROUP_NAME, and Value.OLD_AREA_ID_NAME from
FILE_TYPE and CONTACT_TYPE
Closes #7255
Co-authored-by: sug <sug@tutao.de>
2024-07-23 10:05:35 +02:00
|
|
|
const inboxRule = await _findMatchingRule(this.mailFacade, mail, this.logins.getUserController().props.inboxRules)
|
2022-01-07 15:58:30 +01:00
|
|
|
if (inboxRule) {
|
2024-10-08 18:30:24 +02:00
|
|
|
const folders = await mailLocator.mailModel.getMailboxFoldersForId(mailboxDetail.mailbox.folders._id)
|
2025-01-14 18:20:57 +01:00
|
|
|
const inboxFolder = assertNotNull(folders.getSystemFolderByType(MailSetKind.INBOX))
|
|
|
|
|
const targetFolder = folders.getFolderById(elementIdPart(inboxRule.targetFolder))
|
2022-01-07 15:58:30 +01:00
|
|
|
|
2024-08-07 08:38:58 +02:00
|
|
|
if (targetFolder && targetFolder.folderType !== MailSetKind.INBOX) {
|
2022-01-07 15:58:30 +01:00
|
|
|
if (applyRulesOnServer) {
|
2022-12-27 15:37:40 +01:00
|
|
|
let moveMailData = moveMailDataPerFolder.find((folderMoveMailData) => isSameId(folderMoveMailData.targetFolder, inboxRule.targetFolder))
|
2022-01-07 15:58:30 +01:00
|
|
|
|
|
|
|
|
if (moveMailData) {
|
|
|
|
|
moveMailData.mails.push(mail._id)
|
|
|
|
|
} else {
|
2023-11-09 17:04:42 +01:00
|
|
|
moveMailData = createMoveMailData({
|
|
|
|
|
targetFolder: inboxRule.targetFolder,
|
|
|
|
|
mails: [mail._id],
|
2025-02-17 15:34:28 +01:00
|
|
|
excludeMailSet: null,
|
2023-11-09 17:04:42 +01:00
|
|
|
})
|
2022-01-07 15:58:30 +01:00
|
|
|
moveMailDataPerFolder.push(moveMailData)
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-17 16:49:56 +02:00
|
|
|
applyMatchingRules(this.mailFacade)
|
2022-01-07 15:58:30 +01:00
|
|
|
}
|
|
|
|
|
|
2024-08-07 08:38:58 +02:00
|
|
|
return { folder: targetFolder, mail }
|
2022-01-07 15:58:30 +01:00
|
|
|
} else {
|
|
|
|
|
return null
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return null
|
|
|
|
|
}
|
2023-05-17 16:49:56 +02:00
|
|
|
}
|
2017-08-15 13:54:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Finds the first matching inbox rule for the mail and returns it.
|
|
|
|
|
* export only for testing
|
|
|
|
|
*/
|
Remove LegacyMailWrapper (legacy mail bodies) and cleanup TutanotaModel
Prior to starting implementing static MailIds and MailSets, we
want to clean up the current TutanotaModel. Therefore, this commit
removes a lot of legacy metamodel definitions that are not used any
longer, including removing the LegacyMailWrapper (legacy mail bodies).
Additionally, this commit inter alia includes:
* removing types no longer needed after migrating to MailDetails, e.g.
the "body", "toRecipients", "ccRecipients", "bccRecipients",
"replyTos", "sentDate" and "headers" references / values from MAIL_TYPE
* removing "mails" reference form MAIL_BOX_TYPE
* removing "subFolders" reference from MAIL_FOLDER
* removing the legacy types MAIL_BODY_TYPE and MAIL_HEADERS
* removing Value.OLD_OWNER_GROUP_NAME, and Value.OLD_AREA_ID_NAME from
FILE_TYPE and CONTACT_TYPE
Closes #7255
Co-authored-by: sug <sug@tutao.de>
2024-07-23 10:05:35 +02:00
|
|
|
export async function _findMatchingRule(mailFacade: MailFacade, mail: Mail, rules: InboxRule[]): Promise<InboxRule | null> {
|
|
|
|
|
return asyncFind(rules, (rule) => checkInboxRule(mailFacade, mail, rule)).then((v) => v ?? null)
|
2021-06-23 17:39:31 +02:00
|
|
|
}
|
2017-08-15 13:54:22 +02:00
|
|
|
|
Remove LegacyMailWrapper (legacy mail bodies) and cleanup TutanotaModel
Prior to starting implementing static MailIds and MailSets, we
want to clean up the current TutanotaModel. Therefore, this commit
removes a lot of legacy metamodel definitions that are not used any
longer, including removing the LegacyMailWrapper (legacy mail bodies).
Additionally, this commit inter alia includes:
* removing types no longer needed after migrating to MailDetails, e.g.
the "body", "toRecipients", "ccRecipients", "bccRecipients",
"replyTos", "sentDate" and "headers" references / values from MAIL_TYPE
* removing "mails" reference form MAIL_BOX_TYPE
* removing "subFolders" reference from MAIL_FOLDER
* removing the legacy types MAIL_BODY_TYPE and MAIL_HEADERS
* removing Value.OLD_OWNER_GROUP_NAME, and Value.OLD_AREA_ID_NAME from
FILE_TYPE and CONTACT_TYPE
Closes #7255
Co-authored-by: sug <sug@tutao.de>
2024-07-23 10:05:35 +02:00
|
|
|
async function checkInboxRule(mailFacade: MailFacade, mail: Mail, inboxRule: InboxRule): Promise<boolean> {
|
2022-01-07 15:58:30 +01:00
|
|
|
const ruleType = inboxRule.type
|
|
|
|
|
try {
|
|
|
|
|
if (ruleType === InboxRuleType.FROM_EQUALS) {
|
|
|
|
|
let mailAddresses = [mail.sender.address]
|
|
|
|
|
|
|
|
|
|
if (mail.differentEnvelopeSender) {
|
|
|
|
|
mailAddresses.push(mail.differentEnvelopeSender)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return _checkEmailAddresses(mailAddresses, inboxRule)
|
|
|
|
|
} else if (ruleType === InboxRuleType.RECIPIENT_TO_EQUALS) {
|
Remove LegacyMailWrapper (legacy mail bodies) and cleanup TutanotaModel
Prior to starting implementing static MailIds and MailSets, we
want to clean up the current TutanotaModel. Therefore, this commit
removes a lot of legacy metamodel definitions that are not used any
longer, including removing the LegacyMailWrapper (legacy mail bodies).
Additionally, this commit inter alia includes:
* removing types no longer needed after migrating to MailDetails, e.g.
the "body", "toRecipients", "ccRecipients", "bccRecipients",
"replyTos", "sentDate" and "headers" references / values from MAIL_TYPE
* removing "mails" reference form MAIL_BOX_TYPE
* removing "subFolders" reference from MAIL_FOLDER
* removing the legacy types MAIL_BODY_TYPE and MAIL_HEADERS
* removing Value.OLD_OWNER_GROUP_NAME, and Value.OLD_AREA_ID_NAME from
FILE_TYPE and CONTACT_TYPE
Closes #7255
Co-authored-by: sug <sug@tutao.de>
2024-07-23 10:05:35 +02:00
|
|
|
const toRecipients = (await mailFacade.loadMailDetailsBlob(mail)).recipients.toRecipients
|
2022-01-07 15:58:30 +01:00
|
|
|
return _checkEmailAddresses(
|
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
|
|
|
toRecipients.map((m) => m.address),
|
2022-01-07 15:58:30 +01:00
|
|
|
inboxRule,
|
|
|
|
|
)
|
|
|
|
|
} else if (ruleType === InboxRuleType.RECIPIENT_CC_EQUALS) {
|
Remove LegacyMailWrapper (legacy mail bodies) and cleanup TutanotaModel
Prior to starting implementing static MailIds and MailSets, we
want to clean up the current TutanotaModel. Therefore, this commit
removes a lot of legacy metamodel definitions that are not used any
longer, including removing the LegacyMailWrapper (legacy mail bodies).
Additionally, this commit inter alia includes:
* removing types no longer needed after migrating to MailDetails, e.g.
the "body", "toRecipients", "ccRecipients", "bccRecipients",
"replyTos", "sentDate" and "headers" references / values from MAIL_TYPE
* removing "mails" reference form MAIL_BOX_TYPE
* removing "subFolders" reference from MAIL_FOLDER
* removing the legacy types MAIL_BODY_TYPE and MAIL_HEADERS
* removing Value.OLD_OWNER_GROUP_NAME, and Value.OLD_AREA_ID_NAME from
FILE_TYPE and CONTACT_TYPE
Closes #7255
Co-authored-by: sug <sug@tutao.de>
2024-07-23 10:05:35 +02:00
|
|
|
const ccRecipients = (await mailFacade.loadMailDetailsBlob(mail)).recipients.ccRecipients
|
2022-01-07 15:58:30 +01:00
|
|
|
return _checkEmailAddresses(
|
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
|
|
|
ccRecipients.map((m) => m.address),
|
2022-01-07 15:58:30 +01:00
|
|
|
inboxRule,
|
|
|
|
|
)
|
|
|
|
|
} else if (ruleType === InboxRuleType.RECIPIENT_BCC_EQUALS) {
|
Remove LegacyMailWrapper (legacy mail bodies) and cleanup TutanotaModel
Prior to starting implementing static MailIds and MailSets, we
want to clean up the current TutanotaModel. Therefore, this commit
removes a lot of legacy metamodel definitions that are not used any
longer, including removing the LegacyMailWrapper (legacy mail bodies).
Additionally, this commit inter alia includes:
* removing types no longer needed after migrating to MailDetails, e.g.
the "body", "toRecipients", "ccRecipients", "bccRecipients",
"replyTos", "sentDate" and "headers" references / values from MAIL_TYPE
* removing "mails" reference form MAIL_BOX_TYPE
* removing "subFolders" reference from MAIL_FOLDER
* removing the legacy types MAIL_BODY_TYPE and MAIL_HEADERS
* removing Value.OLD_OWNER_GROUP_NAME, and Value.OLD_AREA_ID_NAME from
FILE_TYPE and CONTACT_TYPE
Closes #7255
Co-authored-by: sug <sug@tutao.de>
2024-07-23 10:05:35 +02:00
|
|
|
const bccRecipients = (await mailFacade.loadMailDetailsBlob(mail)).recipients.bccRecipients
|
2022-01-07 15:58:30 +01:00
|
|
|
return _checkEmailAddresses(
|
add MailDetails feature, #4719
server issues: 1276, 1271, 1279, 1272, 1270, 1258, 1254, 1253, 1242, 1241
2022-11-03 19:03:54 +01:00
|
|
|
bccRecipients.map((m) => m.address),
|
2022-01-07 15:58:30 +01:00
|
|
|
inboxRule,
|
|
|
|
|
)
|
|
|
|
|
} else if (ruleType === InboxRuleType.SUBJECT_CONTAINS) {
|
|
|
|
|
return _checkContainsRule(mail.subject, inboxRule)
|
|
|
|
|
} else if (ruleType === InboxRuleType.MAIL_HEADER_CONTAINS) {
|
Remove LegacyMailWrapper (legacy mail bodies) and cleanup TutanotaModel
Prior to starting implementing static MailIds and MailSets, we
want to clean up the current TutanotaModel. Therefore, this commit
removes a lot of legacy metamodel definitions that are not used any
longer, including removing the LegacyMailWrapper (legacy mail bodies).
Additionally, this commit inter alia includes:
* removing types no longer needed after migrating to MailDetails, e.g.
the "body", "toRecipients", "ccRecipients", "bccRecipients",
"replyTos", "sentDate" and "headers" references / values from MAIL_TYPE
* removing "mails" reference form MAIL_BOX_TYPE
* removing "subFolders" reference from MAIL_FOLDER
* removing the legacy types MAIL_BODY_TYPE and MAIL_HEADERS
* removing Value.OLD_OWNER_GROUP_NAME, and Value.OLD_AREA_ID_NAME from
FILE_TYPE and CONTACT_TYPE
Closes #7255
Co-authored-by: sug <sug@tutao.de>
2024-07-23 10:05:35 +02:00
|
|
|
const details = await mailFacade.loadMailDetailsBlob(mail)
|
|
|
|
|
if (details.headers != null) {
|
|
|
|
|
return _checkContainsRule(getMailHeaders(details.headers), inboxRule)
|
2022-01-07 15:58:30 +01:00
|
|
|
} else {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
console.warn("Unknown rule type: ", inboxRule.type)
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error("Error processing inbox rule:", e.message)
|
|
|
|
|
return false
|
|
|
|
|
}
|
2017-08-15 13:54:22 +02:00
|
|
|
}
|
|
|
|
|
|
2021-06-23 17:39:31 +02:00
|
|
|
function _checkContainsRule(value: string, inboxRule: InboxRule): boolean {
|
2022-01-07 15:58:30 +01:00
|
|
|
return (isRegularExpression(inboxRule.value) && _matchesRegularExpression(value, inboxRule)) || value.includes(inboxRule.value)
|
2017-08-15 13:54:22 +02:00
|
|
|
}
|
2018-07-18 17:22:54 +02:00
|
|
|
|
2017-08-15 13:54:22 +02:00
|
|
|
/** export for test. */
|
|
|
|
|
export function _matchesRegularExpression(value: string, inboxRule: InboxRule): boolean {
|
2022-01-07 15:58:30 +01:00
|
|
|
if (isRegularExpression(inboxRule.value)) {
|
|
|
|
|
let flags = inboxRule.value.replace(/.*\/([gimsuy]*)$/, "$1")
|
|
|
|
|
let pattern = inboxRule.value.replace(new RegExp("^/(.*?)/" + flags + "$"), "$1")
|
|
|
|
|
let regExp = new RegExp(pattern, flags)
|
|
|
|
|
return regExp.test(value)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false
|
2017-08-15 13:54:22 +02:00
|
|
|
}
|
|
|
|
|
|
2021-06-23 17:39:31 +02:00
|
|
|
function _checkEmailAddresses(mailAddresses: string[], inboxRule: InboxRule): boolean {
|
2022-12-27 15:37:40 +01:00
|
|
|
const mailAddress = mailAddresses.find((mailAddress) => {
|
2022-01-07 15:58:30 +01:00
|
|
|
let cleanMailAddress = mailAddress.toLowerCase().trim()
|
|
|
|
|
|
|
|
|
|
if (isRegularExpression(inboxRule.value)) {
|
|
|
|
|
return _matchesRegularExpression(cleanMailAddress, inboxRule)
|
|
|
|
|
} else if (isDomainName(inboxRule.value)) {
|
|
|
|
|
let domain = cleanMailAddress.split("@")[1]
|
|
|
|
|
return domain === inboxRule.value
|
|
|
|
|
} else {
|
|
|
|
|
return cleanMailAddress === inboxRule.value
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
return mailAddress != null
|
2017-08-15 13:54:22 +02:00
|
|
|
}
|
|
|
|
|
|
2024-10-08 18:30:24 +02:00
|
|
|
export async function isInboxFolder(mailboxDetail: MailboxDetail, mail: Mail): Promise<boolean> {
|
|
|
|
|
const folders = await mailLocator.mailModel.getMailboxFoldersForId(assertNotNull(mailboxDetail.mailbox.folders)._id)
|
2024-08-07 16:29:40 +02:00
|
|
|
const mailFolder = folders.getFolderByMail(mail)
|
2024-08-07 08:38:58 +02:00
|
|
|
return mailFolder?.folderType === MailSetKind.INBOX
|
2022-12-27 15:37:40 +01:00
|
|
|
}
|