708 lines
26 KiB
TypeScript
708 lines
26 KiB
TypeScript
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
|
import { firstValueFrom } from "rxjs";
|
|
|
|
import { MailboxResolverService } from "./mailbox-resolver.service";
|
|
import { EmailMessage } from "../../../common/enums/message.enum";
|
|
import { MailServerService } from "../../mail-server/services/mail-server.service";
|
|
import { MailboxEnum } from "../../mailbox/enums/mailbox.enum";
|
|
import { MessageListQueryDto, SearchMessagesQueryDto } from "../DTO/email-query.dto";
|
|
import { SendEmailDto, UpdateDraftDto } from "../DTO/send-email.dto";
|
|
import { EmailGateway } from "../email.gateway";
|
|
import { EmailDeletePayload, EmailMovePayload, EmailStatusUpdatePayload } from "../interfaces/email-events.interface";
|
|
|
|
@Injectable()
|
|
export class EmailService {
|
|
private readonly logger = new Logger(EmailService.name);
|
|
|
|
constructor(
|
|
private readonly mailServerService: MailServerService,
|
|
private readonly mailboxResolverService: MailboxResolverService,
|
|
private readonly emailGateway: EmailGateway,
|
|
// private readonly userService: UsersService,
|
|
) {}
|
|
|
|
//########################################################
|
|
async sendEmail(userEmailId: string, sendEmailDto: SendEmailDto) {
|
|
// const userEmailId = await this.userService.getUserEmailIdFromId(userId);
|
|
|
|
this.logger.log(`Sending email from user ${userEmailId} to ${sendEmailDto.to.map((t) => t.address).join(", ")}`);
|
|
|
|
try {
|
|
const response = await firstValueFrom(this.mailServerService.submission.submitMessage(userEmailId, sendEmailDto));
|
|
|
|
this.logger.log(`Email sent successfully: ${response.id} (Queue: ${response.queueId})`);
|
|
|
|
return {
|
|
message: EmailMessage.EMAIL_SENDING_SUCCESS,
|
|
messageId: response.id,
|
|
queueId: response.queueId,
|
|
from: response.from,
|
|
to: response.to,
|
|
subject: response.subject,
|
|
created: response.created,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(`Failed to send email for user ${userEmailId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//########################################################
|
|
async getEmailStatus(queueId: string) {
|
|
this.logger.log(`Getting email status for queue: ${queueId}`);
|
|
|
|
try {
|
|
const response = await firstValueFrom(this.mailServerService.submission.getQueueStatus(queueId));
|
|
|
|
this.logger.log(`Retrieved status for queue ${queueId}: ${response.status}`);
|
|
|
|
return {
|
|
message: EmailMessage.EMAIL_STATUS_RETRIEVED_SUCCESSFULLY,
|
|
...response,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(`Failed to get email status for queue ${queueId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//########################################################
|
|
async searchMessages(userId: string, query: SearchMessagesQueryDto) {
|
|
this.logger.log(`Searching messages for user ${userId} with query: ${query.q}`);
|
|
|
|
try {
|
|
const response = await firstValueFrom(
|
|
this.mailServerService.messages.searchMessages(userId, { query: query.q || "", limit: query.limit, page: query.page }),
|
|
);
|
|
|
|
this.logger.log(`Found ${response.results.length} messages matching search for user: ${userId}`);
|
|
|
|
return {
|
|
message: EmailMessage.MESSAGES_SEARCHED_SUCCESSFULLY,
|
|
...response,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(`Failed to search messages for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//########################################################
|
|
async listMessages(userId: string, query: MessageListQueryDto) {
|
|
try {
|
|
const inboxMailboxId = await this.mailboxResolverService.getInboxMailboxId(userId);
|
|
this.logger.log(`Listing messages in mailbox ${inboxMailboxId} for user: ${userId}`);
|
|
|
|
const { results, total: count } = await firstValueFrom(this.mailServerService.messages.listMessages(userId, inboxMailboxId, query));
|
|
|
|
this.logger.log(`Found ${count} messages in mailbox ${inboxMailboxId} for user: ${userId}`);
|
|
|
|
return {
|
|
message: EmailMessage.MESSAGES_LISTED_SUCCESSFULLY,
|
|
results,
|
|
count,
|
|
paginate: true,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(`Failed to list messages for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//########################################################
|
|
async getMessage(userId: string, messageId: number) {
|
|
try {
|
|
const messageLocation = await this.findMessageMailbox(userId, messageId);
|
|
|
|
if (!messageLocation) throw new BadRequestException(EmailMessage.MESSAGE_NOT_FOUND);
|
|
|
|
this.logger.log(`Getting message ${messageId} from ${messageLocation.mailboxName} mailbox for user: ${userId}`);
|
|
|
|
await this.markMessageAsSeen(userId, messageId);
|
|
const message = await firstValueFrom(this.mailServerService.messages.getMessage(userId, messageLocation.mailboxId, messageId));
|
|
|
|
this.logger.log(`Retrieved message ${messageId} from ${messageLocation.mailboxName} for user: ${userId}`);
|
|
|
|
return {
|
|
message,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(`Failed to get message ${messageId} for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//########################################################
|
|
|
|
private async findMessageMailbox(userId: string, messageId: number): Promise<{ mailboxId: string; mailboxName: string } | null> {
|
|
try {
|
|
const mailboxIds = await this.mailboxResolverService.getUserMailboxIds(userId);
|
|
|
|
const mailboxesToSearch = [
|
|
{ id: mailboxIds.inbox, name: MailboxEnum.INBOX },
|
|
{ id: mailboxIds.sent, name: MailboxEnum.SENT },
|
|
{ id: mailboxIds.drafts, name: MailboxEnum.DRAFTS },
|
|
{ id: mailboxIds.trash, name: MailboxEnum.TRASH },
|
|
{ id: mailboxIds.archive, name: MailboxEnum.ARCHIVE },
|
|
{ id: mailboxIds.favorite, name: MailboxEnum.FAVORITE },
|
|
{ id: mailboxIds.junk, name: MailboxEnum.Junk },
|
|
];
|
|
|
|
for (const mailbox of mailboxesToSearch) {
|
|
if (!mailbox.id) continue;
|
|
|
|
try {
|
|
await firstValueFrom(this.mailServerService.messages.getMessage(userId, mailbox.id, messageId));
|
|
this.logger.log(`Message ${messageId} found in ${mailbox.name} mailbox`);
|
|
return { mailboxId: mailbox.id, mailboxName: mailbox.name };
|
|
} catch (_error) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
this.logger.warn(`Message ${messageId} not found in any mailbox for user ${userId}`);
|
|
return null;
|
|
} catch (error) {
|
|
this.logger.error(`Failed to find message ${messageId} for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//########################################################
|
|
async deleteMessage(userId: string, messageId: number) {
|
|
try {
|
|
const messageLocation = await this.findMessageMailbox(userId, messageId);
|
|
|
|
if (!messageLocation) throw new BadRequestException(EmailMessage.MESSAGE_NOT_FOUND);
|
|
|
|
this.logger.log(`Deleting message ${messageId} from ${messageLocation.mailboxName} mailbox for user: ${userId}`);
|
|
|
|
const result = await firstValueFrom(this.mailServerService.messages.deleteMessage(userId, messageLocation.mailboxId, messageId));
|
|
|
|
// Emit WebSocket notification
|
|
const payload: EmailDeletePayload = {
|
|
messageId,
|
|
userId,
|
|
mailboxId: messageLocation.mailboxId,
|
|
mailboxName: messageLocation.mailboxName,
|
|
timestamp: new Date().toISOString(),
|
|
};
|
|
await this.emailGateway.notifyMessageDeleted(payload);
|
|
|
|
this.logger.log(`Message ${messageId} deleted successfully from ${messageLocation.mailboxName}`);
|
|
|
|
return {
|
|
success: true,
|
|
message: EmailMessage.MESSAGE_DELETED_SUCCESSFULLY,
|
|
result,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(`Failed to delete message ${messageId} for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//==============================================
|
|
async markMessageAsSeen(userId: string, messageId: number) {
|
|
try {
|
|
const messageLocation = await this.findMessageMailbox(userId, messageId);
|
|
|
|
if (!messageLocation) throw new BadRequestException(EmailMessage.MESSAGE_NOT_FOUND);
|
|
|
|
this.logger.log(`Marking message ${messageId} as seen in ${messageLocation.mailboxName} mailbox for user: ${userId}`);
|
|
|
|
const result = await firstValueFrom(
|
|
this.mailServerService.messages.updateMessage(userId, messageLocation.mailboxId, messageId, { seen: true }),
|
|
);
|
|
|
|
// Emit WebSocket notification
|
|
const payload: EmailStatusUpdatePayload = {
|
|
messageId,
|
|
userId,
|
|
status: "read",
|
|
mailboxId: messageLocation.mailboxId,
|
|
timestamp: new Date().toISOString(),
|
|
};
|
|
await this.emailGateway.notifyMessageStatusUpdate(payload);
|
|
|
|
this.logger.log(`Message ${messageId} marked as seen successfully in ${messageLocation.mailboxName}`);
|
|
|
|
return {
|
|
success: true,
|
|
message: EmailMessage.MESSAGE_MARKED_AS_SEEN_SUCCESSFULLY,
|
|
data: result,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(
|
|
`Failed to mark message ${messageId} as seen for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//==============================================
|
|
async getSentMessages(userId: string, query: MessageListQueryDto) {
|
|
try {
|
|
const sentMailboxId = await this.mailboxResolverService.getSentMailboxId(userId);
|
|
const { results: sentMails, total: count } = await firstValueFrom(this.mailServerService.messages.listMessages(userId, sentMailboxId, query));
|
|
|
|
return {
|
|
sentMails,
|
|
count,
|
|
paginate: true,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(`Failed to get sent messages for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//==============================================
|
|
async getTrashMessages(userId: string, query: MessageListQueryDto) {
|
|
try {
|
|
const trashMailboxId = await this.mailboxResolverService.getTrashMailboxId(userId);
|
|
const { results: trashMails, total: count } = await firstValueFrom(this.mailServerService.messages.listMessages(userId, trashMailboxId, query));
|
|
return {
|
|
trashMails,
|
|
count,
|
|
paginate: true,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(`Failed to get trash messages for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
throw error;
|
|
}
|
|
}
|
|
//==============================================
|
|
|
|
async getJunkMessages(userId: string, query: MessageListQueryDto) {
|
|
try {
|
|
const junkMailboxId = await this.mailboxResolverService.getJunkMailboxId(userId);
|
|
const { results: junkMails, total: count } = await firstValueFrom(this.mailServerService.messages.listMessages(userId, junkMailboxId, query));
|
|
|
|
return {
|
|
junkMails,
|
|
count,
|
|
paginate: true,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(`Failed to get junk messages for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
throw error;
|
|
}
|
|
}
|
|
//==============================================
|
|
|
|
async getArchivedMessages(userId: string, query: MessageListQueryDto) {
|
|
try {
|
|
const archiveMailboxId = await this.mailboxResolverService.getArchiveMailboxId(userId);
|
|
const { results: archiveMails, total: count } = await firstValueFrom(
|
|
this.mailServerService.messages.listMessages(userId, archiveMailboxId, query),
|
|
);
|
|
|
|
return {
|
|
archiveMails,
|
|
count,
|
|
paginate: true,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(`Failed to get archive messages for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
throw error;
|
|
}
|
|
}
|
|
//==============================================
|
|
|
|
async getFavoriteMessages(userId: string, query: MessageListQueryDto) {
|
|
try {
|
|
const favoriteMailboxId = await this.mailboxResolverService.getFavoriteMailboxId(userId);
|
|
const { results: favoriteMails, total: count } = await firstValueFrom(
|
|
this.mailServerService.messages.listMessages(userId, favoriteMailboxId, query),
|
|
);
|
|
|
|
return {
|
|
favoriteMails,
|
|
count,
|
|
paginate: true,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(`Failed to get junk messages for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//==============================================
|
|
|
|
async getDraftsMessages(userId: string, query: MessageListQueryDto) {
|
|
try {
|
|
const draftsMailboxId = await this.mailboxResolverService.getDraftsMailboxId(userId);
|
|
|
|
const { results: draftsMail, total: count } = await firstValueFrom(
|
|
this.mailServerService.messages.listMessages(userId, draftsMailboxId, query),
|
|
);
|
|
return {
|
|
draftsMail,
|
|
count,
|
|
paginate: true,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(`Failed to get drafts messages for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//==============================================
|
|
async updateDraft(userEmailId: string, messageId: number, updateDraftDto: UpdateDraftDto) {
|
|
this.logger.log(`Updating draft ${messageId} for user ${userEmailId}`);
|
|
|
|
try {
|
|
const draftsMailboxId = await this.mailboxResolverService.getDraftsMailboxId(userEmailId);
|
|
const existingDraft = await firstValueFrom(this.mailServerService.messages.getMessage(userEmailId, draftsMailboxId, messageId));
|
|
|
|
const draftData: SendEmailDto = {
|
|
mailbox: updateDraftDto.mailbox,
|
|
from: updateDraftDto.from || { address: existingDraft.from?.address || "" },
|
|
to: updateDraftDto.to || [],
|
|
cc: updateDraftDto.cc,
|
|
bcc: updateDraftDto.bcc,
|
|
replyTo: updateDraftDto.replyTo,
|
|
headers: updateDraftDto.headers,
|
|
subject: updateDraftDto.subject,
|
|
text: updateDraftDto.text,
|
|
html: updateDraftDto.html,
|
|
attachments: updateDraftDto.attachments,
|
|
meta: updateDraftDto.meta,
|
|
sess: updateDraftDto.sess,
|
|
ip: updateDraftDto.ip,
|
|
reference: updateDraftDto.reference,
|
|
isDraft: true,
|
|
uploadOnly: true,
|
|
draft: {
|
|
mailbox: draftsMailboxId,
|
|
id: messageId,
|
|
},
|
|
};
|
|
|
|
const response = await firstValueFrom(this.mailServerService.submission.submitMessage(userEmailId, draftData));
|
|
|
|
this.logger.log(`Draft updated successfully: ${response.id}`);
|
|
|
|
return {
|
|
message: EmailMessage.DRAFT_UPDATED_SUCCESSFULLY,
|
|
messageId: response.id,
|
|
from: response.from,
|
|
to: response.to,
|
|
subject: response.subject || "Draft",
|
|
updated: response.created,
|
|
isDraft: true,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(`Failed to update draft ${messageId} for user ${userEmailId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//==============================================
|
|
async sendDraft(userId: string, messageId: number) {
|
|
this.logger.log(`Sending draft ${messageId} for user: ${userId}`);
|
|
|
|
try {
|
|
const draftsMailboxId = await this.mailboxResolverService.getDraftsMailboxId(userId);
|
|
const result = await firstValueFrom(
|
|
this.mailServerService.messages.submitDraft(userId, draftsMailboxId, messageId, {
|
|
deleteFiles: false,
|
|
}),
|
|
);
|
|
|
|
this.logger.log(`Draft ${messageId} sent successfully`);
|
|
|
|
return {
|
|
message: EmailMessage.DRAFT_SENT_SUCCESSFULLY,
|
|
messageId: result.id,
|
|
queueId: result.queueId,
|
|
result,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(`Failed to send draft ${messageId} for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//==============================================
|
|
async deleteDraft(userId: string, messageId: number) {
|
|
this.logger.log(`Deleting draft ${messageId} for user: ${userId}`);
|
|
|
|
try {
|
|
const draftsMailboxId = await this.mailboxResolverService.getDraftsMailboxId(userId);
|
|
const result = await firstValueFrom(this.mailServerService.messages.deleteMessage(userId, draftsMailboxId, messageId));
|
|
|
|
this.logger.log(`Draft ${messageId} deleted successfully`);
|
|
|
|
return {
|
|
message: EmailMessage.DRAFT_DELETED_SUCCESSFULLY,
|
|
result,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(`Failed to delete draft ${messageId} for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//==============================================
|
|
async moveMessageToArchive(userId: string, messageId: number) {
|
|
this.logger.log(`Moving message ${messageId} to archive for user: ${userId}`);
|
|
|
|
try {
|
|
const messageLocation = await this.findMessageMailbox(userId, messageId);
|
|
|
|
if (!messageLocation) throw new BadRequestException(EmailMessage.MESSAGE_NOT_FOUND);
|
|
|
|
const archiveMailboxId = await this.mailboxResolverService.getArchiveMailboxId(userId);
|
|
|
|
this.logger.log(`Moving message ${messageId} from ${messageLocation.mailboxName} to ${MailboxEnum.ARCHIVE} for user: ${userId}`);
|
|
|
|
const result = await firstValueFrom(
|
|
this.mailServerService.messages.updateMessage(userId, messageLocation.mailboxId, messageId, {
|
|
moveTo: archiveMailboxId,
|
|
}),
|
|
);
|
|
|
|
// Emit WebSocket notification
|
|
const payload: EmailMovePayload = {
|
|
messageId,
|
|
userId,
|
|
fromMailboxId: messageLocation.mailboxId,
|
|
toMailboxId: archiveMailboxId,
|
|
fromMailboxName: messageLocation.mailboxName,
|
|
toMailboxName: MailboxEnum.ARCHIVE,
|
|
timestamp: new Date().toISOString(),
|
|
};
|
|
await this.emailGateway.notifyMessageMoved(payload);
|
|
|
|
this.logger.log(`Message ${messageId} moved to archive successfully from ${messageLocation.mailboxName}`);
|
|
|
|
return {
|
|
success: true,
|
|
message: EmailMessage.MESSAGE_MOVED_TO_ARCHIVE_SUCCESSFULLY,
|
|
result,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(
|
|
`Failed to move message ${messageId} to archive for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//==============================================
|
|
async moveMessageToFavorite(userId: string, messageId: number) {
|
|
this.logger.log(`Moving message ${messageId} to favorite for user: ${userId}`);
|
|
|
|
try {
|
|
const messageLocation = await this.findMessageMailbox(userId, messageId);
|
|
|
|
if (!messageLocation) throw new BadRequestException(EmailMessage.MESSAGE_NOT_FOUND);
|
|
|
|
const favoriteMailboxId = await this.mailboxResolverService.getFavoriteMailboxId(userId);
|
|
|
|
this.logger.log(`Moving message ${messageId} from ${messageLocation.mailboxName} to ${MailboxEnum.FAVORITE} for user: ${userId}`);
|
|
|
|
const result = await firstValueFrom(
|
|
this.mailServerService.messages.updateMessage(userId, messageLocation.mailboxId, messageId, {
|
|
moveTo: favoriteMailboxId,
|
|
}),
|
|
);
|
|
|
|
// Emit WebSocket notification
|
|
const payload: EmailMovePayload = {
|
|
messageId,
|
|
userId,
|
|
fromMailboxId: messageLocation.mailboxId,
|
|
toMailboxId: favoriteMailboxId,
|
|
fromMailboxName: messageLocation.mailboxName,
|
|
toMailboxName: MailboxEnum.FAVORITE,
|
|
timestamp: new Date().toISOString(),
|
|
};
|
|
await this.emailGateway.notifyMessageMoved(payload);
|
|
|
|
this.logger.log(`Message ${messageId} moved to favorite successfully from ${messageLocation.mailboxName}`);
|
|
|
|
return {
|
|
success: true,
|
|
message: EmailMessage.MESSAGE_MOVED_TO_FAVORITE_SUCCESSFULLY,
|
|
result,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(
|
|
`Failed to move message ${messageId} to favorite for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async moveMessageToTrash(userId: string, messageId: number) {
|
|
this.logger.log(`Moving message ${messageId} to trash for user: ${userId}`);
|
|
|
|
try {
|
|
const messageLocation = await this.findMessageMailbox(userId, messageId);
|
|
|
|
if (!messageLocation) throw new BadRequestException(EmailMessage.MESSAGE_NOT_FOUND);
|
|
|
|
const trashMailboxId = await this.mailboxResolverService.getTrashMailboxId(userId);
|
|
|
|
this.logger.log(`Moving message ${messageId} from ${messageLocation.mailboxName} to ${MailboxEnum.TRASH} for user: ${userId}`);
|
|
|
|
const result = await firstValueFrom(
|
|
this.mailServerService.messages.updateMessage(userId, messageLocation.mailboxId, messageId, {
|
|
moveTo: trashMailboxId,
|
|
}),
|
|
);
|
|
|
|
// Emit WebSocket notification
|
|
const payload: EmailMovePayload = {
|
|
messageId,
|
|
userId,
|
|
fromMailboxId: messageLocation.mailboxId,
|
|
toMailboxId: trashMailboxId,
|
|
fromMailboxName: messageLocation.mailboxName,
|
|
toMailboxName: MailboxEnum.TRASH,
|
|
timestamp: new Date().toISOString(),
|
|
};
|
|
await this.emailGateway.notifyMessageMoved(payload);
|
|
|
|
this.logger.log(`Message ${messageId} moved to trash successfully from ${messageLocation.mailboxName}`);
|
|
|
|
return {
|
|
success: true,
|
|
message: EmailMessage.MESSAGE_MOVED_TO_TRASH_SUCCESSFULLY,
|
|
result,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(
|
|
`Failed to move message ${messageId} to trash for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//==============================================
|
|
async moveMessageToInboxFromArchive(userId: string, messageId: number) {
|
|
this.logger.log(`Moving message ${messageId} from archive to inbox for user: ${userId}`);
|
|
|
|
try {
|
|
const inboxMailboxId = await this.mailboxResolverService.getInboxMailboxId(userId);
|
|
const archiveMailboxId = await this.mailboxResolverService.getArchiveMailboxId(userId);
|
|
|
|
const result = await firstValueFrom(
|
|
this.mailServerService.messages.updateMessage(userId, archiveMailboxId, messageId, {
|
|
moveTo: inboxMailboxId,
|
|
}),
|
|
);
|
|
|
|
// Emit WebSocket notification
|
|
const payload: EmailMovePayload = {
|
|
messageId,
|
|
userId,
|
|
fromMailboxId: archiveMailboxId,
|
|
toMailboxId: inboxMailboxId,
|
|
fromMailboxName: "Archive",
|
|
toMailboxName: "Inbox",
|
|
timestamp: new Date().toISOString(),
|
|
};
|
|
await this.emailGateway.notifyMessageMoved(payload);
|
|
|
|
this.logger.log(`Message ${messageId} moved from archive to inbox successfully`);
|
|
|
|
return {
|
|
success: true,
|
|
message: EmailMessage.MESSAGE_MOVED_TO_INBOX_FROM_ARCHIVE_SUCCESSFULLY,
|
|
result,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(
|
|
`Failed to move message ${messageId} from archive to inbox for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//==============================================
|
|
async moveMessageToInboxFromFavorite(userId: string, messageId: number) {
|
|
this.logger.log(`Moving message ${messageId} from favorite to inbox for user: ${userId}`);
|
|
|
|
try {
|
|
const inboxMailboxId = await this.mailboxResolverService.getInboxMailboxId(userId);
|
|
const favoriteMailboxId = await this.mailboxResolverService.getFavoriteMailboxId(userId);
|
|
|
|
const result = await firstValueFrom(
|
|
this.mailServerService.messages.updateMessage(userId, favoriteMailboxId, messageId, {
|
|
moveTo: inboxMailboxId,
|
|
}),
|
|
);
|
|
|
|
// Emit WebSocket notification
|
|
const payload: EmailMovePayload = {
|
|
messageId,
|
|
userId,
|
|
fromMailboxId: favoriteMailboxId,
|
|
toMailboxId: inboxMailboxId,
|
|
fromMailboxName: "Favorite",
|
|
toMailboxName: "Inbox",
|
|
timestamp: new Date().toISOString(),
|
|
};
|
|
await this.emailGateway.notifyMessageMoved(payload);
|
|
|
|
this.logger.log(`Message ${messageId} moved from favorite to inbox successfully`);
|
|
|
|
return {
|
|
success: true,
|
|
message: EmailMessage.MESSAGE_MOVED_TO_INBOX_FROM_FAVORITE_SUCCESSFULLY,
|
|
result,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(
|
|
`Failed to move message ${messageId} from favorite to inbox for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
//==============================================
|
|
async moveMessageToInboxFromTrash(userId: string, messageId: number) {
|
|
this.logger.log(`Moving message ${messageId} from trash to inbox for user: ${userId}`);
|
|
|
|
try {
|
|
const inboxMailboxId = await this.mailboxResolverService.getInboxMailboxId(userId);
|
|
const trashMailboxId = await this.mailboxResolverService.getTrashMailboxId(userId);
|
|
|
|
const result = await firstValueFrom(
|
|
this.mailServerService.messages.updateMessage(userId, trashMailboxId, messageId, {
|
|
moveTo: inboxMailboxId,
|
|
}),
|
|
);
|
|
|
|
// Emit WebSocket notification
|
|
const payload: EmailMovePayload = {
|
|
messageId,
|
|
userId,
|
|
fromMailboxId: trashMailboxId,
|
|
toMailboxId: inboxMailboxId,
|
|
fromMailboxName: "Trash",
|
|
toMailboxName: "Inbox",
|
|
timestamp: new Date().toISOString(),
|
|
};
|
|
await this.emailGateway.notifyMessageMoved(payload);
|
|
|
|
this.logger.log(`Message ${messageId} moved from trash to inbox successfully`);
|
|
|
|
return {
|
|
success: true,
|
|
message: EmailMessage.MESSAGE_MOVED_TO_INBOX_FROM_TRASH_SUCCESSFULLY,
|
|
result,
|
|
};
|
|
} catch (error) {
|
|
this.logger.error(
|
|
`Failed to move message ${messageId} from trash to inbox for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
);
|
|
throw error;
|
|
}
|
|
}
|
|
}
|