11import type { NotificationAgentEmail } from '@server/lib/settings' ;
22import { getSettings } from '@server/lib/settings' ;
33import Email from 'email-templates' ;
4+ import net from 'node:net' ;
45import nodemailer from 'nodemailer' ;
6+ import type SMTPTransport from 'nodemailer/lib/smtp-transport' ;
57import { URL } from 'url' ;
68import { openpgpEncrypt } from './openpgpEncrypt' ;
79
10+ const getSocket : SMTPTransport . Options [ 'getSocket' ] = ( options , callback ) => {
11+ const socket = net . connect ( {
12+ host : options . host ?? 'localhost' ,
13+ port : options . port ?? 587 ,
14+ localAddress : options . localAddress ,
15+ } ) ;
16+ const cleanup = ( ) => {
17+ socket . setTimeout ( 0 ) ;
18+ socket . removeListener ( 'error' , onError ) ;
19+ socket . removeListener ( 'connect' , onConnect ) ;
20+ socket . removeListener ( 'timeout' , onTimeout ) ;
21+ } ;
22+ const onError = ( error : Error ) => {
23+ cleanup ( ) ;
24+ callback ( error , undefined ) ;
25+ } ;
26+ const onConnect = ( ) => {
27+ cleanup ( ) ;
28+ callback ( null , { connection : socket } ) ;
29+ } ;
30+ const onTimeout = ( ) => {
31+ cleanup ( ) ;
32+ socket . destroy ( ) ;
33+ callback ( new Error ( 'SMTP connection timed out' ) , undefined ) ;
34+ } ;
35+
36+ socket . once ( 'error' , onError ) ;
37+ socket . once ( 'connect' , onConnect ) ;
38+ socket . once ( 'timeout' , onTimeout ) ;
39+ socket . setTimeout ( 10000 ) ;
40+ } ;
41+
842class PreparedEmail extends Email {
943 public constructor ( settings : NotificationAgentEmail , pgpKey ?: string ) {
1044 const { applicationUrl } = getSettings ( ) . main ;
@@ -28,6 +62,7 @@ class PreparedEmail extends Email {
2862 pass : settings . options . authPass ,
2963 }
3064 : undefined ,
65+ getSocket : net . isIP ( settings . options . smtpHost ) ? undefined : getSocket ,
3166 } ) ;
3267
3368 if ( pgpKey ) {
0 commit comments