chore: new feature

This commit is contained in:
mahyargdz
2025-07-20 12:30:33 +03:30
parent 495646e770
commit 6dd996b30d
6 changed files with 40 additions and 144 deletions
+1
View File
@@ -221,6 +221,7 @@ export const enum EmailMessage {
USER_NOT_FOUND = "کاربر یافت نشد", USER_NOT_FOUND = "کاربر یافت نشد",
PRIORITY_MUST_BE_ONE_OF_HIGH_NORMAL_LOW = "اولویت باید یکی از مقادیر high, normal, low باشد", PRIORITY_MUST_BE_ONE_OF_HIGH_NORMAL_LOW = "اولویت باید یکی از مقادیر high, normal, low باشد",
SUBJECT_REQUIRED = "موضوع ایمیل مورد نیاز است", SUBJECT_REQUIRED = "موضوع ایمیل مورد نیاز است",
ALL_MESSAGES_DELETED_SUCCESSFULLY = "همه پیام ها با موفقیت حذف شدند",
} }
export const enum WebSocketMessage { export const enum WebSocketMessage {
+2 -2
View File
@@ -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 { ApiBadRequestResponse, ApiOperation, ApiResponse, ApiTags, ApiUnauthorizedResponse } from "@nestjs/swagger";
import { ChangePasswordDto } from "./DTO/change-password.dto"; import { ChangePasswordDto } from "./DTO/change-password.dto";
@@ -44,7 +44,7 @@ export class AuthController {
@AuthGuards() @AuthGuards()
@ApiOperation({ summary: "change the user password" }) @ApiOperation({ summary: "change the user password" })
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@Post("change-password") @Patch("change-password")
changePassword(@UserDec("id") userId: string, @Body() changePasswordDto: ChangePasswordDto) { changePassword(@UserDec("id") userId: string, @Body() changePasswordDto: ChangePasswordDto) {
return this.authService.changePassword(userId, changePasswordDto); return this.authService.changePassword(userId, changePasswordDto);
} }
+20 -6
View File
@@ -100,7 +100,6 @@ export class EmailService {
this.logger.log(`Retrieved status for queue ${queueId}: ${response.status}`); this.logger.log(`Retrieved status for queue ${queueId}: ${response.status}`);
return { return {
message: EmailMessage.EMAIL_STATUS_RETRIEVED_SUCCESSFULLY,
...response, ...response,
}; };
} catch (error) { } catch (error) {
@@ -136,7 +135,6 @@ export class EmailService {
); );
return { return {
message: EmailMessage.MESSAGES_SEARCHED_SUCCESSFULLY,
results: response.results, results: response.results,
total: response.total, total: response.total,
page: response.page, 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}`); this.logger.log(`Found ${response.total} total messages (page ${response.page}) in mailbox ${inboxMailboxId} for user: ${userId}`);
return { return {
message: EmailMessage.MESSAGES_LISTED_SUCCESSFULLY,
results: response.results, results: response.results,
count: response.total, count: response.total,
page: response.page, page: response.page,
@@ -214,7 +211,6 @@ export class EmailService {
this.logger.log(`Message ${messageId} deleted successfully from ${messageLocation.mailboxName}`); this.logger.log(`Message ${messageId} deleted successfully from ${messageLocation.mailboxName}`);
return { return {
success: true,
message: EmailMessage.MESSAGE_DELETED_SUCCESSFULLY, message: EmailMessage.MESSAGE_DELETED_SUCCESSFULLY,
result, 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) { async markMessageAsSeen(userId: string, messageId: number) {
try { try {
@@ -233,7 +247,7 @@ export class EmailService {
this.logger.log(`Marking message ${messageId} as seen in ${messageLocation.mailboxName} mailbox for user: ${userId}`); 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 }), this.mailServerService.messages.updateMessage(userId, messageLocation.mailboxId, messageId, { seen: true }),
); );
@@ -248,7 +262,7 @@ export class EmailService {
return { return {
success: true, success: true,
message: EmailMessage.MESSAGE_MARKED_AS_SEEN_SUCCESSFULLY, message: EmailMessage.MESSAGE_MARKED_AS_SEEN_SUCCESSFULLY,
data: result, updated,
}; };
} catch (error) { } catch (error) {
this.logger.error( this.logger.error(
@@ -126,3 +126,10 @@ export interface MessageFlaggedResponse {
nextCursor: string | false; nextCursor: string | false;
results: MessageDetails[]; results: MessageDetails[];
} }
export interface MessageUpdateResponse {
success: true;
id: string[];
mailbox: string;
updated: number;
}
@@ -17,137 +17,3 @@ export interface WildDuckPaginatedResponse<T = any> extends WildDuckSuccessRespo
nextCursor: string | false; nextCursor: string | false;
results: T[]; 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;
// }
@@ -12,6 +12,7 @@ import {
MessageListResponse, MessageListResponse,
MessageSearchResponse, MessageSearchResponse,
MessageSubmitResponse, MessageSubmitResponse,
MessageUpdateResponse,
MessageUploadResponse, MessageUploadResponse,
} from "../interfaces/messages-response.interface"; } from "../interfaces/messages-response.interface";
import { WildDuckSuccessResponse } from "../interfaces/wildduck-response.interface"; import { WildDuckSuccessResponse } from "../interfaces/wildduck-response.interface";
@@ -35,8 +36,8 @@ export class WildDuckMessagesService extends WildDuckBaseService {
/** /**
* Update message details * Update message details
*/ */
updateMessage(userId: string, mailboxId: string, messageId: number | string, data: UpdateMessageDto): Observable<WildDuckSuccessResponse> { updateMessage(userId: string, mailboxId: string, messageId: number | string, data: UpdateMessageDto): Observable<MessageUpdateResponse> {
return this.put<WildDuckSuccessResponse>(`/users/${userId}/mailboxes/${mailboxId}/messages/${messageId}`, data); return this.put<MessageUpdateResponse>(`/users/${userId}/mailboxes/${mailboxId}/messages/${messageId}`, data);
} }
/** /**
@@ -46,6 +47,13 @@ export class WildDuckMessagesService extends WildDuckBaseService {
return this.delete<WildDuckSuccessResponse>(`/users/${userId}/mailboxes/${mailboxId}/messages/${messageId}`); return this.delete<WildDuckSuccessResponse>(`/users/${userId}/mailboxes/${mailboxId}/messages/${messageId}`);
} }
/**
* Delete all messages from a mailbox
*/
deleteAllFromMailbox(userId: string, mailboxId: string): Observable<MessageDeleteAllResponse> {
return this.delete<MessageDeleteAllResponse>(`/users/${userId}/mailboxes/${mailboxId}/messages`);
}
/** /**
* Upload message to mailbox * Upload message to mailbox
*/ */