UNPKG

vpn.email

Version:
291 lines (194 loc) 7.97 kB
import * as IMAP from 'imap'; import * as event from 'events'; import * as mailparser from 'mailparser'; import * as async from 'async'; import * as smtpClass from './smtpClass'; interface nodeImap { imap_account: string; imap_password: string; } const Mailparser = mailparser.MailParser; /** * @param imap {IMAP.Connection} imap Connection. * @param mailBox {string} mail box name that want open * @cb {function} call back function */ const openInbox = ( imap, mailBox: string, cb: ( err?: Error, box? ) => void ) => { imap.openBox ( mailBox, false, err => { if ( err ) { imap.addBox ( mailBox, err1 => { if ( err1 ) return cb ( err1 ); return openInbox ( imap, mailBox, cb ); }) } cb (); }) } /** * @param imap {IMAP.Connection} * @param clearBox {boolean} * @param events {event.EventEmitter} * Decryption (msg.attachments[0].content.toString('utf8') , key.password, key.private, service.public_key, ( err, data ) => { * data.signatures[0].valid */ const scanEmail = ( imap, clearBox = false, events: event.EventEmitter, CallBack: ICallBack = null ) => { async.waterfall ([ next => { imap.search ( [ 'UNSEEN' ], next ); }, ( results, next ) => { if ( !results || !results.length ) return next (); const fetch = imap.fetch ( results, { markSeen : true, bodies: [ '' ]}); let ret = []; fetch.on ( 'message', msg => { let mp = new Mailparser (); let buffer = ''; mp.once ( 'end', msg => { events.emit ( 'email', msg ); }) msg.on ( 'body', data => { data.on ('data', ( chunk ) => { buffer += chunk.toString () }) }) msg.once ( 'end', () => { mp.write ( buffer ); mp.end () }) }) fetch.once ( 'error', err => { next ( err ) }) fetch.once ( 'end', () => { if ( clearBox ) return imap.addFlags ( results, [ '\\Deleted' ], next ); next ( null ); }) }], err => { if ( err ) return events.emit ( 'error', err ); if ( CallBack && typeof CallBack === 'function' ) CallBack () }) } /*** * @param user {string} imap user name. * @param password {string} imap user password * @param mailBoxName {string} open mail box name * @param forever {boolean} if forever true * * event emit *** * @param error {Error} when err * @param email {mailparser.ParsedMail []} new email data * * event listen *** * @param save */ export default class imapConnect { private _imapConnects: IMAP.Connection; static type = 'class imapConnect '; public _events = new event.EventEmitter (); private imapEnd = false; private haveError = false; public openFolder = false; private CallBack = null; constructor ( private user: string, private password: string, private host: string, private port: number, private tls: boolean, private newMailCheck: boolean, private mailBoxName, private clearBox:boolean, private forever: boolean, private isTest: boolean, private debug: boolean) { const ImapConnectConfig = { user: user, host: host, password: password, port: port, tls: tls, debug: debug ? ( err ) => { console.log ( new Date(), ' = ', err )} : null, keepalive: true } this.imapEnd = !forever this._imapConnects = new IMAP ( ImapConnectConfig ) if ( ! isTest ) this.connect () } public connect ( CallBack : ICallBack = null ) { this.CallBack = CallBack; this._imapConnects.once ( 'ready', () => { if ( this.mailBoxName ) { const loop = () => { if ( this._imapConnects.state !== 'authenticated' ) { return setTimeout (() => { loop () }, 1000 ); } openInbox ( this._imapConnects, this.mailBoxName, ( err, box ) => { if ( err ) { console.log ( err.message ); } console.log ( 'watch mail box ready:', this.mailBoxName ) this.openFolder = true; this._events.emit ( 'imapReady' ) if ( this.imapEnd ) { this._imapConnects.destroy (); } if ( CallBack && typeof CallBack === 'function' ) { CallBack ( null, this ) } }) } loop(); } }) this._imapConnects.on ( 'mail', () => { if ( this.newMailCheck ) { scanEmail ( this._imapConnects, this.clearBox, this._events ); } }) this._events.once ( 'end', () => { //console.log ('this._imapConnects.once end') this._imapConnects.destroy (); this._events.emit ( 'end' ); }) this._imapConnects.once ( 'error', ( err ) => { console.log ('this._imapConnects.once error') if ( this.forever ) { this._imapConnects.connect (); } this._events.emit ( 'error', err ); }) this._imapConnects.connect (); } public save ( boxName:string, email: mailcomposer, CallBack: ICallBack ) { if ( this._imapConnects.state !== 'authenticated' ) { return setTimeout (() => { this.save ( boxName, email, CallBack ) }, 2000 ); } console.log ( 'save message to folder', boxName ) async.waterfall ([ next => { email.build ( next ); }, ( data, next ) => { this._imapConnects.append ( data, { mailbox: boxName }, next ); } ], ( err, data ) => { if ( err ) { return this._imapConnects.addBox ( boxName, err => { if ( err ) { return CallBack ( err ); } this.save ( boxName, email, CallBack ); }) } if ( !this.forever ) { this._imapConnects.end (); } CallBack () }) } public distroy () { this._imapConnects.removeAllListeners() this._imapConnects.delBox ( this.mailBoxName, () => { this._imapConnects.destroy () }) } }