chore: add new fetaure

This commit is contained in:
mahyargdz
2025-07-20 14:48:02 +03:30
parent 6dd996b30d
commit b2dd55b166
19 changed files with 654 additions and 193 deletions
@@ -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;
}
}
}