chore: add new fetaure
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
import { Injectable, Logger } from "@nestjs/common";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { EmailMessage } from "../../../common/enums/message.enum";
|
||||
import { ListDomainAccessQueryDto } from "../../mail-server/DTO/domain-access.dto";
|
||||
import { MailServerService } from "../../mail-server/services/mail-server.service";
|
||||
import { MessageSenderInfo, SpamActionOptions } from "../interfaces/email-spam.interface";
|
||||
|
||||
@Injectable()
|
||||
export class EmailSpamService {
|
||||
private readonly logger = new Logger(EmailSpamService.name);
|
||||
|
||||
constructor(private readonly mailServerService: MailServerService) {}
|
||||
|
||||
async getMessageSenderInfo(userId: string, messageId: number): Promise<MessageSenderInfo | null> {
|
||||
try {
|
||||
const mailboxes = await firstValueFrom(this.mailServerService.mailboxes.listMailboxes(userId));
|
||||
|
||||
for (const mailbox of mailboxes.results) {
|
||||
try {
|
||||
const message = await firstValueFrom(this.mailServerService.messages.getMessage(userId, mailbox.id, messageId));
|
||||
|
||||
if (message && message.from && message.from.address) {
|
||||
const senderEmail = message.from.address;
|
||||
const senderDomain = senderEmail.split("@")[1]?.toLowerCase();
|
||||
|
||||
if (senderDomain) {
|
||||
return {
|
||||
senderDomain,
|
||||
senderEmail,
|
||||
messageId,
|
||||
};
|
||||
}
|
||||
}
|
||||
} catch (_error) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to get sender info for message ${messageId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================
|
||||
async markAsSpam(options: SpamActionOptions) {
|
||||
const { messageId, wildduckUserId, manageDomainList = false, domainTag = "default" } = options;
|
||||
|
||||
this.logger.log(`Marking message ${messageId} as spam for user: ${wildduckUserId}`);
|
||||
|
||||
try {
|
||||
let domainBlocked = false;
|
||||
|
||||
if (manageDomainList) {
|
||||
const senderInfo = await this.getMessageSenderInfo(wildduckUserId, messageId);
|
||||
|
||||
if (senderInfo) {
|
||||
try {
|
||||
await firstValueFrom(
|
||||
this.mailServerService.domainAccess.addBlockedDomain(domainTag, {
|
||||
domain: senderInfo.senderDomain,
|
||||
description: `Auto-blocked due to spam report from message ${messageId}`,
|
||||
}),
|
||||
);
|
||||
|
||||
domainBlocked = true;
|
||||
this.logger.log(`Added domain ${senderInfo.senderDomain} to blocklist for tag: ${domainTag}`);
|
||||
} catch (error) {
|
||||
this.logger.warn(`Could not add domain to blocklist: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: EmailMessage.MESSAGE_MOVED_TO_JUNK_SUCCESSFULLY,
|
||||
domainBlocked,
|
||||
};
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to mark message ${messageId} as spam: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================
|
||||
async markAsNotSpam(options: SpamActionOptions) {
|
||||
const { messageId, wildduckUserId, manageDomainList = false, domainTag = "default" } = options;
|
||||
|
||||
this.logger.log(`Marking message ${messageId} as not spam for user: ${wildduckUserId}`);
|
||||
|
||||
try {
|
||||
let domainAllowed = false;
|
||||
|
||||
if (manageDomainList) {
|
||||
const senderInfo = await this.getMessageSenderInfo(wildduckUserId, messageId);
|
||||
|
||||
if (senderInfo) {
|
||||
try {
|
||||
await firstValueFrom(
|
||||
this.mailServerService.domainAccess.addAllowedDomain(domainTag, {
|
||||
domain: senderInfo.senderDomain,
|
||||
description: `Auto-allowed due to not-spam report from message ${messageId}`,
|
||||
}),
|
||||
);
|
||||
|
||||
domainAllowed = true;
|
||||
this.logger.log(`Added domain ${senderInfo.senderDomain} to allowlist for tag: ${domainTag}`);
|
||||
} catch (error) {
|
||||
this.logger.warn(`Could not add domain to allowlist: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: EmailMessage.MESSAGE_MOVED_TO_INBOX_FROM_JUNK_SUCCESSFULLY,
|
||||
domainAllowed,
|
||||
};
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to mark message ${messageId} as not spam: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================
|
||||
async listAllowedDomains(domainTag = "default", query?: ListDomainAccessQueryDto) {
|
||||
this.logger.log(`Listing allowed domains for tag: ${domainTag}`);
|
||||
|
||||
try {
|
||||
return await firstValueFrom(this.mailServerService.domainAccess.listAllowedDomains(domainTag, query));
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to list allowed domains: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================
|
||||
async listBlockedDomains(domainTag = "default", query?: ListDomainAccessQueryDto) {
|
||||
this.logger.log(`Listing blocked domains for tag: ${domainTag}`);
|
||||
|
||||
try {
|
||||
return await firstValueFrom(this.mailServerService.domainAccess.listBlockedDomains(domainTag, query));
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to list blocked domains: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================
|
||||
async removeDomainFromAllowlist(domain: string, domainTag = "default") {
|
||||
this.logger.log(`Removing domain ${domain} from allowlist for tag: ${domainTag}`);
|
||||
|
||||
try {
|
||||
return await firstValueFrom(this.mailServerService.domainAccess.removeAllowedDomain(domainTag, domain));
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to remove domain from allowlist: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================
|
||||
async removeDomainFromBlocklist(domain: string, domainTag = "default") {
|
||||
this.logger.log(`Removing domain ${domain} from blocklist for tag: ${domainTag}`);
|
||||
|
||||
try {
|
||||
return await firstValueFrom(this.mailServerService.domainAccess.removeBlockedDomain(domainTag, domain));
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to remove domain from blocklist: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================
|
||||
async addDomainToAllowlist(domain: string, description?: string, domainTag = "default") {
|
||||
this.logger.log(`Adding domain ${domain} to allowlist for tag: ${domainTag}`);
|
||||
|
||||
try {
|
||||
return await firstValueFrom(
|
||||
this.mailServerService.domainAccess.addAllowedDomain(domainTag, {
|
||||
domain,
|
||||
description: description || `Manually added to allowlist`,
|
||||
}),
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to add domain to allowlist: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================
|
||||
async addDomainToBlocklist(domain: string, description?: string, domainTag = "default") {
|
||||
this.logger.log(`Adding domain ${domain} to blocklist for tag: ${domainTag}`);
|
||||
|
||||
try {
|
||||
return await firstValueFrom(
|
||||
this.mailServerService.domainAccess.addBlockedDomain(domainTag, {
|
||||
domain,
|
||||
description: description || `Manually added to blocklist`,
|
||||
}),
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.error(`Failed to add domain to blocklist: ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user