@@ -7,6 +7,21 @@ const smtpMessage = new SMTP.SmtpMessage({
77 secure : false
88} )
99
10+ Deno . test ( 'SmtpMessage accepts safe custom headers' , ( ) => {
11+ const formattedMessage = smtpMessage . formatMessage ( {
12+ from : 'sender@example.com' ,
13+ to : 'receiver@example.com' ,
14+ subject : 'Header' ,
15+ text : 'body' ,
16+ headers : {
17+ 'X-Security-Test' : 'safe-value' ,
18+ 'X-Trace_Id' : 'trace-123'
19+ }
20+ } )
21+ assertMatch ( formattedMessage , / X - S e c u r i t y - T e s t : s a f e - v a l u e / )
22+ assertMatch ( formattedMessage , / X - T r a c e _ I d : t r a c e - 1 2 3 / )
23+ } )
24+
1025Deno . test ( 'SmtpMessage formats multipart html and text' , ( ) => {
1126 const formattedMessage = smtpMessage . formatMessage ( {
1227 from : 'sender@example.com' ,
@@ -32,6 +47,108 @@ Deno.test('SmtpMessage formats plain text message', () => {
3247 assertMatch ( formattedMessage , / h e l l o / )
3348} )
3449
50+ Deno . test ( 'SmtpMessage rejects custom header names with invalid characters' , ( ) => {
51+ assertThrows (
52+ ( ) =>
53+ smtpMessage . formatMessage ( {
54+ from : 'sender@example.com' ,
55+ to : 'receiver@example.com' ,
56+ subject : 'Header' ,
57+ text : 'body' ,
58+ headers : {
59+ 'Bad Header' : 'value'
60+ }
61+ } ) ,
62+ Error ,
63+ 'contains invalid characters'
64+ )
65+ } )
66+
67+ Deno . test ( 'SmtpMessage rejects custom header names with line breaks' , ( ) => {
68+ assertThrows (
69+ ( ) =>
70+ smtpMessage . formatMessage ( {
71+ from : 'sender@example.com' ,
72+ to : 'receiver@example.com' ,
73+ subject : 'Header' ,
74+ text : 'body' ,
75+ headers : {
76+ 'X-Test\r\nBcc' : 'value'
77+ }
78+ } ) ,
79+ Error ,
80+ 'contains invalid characters'
81+ )
82+ } )
83+
84+ Deno . test ( 'SmtpMessage rejects custom header values with line breaks' , ( ) => {
85+ assertThrows (
86+ ( ) =>
87+ smtpMessage . formatMessage ( {
88+ from : 'sender@example.com' ,
89+ to : 'receiver@example.com' ,
90+ subject : 'Header' ,
91+ text : 'body' ,
92+ headers : {
93+ 'X-Test' : 'ok\r\nBcc: victim@example.com'
94+ }
95+ } ) ,
96+ Error ,
97+ 'value contains line break characters'
98+ )
99+ } )
100+
101+ Deno . test ( 'SmtpMessage rejects empty custom header names' , ( ) => {
102+ assertThrows (
103+ ( ) =>
104+ smtpMessage . formatMessage ( {
105+ from : 'sender@example.com' ,
106+ to : 'receiver@example.com' ,
107+ subject : 'Header' ,
108+ text : 'body' ,
109+ headers : {
110+ ' ' : 'value'
111+ }
112+ } ) ,
113+ Error ,
114+ 'name cannot be empty'
115+ )
116+ } )
117+
118+ Deno . test ( 'SmtpMessage rejects reserved custom header names' , ( ) => {
119+ assertThrows (
120+ ( ) =>
121+ smtpMessage . formatMessage ( {
122+ from : 'sender@example.com' ,
123+ to : 'receiver@example.com' ,
124+ subject : 'Header' ,
125+ text : 'body' ,
126+ headers : {
127+ Subject : 'Injected subject'
128+ }
129+ } ) ,
130+ Error ,
131+ 'reserved and cannot be overridden'
132+ )
133+ } )
134+
135+ Deno . test ( 'SmtpMessage rejects reserved headers case-insensitively' , ( ) => {
136+ assertThrows (
137+ ( ) =>
138+ smtpMessage . formatMessage ( {
139+ from : 'sender@example.com' ,
140+ to : 'receiver@example.com' ,
141+ subject : 'Header' ,
142+ text : 'body' ,
143+ headers : {
144+ 'mImE-vErSiOn' : '2.0'
145+ }
146+ } ) ,
147+ Error ,
148+ 'reserved and cannot be overridden'
149+ )
150+ } )
151+
35152Deno . test ( 'SmtpMessage throws when embedded cid is invalid' , ( ) => {
36153 assertThrows (
37154 ( ) =>
0 commit comments