Skip to content

Commit a0a71a8

Browse files
committed
FIX submit error msg
1 parent 00bc9c6 commit a0a71a8

8 files changed

+696
-521
lines changed

Makefile

+10-6
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,16 @@ generate:
3838
@docker exec -it $(APPNAME) yarn generate
3939

4040
dbs:
41-
@docker volume create $(APPNAME)-redis
42-
@docker run -d --rm \
43-
--name $(APPNAME)-redis \
44-
--network dev \
45-
-p 6379:6379 \
46-
redis
41+
@docker run --rm -d \
42+
-p 1080:1080 \
43+
-p 1025:1025 \
44+
maildev/maildev
45+
# @docker volume create $(APPNAME)-redis
46+
# @docker run -d --rm \
47+
# --name $(APPNAME)-redis \
48+
# --network dev \
49+
# -p 6379:6379 \
50+
# redis
4751

4852
stop:
4953
@docker stop $(APPNAME) || true

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"axios": "^1.5.0",
5858
"class-transformer": "^0.5.1",
5959
"class-validator": "^0.14.0",
60+
"default-gateway": "^6.0.3",
6061
"form-data": "^4.0.0",
6162
"handlebars": "^4.7.8",
6263
"imapflow": "^1.0.136",
@@ -81,6 +82,7 @@
8182
"@nestjs/testing": "^10.1.3",
8283
"@swc/cli": "^0.1.62",
8384
"@swc/core": "^1.3.93",
85+
"@types/default-gateway": "^3.0.1",
8486
"@types/express": "^4.17.17",
8587
"@types/form-data": "^2.5.0",
8688
"@types/imapflow": "^1.0.13",
@@ -89,7 +91,7 @@
8991
"@types/lru-cache": "^7.10.10",
9092
"@types/mailparser": "^3.4.0",
9193
"@types/multer": "^1.4.8",
92-
"@types/node": "^18.0.0",
94+
"@types/node": "^18.18.0",
9395
"@types/nodemailer": "^6.4.11",
9496
"@types/passport-jwt": "^3.0.9",
9597
"@typescript-eslint/eslint-plugin": "^6.4.0",

src/accounts/_dto/account-submit.dto.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ export class AccountSubmitDto {
7474
[name: string]: any
7575
}
7676

77-
@IsString()
7877
@IsOptional()
78+
@IsObject()
7979
@ApiProperty()
8080
public context?: {
8181
[name: string]: any
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import { ApiProperty } from '@nestjs/swagger'
2+
import { IsArray, IsNumber, IsObject, IsOptional, IsString } from 'class-validator'
3+
4+
export class AccountSubmitedDto {
5+
@IsOptional()
6+
@IsArray()
7+
@IsString({ each: true })
8+
@ApiProperty()
9+
public accepted?: string[]
10+
11+
@IsOptional()
12+
@IsArray()
13+
@IsString({ each: true })
14+
@ApiProperty()
15+
public rejected?: string[]
16+
17+
@IsOptional()
18+
@IsArray()
19+
@IsString({ each: true })
20+
@ApiProperty()
21+
public ehlo?: string[]
22+
23+
@IsOptional()
24+
@IsNumber()
25+
@ApiProperty()
26+
public envelopeTime?: number
27+
28+
@IsOptional()
29+
@IsNumber()
30+
@ApiProperty()
31+
public messageTime?: number
32+
33+
@IsOptional()
34+
@IsNumber()
35+
@ApiProperty()
36+
public messageSize?: number
37+
38+
@IsOptional()
39+
@IsString()
40+
@ApiProperty()
41+
public response?: string
42+
43+
@IsOptional()
44+
@IsObject()
45+
@ApiProperty()
46+
public envelope?: {
47+
[name: string]: any
48+
}
49+
50+
@IsOptional()
51+
@IsString()
52+
@ApiProperty()
53+
public messageId?: string
54+
}

src/accounts/accounts.controller.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ import {
55
Get,
66
HttpStatus,
77
Logger,
8-
Param, ParseFilePipe,
8+
Param,
9+
ParseFilePipe,
910
Patch,
1011
Post,
1112
Res,
12-
Sse, UploadedFiles,
13+
Sse,
14+
UploadedFiles,
1315
UseInterceptors,
1416
} from '@nestjs/common'
1517
import { ModuleRef } from '@nestjs/core'
@@ -28,7 +30,7 @@ import { ApiReadResponseDecorator } from '~/_common/decorators/api-read-response
2830
import { ApiUpdateDecorator } from '~/_common/decorators/api-update.decorator'
2931
import { ApiDeletedResponseDecorator } from '~/_common/decorators/api-deleted-response.decorator'
3032
import { ApiTags } from '@nestjs/swagger'
31-
import { FileInterceptor } from '@nestjs/platform-express'
33+
import { FilesInterceptor } from '@nestjs/platform-express'
3234
import { AccountSubmitDto } from '~/accounts/_dto/account-submit.dto'
3335

3436
@ApiTags('accounts')
@@ -112,7 +114,7 @@ export class AccountsController extends AbstractController {
112114
}
113115

114116
@Post(':account([\\w-.]+)/submit')
115-
@UseInterceptors(FileInterceptor('file'))
117+
@UseInterceptors(FilesInterceptor('files'))
116118
@UseRoles({
117119
resource: ScopesEnum.Accounts,
118120
action: ActionEnum.Create,
@@ -121,9 +123,7 @@ export class AccountsController extends AbstractController {
121123
@Res() res: Response,
122124
@Param('account') id: string,
123125
@Body() body: AccountSubmitDto,
124-
@UploadedFiles(
125-
new ParseFilePipe({ fileIsRequired: false }),
126-
) files?: Array<Express.Multer.File>,
126+
@UploadedFiles(new ParseFilePipe({ fileIsRequired: false })) files?: Array<Express.Multer.File>,
127127
): Promise<Response> {
128128
const data = await this.service.submit(id, body, files)
129129
return res.status(HttpStatus.OK).json({

src/accounts/accounts.service.ts

+44-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
import { Injectable, Logger, NotFoundException } from '@nestjs/common'
1+
import {
2+
BadGatewayException,
3+
BadRequestException,
4+
ConflictException,
5+
Injectable,
6+
InternalServerErrorException,
7+
Logger,
8+
NotFoundException,
9+
ServiceUnavailableException,
10+
} from '@nestjs/common'
211
import { ModuleRef } from '@nestjs/core'
312
import { ImapFlow } from 'imapflow'
413
import { LRUCache } from 'lru-cache'
@@ -8,9 +17,11 @@ import { AccountsFileV1, AccountsMetadataV1, readAccountsFile, writeAccountsFile
817
import { PartialType } from '@nestjs/swagger'
918
import { MailerService } from '@nestjs-modules/mailer'
1019
import { AccountSubmitDto } from '~/accounts/_dto/account-submit.dto'
20+
import { AccountSubmitedDto } from '~/accounts/_dto/account-submited.dto'
21+
import os from 'os'
22+
import gateway from 'default-gateway'
1123

12-
class InternalAccountMetadataV1 extends PartialType(AccountsMetadataV1) {
13-
}
24+
class InternalAccountMetadataV1 extends PartialType(AccountsMetadataV1) {}
1425

1526
@Injectable()
1627
export class AccountsService extends AbstractService {
@@ -77,15 +88,38 @@ export class AccountsService extends AbstractService {
7788
return account
7889
}
7990

80-
public async submit(id: string, body: AccountSubmitDto, files?: Express.Multer.File[]) {
91+
public async submit(id: string, body: AccountSubmitDto, files?: Express.Multer.File[]): Promise<AccountSubmitedDto> {
8192
const accounts = await readAccountsFile(this.cache)
8293
const account = accounts.accounts.find((a) => a.id === id)
8394
if (!account) throw new NotFoundException(`Account not found: ${id}`)
84-
return this.mailerService.sendMail({
85-
...body,
86-
attachments: files,
87-
from: account.smtp.from || account.smtp.auth.user,
88-
transporterName: id,
89-
})
95+
if (!body.template && (!body.text || !body.html)) {
96+
throw new BadRequestException(`Template, text or html is required !`)
97+
}
98+
try {
99+
return await this.mailerService.sendMail({
100+
...body,
101+
attachments: files.map((file) => ({
102+
filename: file.originalname,
103+
content: file.buffer,
104+
})),
105+
from:
106+
account.smtp.from ||
107+
account.smtp?.auth?.user ||
108+
(await (async () => {
109+
return `${os.hostname()}@${(await gateway.v4()).gateway}`
110+
})()),
111+
transporterName: id,
112+
})
113+
} catch (e) {
114+
if (!e.code) throw new BadRequestException(`Failed to post message with <${e.message}>`, e.stack)
115+
switch (e.code) {
116+
case 'EDNS':
117+
throw new BadGatewayException(`[${e.code}] SMTP server connexion failed with <${e.message}>`, e.stack)
118+
case 'ESOCKET':
119+
throw new ServiceUnavailableException(`[${e.code}] SMTP server connexion failed with <${e.message}>`, e.stack)
120+
default:
121+
throw new InternalServerErrorException(`[${e.code}] SMTP connection attempt internal server error with <${e.message}>`, e.stack)
122+
}
123+
}
90124
}
91125
}

src/config.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export default async (): Promise<ConfigInstance> => {
7474
from: '"nest-modules" <[email protected]>',
7575
},
7676
template: {
77-
dir: __dirname + '/../../templates',
77+
dir: __dirname + '/../templates',
7878
adapter: new HandlebarsAdapter(),
7979
options: {
8080
strict: true,

0 commit comments

Comments
 (0)