chore: add forwarder address for users
This commit is contained in:
@@ -62,7 +62,7 @@ export const enum AuthMessage {
|
|||||||
TOKEN_EXPIRED_OR_INVALID = "توکن منقضی شده یا نامعتبر است",
|
TOKEN_EXPIRED_OR_INVALID = "توکن منقضی شده یا نامعتبر است",
|
||||||
ACCESS_DENIED = "دسترسی شما محدود شده است",
|
ACCESS_DENIED = "دسترسی شما محدود شده است",
|
||||||
USER_ACCOUNT_INACTIVE = "حساب کاربری شما غیر فعال است",
|
USER_ACCOUNT_INACTIVE = "حساب کاربری شما غیر فعال است",
|
||||||
TOKEN_MISSED_OR_EXPIRED = "TOKEN_MISSED_OR_EXPIRED",
|
TOKEN_MISSED_OR_EXPIRED = "توکن مفقود یا منقضی شده است",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum UserMessage {
|
export const enum UserMessage {
|
||||||
@@ -102,6 +102,10 @@ export const enum UserMessage {
|
|||||||
STATUS_UPDATED = "وضعیت کاربر با موفقیت تغییر کرد",
|
STATUS_UPDATED = "وضعیت کاربر با موفقیت تغییر کرد",
|
||||||
TEMPLATE_UUID = "شناسه قالب باید یک یو یو آی دی باشد",
|
TEMPLATE_UUID = "شناسه قالب باید یک یو یو آی دی باشد",
|
||||||
TEMPLATE_NOT_EMPTY = "شناسه قالب نمیتواند خالی باشد",
|
TEMPLATE_NOT_EMPTY = "شناسه قالب نمیتواند خالی باشد",
|
||||||
|
ALIASES_EMAIL = "آدرس ایمیل الیاس باید معتبر باشد",
|
||||||
|
FORWARDERS_EMAIL_VALID = "آدرس ایمیل فوروارد باید معتبر باشد",
|
||||||
|
FORWARDERS_ARRAY = "آدرس های فوروارد باید یک آرایه باشد",
|
||||||
|
FORWARDERS_STRING = "آدرس های فوروارد باید یک رشته باشد",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum CommonMessage {
|
export const enum CommonMessage {
|
||||||
@@ -425,7 +429,7 @@ export const enum DomainMessage {
|
|||||||
|
|
||||||
export const enum MailServerMessage {
|
export const enum MailServerMessage {
|
||||||
FAILED_TO_CREATE_ACCOUNT = "خطا در ایجاد ایمیل",
|
FAILED_TO_CREATE_ACCOUNT = "خطا در ایجاد ایمیل",
|
||||||
FAILED_TO_CREATE_DKIM_KEY = "FAILED_TO_CREATE_DKIM_KEY",
|
FAILED_TO_CREATE_DKIM_KEY = "خطا در ایجاد کلید DKIM",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum DnsRecordMessage {
|
export const enum DnsRecordMessage {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
|
import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
|
||||||
import { Transform } from "class-transformer";
|
import { Transform } from "class-transformer";
|
||||||
import { IsArray, IsNotEmpty, IsNumber, IsOptional, IsString, IsUUID, Matches, MinLength } from "class-validator";
|
import { IsArray, IsEmail, IsNotEmpty, IsNumber, IsOptional, IsString, IsUUID, Matches, MinLength } from "class-validator";
|
||||||
|
|
||||||
import { UserMessage } from "../../../common/enums/message.enum";
|
import { UserMessage } from "../../../common/enums/message.enum";
|
||||||
|
|
||||||
@@ -53,4 +53,14 @@ export class CreateEmailUserDto {
|
|||||||
@IsUUID("7", { message: UserMessage.TEMPLATE_UUID })
|
@IsUUID("7", { message: UserMessage.TEMPLATE_UUID })
|
||||||
@ApiPropertyOptional({ description: "Template ID", example: "713e5000-0000-0000-0000-000000000000" })
|
@ApiPropertyOptional({ description: "Template ID", example: "713e5000-0000-0000-0000-000000000000" })
|
||||||
templateId?: string;
|
templateId?: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsEmail({}, { each: true, message: UserMessage.FORWARDERS_EMAIL_VALID })
|
||||||
|
@IsArray({ message: UserMessage.FORWARDERS_ARRAY })
|
||||||
|
@IsString({ each: true, message: UserMessage.FORWARDERS_STRING })
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: "Array of email addresses to forward all messages to",
|
||||||
|
example: ["forward1@example.com", "forward2@example.com"],
|
||||||
|
})
|
||||||
|
forwarders?: string[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ApiPropertyOptional } from "@nestjs/swagger";
|
import { ApiPropertyOptional } from "@nestjs/swagger";
|
||||||
import { Transform } from "class-transformer";
|
import { Transform } from "class-transformer";
|
||||||
import { IsArray, IsNotEmpty, IsNumber, IsOptional, IsString, IsUUID, Matches, MinLength } from "class-validator";
|
import { IsArray, IsEmail, IsNotEmpty, IsNumber, IsOptional, IsString, IsUUID, Matches, MinLength } from "class-validator";
|
||||||
|
|
||||||
import { UserMessage } from "../../../common/enums/message.enum";
|
import { UserMessage } from "../../../common/enums/message.enum";
|
||||||
|
|
||||||
@@ -44,4 +44,14 @@ export class UpdateEmailUserDto {
|
|||||||
@IsUUID("7", { message: UserMessage.TEMPLATE_UUID })
|
@IsUUID("7", { message: UserMessage.TEMPLATE_UUID })
|
||||||
@ApiPropertyOptional({ description: "Template ID", example: "713e5000-0000-0000-0000-000000000000" })
|
@ApiPropertyOptional({ description: "Template ID", example: "713e5000-0000-0000-0000-000000000000" })
|
||||||
templateId?: string;
|
templateId?: string;
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsEmail({}, { each: true, message: UserMessage.FORWARDERS_EMAIL_VALID })
|
||||||
|
@IsArray({ message: UserMessage.FORWARDERS_ARRAY })
|
||||||
|
@IsString({ each: true, message: UserMessage.FORWARDERS_STRING })
|
||||||
|
@ApiPropertyOptional({
|
||||||
|
description: "Array of email addresses to forward all messages to",
|
||||||
|
example: ["forward1@example.com", "forward2@example.com"],
|
||||||
|
})
|
||||||
|
forwarders?: string[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ export class User extends BaseEntity {
|
|||||||
@Property({ type: "timestamptz", nullable: true })
|
@Property({ type: "timestamptz", nullable: true })
|
||||||
lastQuotaSync?: Date;
|
lastQuotaSync?: Date;
|
||||||
|
|
||||||
|
@Property({ type: "json", nullable: true })
|
||||||
|
forwarders?: string[];
|
||||||
|
|
||||||
@Property({ default: true, nullable: false })
|
@Property({ default: true, nullable: false })
|
||||||
isActive: boolean & Opt;
|
isActive: boolean & Opt;
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ export class UsersService {
|
|||||||
remainingInGB: Math.round(Number(user.emailQuota - user.emailQuotaUsed) / (1024 * 1024 * 1024)),
|
remainingInGB: Math.round(Number(user.emailQuota - user.emailQuotaUsed) / (1024 * 1024 * 1024)),
|
||||||
usagePercentage: Math.round((Number(user.emailQuotaUsed) / Number(user.emailQuota)) * 100),
|
usagePercentage: Math.round((Number(user.emailQuotaUsed) / Number(user.emailQuota)) * 100),
|
||||||
},
|
},
|
||||||
|
forwarders: user.forwarders || [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/*******************************/
|
/*******************************/
|
||||||
@@ -83,7 +84,7 @@ export class UsersService {
|
|||||||
|
|
||||||
/*******************************/
|
/*******************************/
|
||||||
async createEmailUser(createEmailUserDto: CreateEmailUserDto, businessId: string) {
|
async createEmailUser(createEmailUserDto: CreateEmailUserDto, businessId: string) {
|
||||||
const { username, password, domainId, displayName, quota, aliases, title, templateId } = createEmailUserDto;
|
const { username, password, domainId, displayName, quota, aliases, title, templateId, forwarders } = createEmailUserDto;
|
||||||
|
|
||||||
const business = await this.em.findOne(Business, { id: businessId });
|
const business = await this.em.findOne(Business, { id: businessId });
|
||||||
if (!business) throw new BadRequestException(BusinessMessage.NOT_FOUND);
|
if (!business) throw new BadRequestException(BusinessMessage.NOT_FOUND);
|
||||||
@@ -122,6 +123,7 @@ export class UsersService {
|
|||||||
address: emailAddress,
|
address: emailAddress,
|
||||||
name: displayName || username,
|
name: displayName || username,
|
||||||
quota: userQuota,
|
quota: userQuota,
|
||||||
|
targets: forwarders || [],
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -140,6 +142,7 @@ export class UsersService {
|
|||||||
business,
|
business,
|
||||||
domain,
|
domain,
|
||||||
role: userRole,
|
role: userRole,
|
||||||
|
forwarders: forwarders || [],
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update business quota after successful user creation
|
// Update business quota after successful user creation
|
||||||
@@ -189,6 +192,7 @@ export class UsersService {
|
|||||||
emailQuota: user.emailQuota!,
|
emailQuota: user.emailQuota!,
|
||||||
emailEnabled: user.emailEnabled,
|
emailEnabled: user.emailEnabled,
|
||||||
domain: domain.name,
|
domain: domain.name,
|
||||||
|
forwarders: user.forwarders || [],
|
||||||
createdAt: user.createdAt,
|
createdAt: user.createdAt,
|
||||||
isActive: user.isActive,
|
isActive: user.isActive,
|
||||||
},
|
},
|
||||||
@@ -245,7 +249,7 @@ export class UsersService {
|
|||||||
/*******************************/
|
/*******************************/
|
||||||
|
|
||||||
async updateEmailUser(userId: string, businessId: string, updateEmailUserDto: UpdateEmailUserDto) {
|
async updateEmailUser(userId: string, businessId: string, updateEmailUserDto: UpdateEmailUserDto) {
|
||||||
const { password, displayName, quota, aliases, title, templateId } = updateEmailUserDto;
|
const { password, displayName, quota, aliases, title, templateId, forwarders } = updateEmailUserDto;
|
||||||
|
|
||||||
const user = await this.userRepository.findOne(
|
const user = await this.userRepository.findOne(
|
||||||
{
|
{
|
||||||
@@ -283,6 +287,11 @@ export class UsersService {
|
|||||||
|
|
||||||
if (quota) updateData.quota = quota;
|
if (quota) updateData.quota = quota;
|
||||||
|
|
||||||
|
if (forwarders !== undefined) {
|
||||||
|
updateData.forward = forwarders;
|
||||||
|
user.forwarders = forwarders;
|
||||||
|
}
|
||||||
|
|
||||||
if (Object.keys(updateData).length > 0) {
|
if (Object.keys(updateData).length > 0) {
|
||||||
await firstValueFrom(this.mailServerService.users.updateUser(user.wildduckUserId!, updateData));
|
await firstValueFrom(this.mailServerService.users.updateUser(user.wildduckUserId!, updateData));
|
||||||
}
|
}
|
||||||
@@ -347,6 +356,7 @@ export class UsersService {
|
|||||||
title: user.title,
|
title: user.title,
|
||||||
emailQuota: user.emailQuota!,
|
emailQuota: user.emailQuota!,
|
||||||
emailEnabled: user.emailEnabled,
|
emailEnabled: user.emailEnabled,
|
||||||
|
forwarders: user.forwarders || [],
|
||||||
isActive: user.isActive,
|
isActive: user.isActive,
|
||||||
updatedAt: user.updatedAt,
|
updatedAt: user.updatedAt,
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user