From 6dd996b30dba23f6771957118a904027cb0e1208 Mon Sep 17 00:00:00 2001 From: mahyargdz Date: Sun, 20 Jul 2025 12:30:33 +0330 Subject: [PATCH] chore: new feature --- src/common/enums/message.enum.ts | 1 + src/modules/auth/auth.controller.ts | 4 +- src/modules/email/services/email.service.ts | 26 +++- .../interfaces/messages-response.interface.ts | 7 + .../interfaces/wildduck-response.interface.ts | 134 ------------------ .../services/wildduck-messages.service.ts | 12 +- 6 files changed, 40 insertions(+), 144 deletions(-) diff --git a/src/common/enums/message.enum.ts b/src/common/enums/message.enum.ts index b2585e7..5a41374 100755 --- a/src/common/enums/message.enum.ts +++ b/src/common/enums/message.enum.ts @@ -221,6 +221,7 @@ export const enum EmailMessage { USER_NOT_FOUND = "کاربر یافت نشد", PRIORITY_MUST_BE_ONE_OF_HIGH_NORMAL_LOW = "اولویت باید یکی از مقادیر high, normal, low باشد", SUBJECT_REQUIRED = "موضوع ایمیل مورد نیاز است", + ALL_MESSAGES_DELETED_SUCCESSFULLY = "همه پیام ها با موفقیت حذف شدند", } export const enum WebSocketMessage { diff --git a/src/modules/auth/auth.controller.ts b/src/modules/auth/auth.controller.ts index e44e286..4ec8567 100644 --- a/src/modules/auth/auth.controller.ts +++ b/src/modules/auth/auth.controller.ts @@ -1,4 +1,4 @@ -import { Body, Controller, HttpCode, HttpStatus, Post } from "@nestjs/common"; +import { Body, Controller, HttpCode, HttpStatus, Patch, Post } from "@nestjs/common"; import { ApiBadRequestResponse, ApiOperation, ApiResponse, ApiTags, ApiUnauthorizedResponse } from "@nestjs/swagger"; import { ChangePasswordDto } from "./DTO/change-password.dto"; @@ -44,7 +44,7 @@ export class AuthController { @AuthGuards() @ApiOperation({ summary: "change the user password" }) @HttpCode(HttpStatus.OK) - @Post("change-password") + @Patch("change-password") changePassword(@UserDec("id") userId: string, @Body() changePasswordDto: ChangePasswordDto) { return this.authService.changePassword(userId, changePasswordDto); } diff --git a/src/modules/email/services/email.service.ts b/src/modules/email/services/email.service.ts index 7f42e24..4aa1b40 100644 --- a/src/modules/email/services/email.service.ts +++ b/src/modules/email/services/email.service.ts @@ -100,7 +100,6 @@ export class EmailService { this.logger.log(`Retrieved status for queue ${queueId}: ${response.status}`); return { - message: EmailMessage.EMAIL_STATUS_RETRIEVED_SUCCESSFULLY, ...response, }; } catch (error) { @@ -136,7 +135,6 @@ export class EmailService { ); return { - message: EmailMessage.MESSAGES_SEARCHED_SUCCESSFULLY, results: response.results, total: response.total, page: response.page, @@ -163,7 +161,6 @@ export class EmailService { this.logger.log(`Found ${response.total} total messages (page ${response.page}) in mailbox ${inboxMailboxId} for user: ${userId}`); return { - message: EmailMessage.MESSAGES_LISTED_SUCCESSFULLY, results: response.results, count: response.total, page: response.page, @@ -214,7 +211,6 @@ export class EmailService { this.logger.log(`Message ${messageId} deleted successfully from ${messageLocation.mailboxName}`); return { - success: true, message: EmailMessage.MESSAGE_DELETED_SUCCESSFULLY, result, }; @@ -224,6 +220,24 @@ export class EmailService { } } + //============================================== + async deleteAllMessages(userId: string, mailboxId: string) { + try { + const result = await firstValueFrom(this.mailServerService.messages.deleteAllFromMailbox(userId, mailboxId)); + + this.logger.log(`All messages deleted successfully from ${mailboxId} for user: ${userId}`); + + return { + message: EmailMessage.ALL_MESSAGES_DELETED_SUCCESSFULLY, + mailboxId, + result, + }; + } catch (error) { + this.logger.error(`Failed to delete all messages for user ${userId}: ${error instanceof Error ? error.message : "Unknown error"}`); + throw error; + } + } + //============================================== async markMessageAsSeen(userId: string, messageId: number) { try { @@ -233,7 +247,7 @@ export class EmailService { this.logger.log(`Marking message ${messageId} as seen in ${messageLocation.mailboxName} mailbox for user: ${userId}`); - const result = await firstValueFrom( + const { updated } = await firstValueFrom( this.mailServerService.messages.updateMessage(userId, messageLocation.mailboxId, messageId, { seen: true }), ); @@ -248,7 +262,7 @@ export class EmailService { return { success: true, message: EmailMessage.MESSAGE_MARKED_AS_SEEN_SUCCESSFULLY, - data: result, + updated, }; } catch (error) { this.logger.error( diff --git a/src/modules/mail-server/interfaces/messages-response.interface.ts b/src/modules/mail-server/interfaces/messages-response.interface.ts index 0004fa3..1759779 100644 --- a/src/modules/mail-server/interfaces/messages-response.interface.ts +++ b/src/modules/mail-server/interfaces/messages-response.interface.ts @@ -126,3 +126,10 @@ export interface MessageFlaggedResponse { nextCursor: string | false; results: MessageDetails[]; } + +export interface MessageUpdateResponse { + success: true; + id: string[]; + mailbox: string; + updated: number; +} diff --git a/src/modules/mail-server/interfaces/wildduck-response.interface.ts b/src/modules/mail-server/interfaces/wildduck-response.interface.ts index 96906dd..bce1fe0 100644 --- a/src/modules/mail-server/interfaces/wildduck-response.interface.ts +++ b/src/modules/mail-server/interfaces/wildduck-response.interface.ts @@ -17,137 +17,3 @@ export interface WildDuckPaginatedResponse extends WildDuckSuccessRespo nextCursor: string | false; results: T[]; } - -// export interface WildDuckUser { -// id: string; -// username: string; -// name?: string; -// address: string; -// tags: string[]; -// forward: string[]; -// targetUrl: string; -// encryptMessages: boolean; -// encryptForwarded: boolean; -// quota: { -// allowed: number; -// used: number; -// }; -// hasPasswordSet: boolean; -// activated: boolean; -// disabled: boolean; -// retention?: number; -// enabled2fa?: string[]; -// pubKey?: string; -// keyInfo?: any; -// limits?: { -// quota: { -// allowed: number; -// used: number; -// }; -// recipients: { -// allowed: number; -// used: number; -// ttl: number | false; -// }; -// forwards: { -// allowed: number; -// used: number; -// ttl: number | false; -// }; -// }; -// } - -// export interface WildDuckMessage { -// id: number; -// mailbox: string; -// thread: string; -// from: { -// address: string; -// name: string; -// }; -// to?: Array<{ -// address: string; -// name: string; -// }>; -// cc?: Array<{ -// address: string; -// name: string; -// }>; -// bcc?: Array<{ -// address: string; -// name: string; -// }>; -// subject: string; -// messageId?: string; -// date: string; -// intro?: string; -// attachments: boolean | WildDuckAttachment[]; -// seen: boolean; -// deleted: boolean; -// flagged: boolean; -// draft: boolean; -// html?: string[]; -// text?: string; -// size?: number; -// } - -// export interface WildDuckAttachment { -// id: string; -// filename: string; -// contentType: string; -// disposition: string; -// transferEncoding: string; -// related: boolean; -// sizeKb: number; -// } - -// export interface WildDuckMailbox { -// id: string; -// name: string; -// path: string; -// specialUse: string | null; -// modifyIndex: number; -// subscribed: boolean; -// total?: number; -// unseen?: number; -// retention?: number; -// } - -// export interface WildDuckAddress { -// id: string; -// address: string; -// main: boolean; -// user?: string; -// created: string; -// } - -// export interface WildDuckFilter { -// id: string; -// name: string; -// query: Array<[string, string]>; -// action: Array<[string]>; -// created: string; -// query_from?: string; -// query_to?: string; -// query_subject?: string; -// query_text?: string; -// query_ha?: boolean; -// query_size?: number; -// action_seen?: boolean; -// action_flag?: boolean; -// action_delete?: boolean; -// action_spam?: boolean; -// action_mailbox?: string; -// action_forward?: string; -// action_targetUrl?: string; -// } - -// export interface WildDuckAuthResult { -// success: boolean; -// id: string; -// username: string; -// scope: string; -// require2fa: string[] | false; -// requirePasswordChange: boolean; -// u2fAuthRequest?: any; -// } diff --git a/src/modules/mail-server/services/wildduck-messages.service.ts b/src/modules/mail-server/services/wildduck-messages.service.ts index 2c28e2d..fe76026 100644 --- a/src/modules/mail-server/services/wildduck-messages.service.ts +++ b/src/modules/mail-server/services/wildduck-messages.service.ts @@ -12,6 +12,7 @@ import { MessageListResponse, MessageSearchResponse, MessageSubmitResponse, + MessageUpdateResponse, MessageUploadResponse, } from "../interfaces/messages-response.interface"; import { WildDuckSuccessResponse } from "../interfaces/wildduck-response.interface"; @@ -35,8 +36,8 @@ export class WildDuckMessagesService extends WildDuckBaseService { /** * Update message details */ - updateMessage(userId: string, mailboxId: string, messageId: number | string, data: UpdateMessageDto): Observable { - return this.put(`/users/${userId}/mailboxes/${mailboxId}/messages/${messageId}`, data); + updateMessage(userId: string, mailboxId: string, messageId: number | string, data: UpdateMessageDto): Observable { + return this.put(`/users/${userId}/mailboxes/${mailboxId}/messages/${messageId}`, data); } /** @@ -46,6 +47,13 @@ export class WildDuckMessagesService extends WildDuckBaseService { return this.delete(`/users/${userId}/mailboxes/${mailboxId}/messages/${messageId}`); } + /** + * Delete all messages from a mailbox + */ + deleteAllFromMailbox(userId: string, mailboxId: string): Observable { + return this.delete(`/users/${userId}/mailboxes/${mailboxId}/messages`); + } + /** * Upload message to mailbox */