@@ -186,18 +186,20 @@ export async function sendMail(mail: IParsedMBox,
186186 return new Promise < string > ( ( resolve , reject ) => {
187187 const transporter = createTransport ( transportOpts ) ;
188188
189+ const rawWithHeader = addHeader (
190+ mail . raw ,
191+ "X-Original-From" ,
192+ mail . from ?? ""
193+ ) ;
194+
189195 // setup email data with unicode symbols
190196 const mailOptions : SendMailOptions = {
191197 envelope : {
192198 cc : mail . cc ? mail . cc . join ( ", " ) : undefined ,
193199 from : mail . from ,
194200 to : mail . to ,
195201 } ,
196- raw : mail . raw ,
197- headers : [ {
198- key : "X-Original-From" ,
199- value : mail . from ?? "" ,
200- } ]
202+ raw : rawWithHeader
201203 } ;
202204
203205 transporter . sendMail ( mailOptions , ( error , info : { messageId : string } )
@@ -210,3 +212,48 @@ export async function sendMail(mail: IParsedMBox,
210212 } ) ;
211213 } ) ;
212214}
215+
216+ function addHeader ( raw : string , name : string , value : string ) : string {
217+ // Detect which newline style the source uses
218+ const CRLF = / \r \n / . test ( raw ) ? "\r\n" : "\n" ;
219+ const headerLine = `${ name } : ${ value } ` ;
220+
221+ // Split into individual lines *without* discarding line–breaks
222+ const lines = raw . split ( / \r ? \n / ) ;
223+
224+ // Locate the canonical “From:” header
225+ let insertPos = - 1 ;
226+
227+ for ( let i = 0 ; i < lines . length ; i ++ ) {
228+ if ( / ^ F r o m : / i. test ( lines [ i ] ) ) {
229+ // Skip any folded continuation lines (start with SP / HT)
230+ insertPos = i + 1 ;
231+ while ( insertPos < lines . length && / ^ [ \t ] / . test ( lines [ insertPos ] ) ) {
232+ insertPos ++ ;
233+ }
234+ break ;
235+ }
236+ // Stop searching once we reach the blank line after headers
237+ if ( lines [ i ] === "" ) break ;
238+ }
239+
240+ // Determine a safe insertion point ---
241+ if ( insertPos === - 1 ) {
242+ // No From: header found – insert just before the header/body separator
243+ insertPos = lines . findIndex ( l => l === "" ) ;
244+ if ( insertPos === - 1 ) {
245+ // Message is malformed (no blank line) – append one
246+ lines . push ( "" ) ;
247+ insertPos = lines . length - 1 ;
248+ }
249+ }
250+
251+ // Insert (or replace if it already exists)
252+ // Remove any existing occurrences of the header we’re about to add
253+ for ( let i = lines . length - 1 ; i >= 0 ; i -- ) {
254+ if ( new RegExp ( `^${ name } :` , "i" ) . test ( lines [ i ] ) ) lines . splice ( i , 1 ) ;
255+ }
256+ lines . splice ( insertPos , 0 , headerLine ) ;
257+
258+ return lines . join ( CRLF ) ;
259+ }
0 commit comments