diff --git a/src/modules/domains/services/domain-automation.service.ts b/src/modules/domains/services/domain-automation.service.ts index 4252704..52d28fc 100644 --- a/src/modules/domains/services/domain-automation.service.ts +++ b/src/modules/domains/services/domain-automation.service.ts @@ -3,6 +3,7 @@ import { Injectable, Logger } from "@nestjs/common"; import { firstValueFrom } from "rxjs"; import { MailServerService } from "../../mail-server/services/mail-server.service"; +import { MailboxEnum } from "../../mailbox/enums/mailbox.enum"; import { Role } from "../../users/entities/role.entity"; import { User } from "../../users/entities/user.entity"; import { RoleEnum } from "../../users/enums/role.enum"; @@ -52,6 +53,33 @@ export class DomainAutomationService { } } + /** + * Create default mailboxes for a user (Archive and Favorite) + */ + async createDefaultMailboxes(wildduckUserId: string): Promise { + try { + const mailboxesToCreate = [ + { path: MailboxEnum.ARCHIVE, name: "Archive" }, + { path: MailboxEnum.FAVORITE, name: "Favorite" }, + ]; + + for (const mailbox of mailboxesToCreate) { + try { + await firstValueFrom( + this.mailServerService.mailboxes.createMailbox(wildduckUserId, { + path: mailbox.path, + }), + ); + this.logger.log(`Created ${mailbox.name} mailbox for user: ${wildduckUserId}`); + } catch (error) { + this.logger.warn(`Failed to create ${mailbox.name} mailbox for user ${wildduckUserId}: ${(error as Error).message}`); + } + } + } catch (error) { + this.logger.error(`Failed to create default mailboxes for user ${wildduckUserId}: ${(error as Error).message}`); + } + } + /** * Create info@domain.com address when domain is verified */ @@ -124,6 +152,9 @@ export class DomainAutomationService { await this.em.persistAndFlush(user); + // Create default mailboxes (Archive and Favorite) + await this.createDefaultMailboxes(mailServerUser.id); + this.logger.log(`Successfully created info address: ${infoEmail} (username: ${uniqueUsername}) for business ${domain.business.name}`); this.logger.log(`Info account credentials - Email: ${infoEmail}, Username: ${uniqueUsername}, Password: [GENERATED]`); } catch (error) { diff --git a/src/modules/email/services/mailbox-resolver.service.ts b/src/modules/email/services/mailbox-resolver.service.ts index 3b91161..3d28862 100644 --- a/src/modules/email/services/mailbox-resolver.service.ts +++ b/src/modules/email/services/mailbox-resolver.service.ts @@ -1,8 +1,8 @@ import { Injectable, Logger, NotFoundException } from "@nestjs/common"; import { firstValueFrom } from "rxjs"; -import { MailboxEnum } from "../../mail-server/enums/mailbox.enum"; import { MailServerService } from "../../mail-server/services/mail-server.service"; +import { MailboxEnum } from "../../mailbox/enums/mailbox.enum"; export interface UserMailboxIds { inbox: string; diff --git a/src/modules/mail-server/DTO/mailbox.dto.ts b/src/modules/mail-server/DTO/mailbox.dto.ts index a86b819..702ce1b 100644 --- a/src/modules/mail-server/DTO/mailbox.dto.ts +++ b/src/modules/mail-server/DTO/mailbox.dto.ts @@ -1,21 +1,29 @@ import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; -import { IsBoolean, IsNumber, IsOptional, IsString } from "class-validator"; +import { IsBoolean, IsNotEmpty, IsNumber, IsOptional, IsString } from "class-validator"; export class CreateMailboxDto { - @ApiProperty({ - description: "Mailbox path with slashes as folder separators", - example: "Important/Work", - }) + @IsNotEmpty() @IsString() + @ApiProperty({ description: "Mailbox path with slashes as folder separators", example: "Important/Work" }) path: string; - @ApiPropertyOptional({ - description: "Retention time in milliseconds for messages in this mailbox", - example: 2592000000, - }) @IsOptional() + @IsNotEmpty() @IsNumber() + @ApiPropertyOptional({ description: "Retention time in milliseconds for messages in this mailbox", example: 2592000000 }) retention?: number; + + @IsOptional() + @IsNotEmpty() + @IsBoolean() + @ApiPropertyOptional({ description: "Encrypt messages in this mailbox", example: false }) + encryptMessages?: boolean; + + @IsNotEmpty() + @IsOptional() + @IsBoolean() + @ApiPropertyOptional({ description: "Is the folder hidden or not. Hidden folders can not be opened in IMAP.", example: false }) + hidden?: boolean; } export class UpdateMailboxDto { diff --git a/src/modules/mail-server/enums/mailbox.enum.ts b/src/modules/mail-server/enums/mailbox.enum.ts deleted file mode 100644 index ff98cb1..0000000 --- a/src/modules/mail-server/enums/mailbox.enum.ts +++ /dev/null @@ -1,9 +0,0 @@ -export enum MailboxEnum { - INBOX = "INBOX", - DRAFTS = "Drafts", - ARCHIVE = "Archive", - Junk = "Junk", - SENT = "Sent Mail", - TRASH = "Trash", - SPAM = "spam", -} diff --git a/src/modules/mailbox/enums/mailbox.enum.ts b/src/modules/mailbox/enums/mailbox.enum.ts new file mode 100644 index 0000000..366597c --- /dev/null +++ b/src/modules/mailbox/enums/mailbox.enum.ts @@ -0,0 +1,11 @@ +export enum MailboxEnum { + INBOX = "INBOX", + DRAFTS = "Drafts", + ARCHIVE = "Archive", //should created when user created + FAVORITE = "FAVORITE", //should created when user created + Junk = "Junk", + SENT = "Sent Mail", + TRASH = "Trash", +} + +// SPAM = "spam", //should created when user created diff --git a/src/modules/users/services/users.service.ts b/src/modules/users/services/users.service.ts index ffd1e2f..4156afd 100644 --- a/src/modules/users/services/users.service.ts +++ b/src/modules/users/services/users.service.ts @@ -13,6 +13,7 @@ import { import { BusinessMessage, DomainMessage, MailServerMessage, RoleMessage, UserMessage } from "../../../common/enums/message.enum"; import { Business } from "../../businesses/entities/business.entity"; import { DomainStatus } from "../../domains/enums/domain-status.enum"; +import { DomainAutomationService } from "../../domains/services/domain-automation.service"; import { DomainsService } from "../../domains/services/domains.service"; import { MailServerService } from "../../mail-server/services/mail-server.service"; import { PasswordService } from "../../utils/services/password.service"; @@ -33,6 +34,7 @@ export class UsersService { private readonly passwordService: PasswordService, private readonly mailServerService: MailServerService, private readonly domainsService: DomainsService, + private readonly domainAutomationService: DomainAutomationService, ) {} async getUserEmailIdFromId(userId: string) { @@ -137,6 +139,8 @@ export class UsersService { this.logger.log(`Email user created: ${emailAddress} for business ${businessId}`); + await this.domainAutomationService.createDefaultMailboxes(mailServerUser.id); + return { user: { id: user.id,