vpn.email
Version:
vpn.email client
296 lines (233 loc) • 10.7 kB
text/typescript
import * as api_util from './util';
import * as testImapAccount from './testImapAccount'
import * as smtp from './smtpClass';
import * as express from 'express';
import isOnline = require ('is-online');
import * as Async from 'async'
export const sockRoute = ( io: SocketIO.Server ) => {
let Session: ISockSession = null;
let imapConnect: testImapAccount.connectImap = null;
let echoTimeOut = null;
let windowsSocketClient: SocketIO.Socket = null;
const checkOnline = ( CallBack: ICallBack ) => {
isOnline (( err, online) => {
if ( err )
return CallBack ( err )
online
? CallBack ()
: CallBack ( new Error ( 'offline' ))
})
}
api_util.defineSession ( null, ( err, data: ISockSession ) => {
if ( err )
return console.log ( 'api_util.defineSession ERROR: ', err )
Session = data
})
io.on ( 'connection', socket => {
const First_Socket_On = ( password, CallBack ) => {
api_util.defineSession ( password, ( err, data: ISockSession ) => {
if ( err )
return console.log ( 'api_util.defineSession ERROR: ', err )
if ( data.keyPair.keyPasswordOK ) {
if ( ! Session || !Session.keyPair.keyPasswordOK )
Session = data
needConnect ()
}
CallBack ( null, data )
})
}
socket.on ( 'first', First_Socket_On )
socket.on ( 'deletePassword', CallBack => {
if ( ! Session.keyPair.keyPasswordOK ) {
if ( Session.vpnServerConnectData && Session.vpnServerConnectData.active )
return CallBack ( 'UnAllowAccess' )
}
api_util.deleteSystemPassword ( Session, err => {
if ( err )
return CallBack ( err )
io.emit ( 'deletePassword' )
})
});
// generate key pair
socket.on ( 'NewKeyPair', ( data: INewKeyPair , CallBack: ICallBack ) => {
if ( Session.keyPair && Session.keyPair.keyPasswordOK )
return CallBack ( 'UnAllowAccess' )
socket.once ( 'cancelCreateKeyPair', CallBack => {
console.log ('cancelCreateKeyPair come')
if ( ! Session.newKeyPairProcessRunning || ! Session.newKeyProcessPid )
return CallBack ( 'UnAllowAccess' )
Session.keyPair.keyPasswordOK = false;
Session.newKeyProcessPid.stop ();
Session.newKeyProcessPid = null;
io.emit ( 'cancelCreateKeyPair' )
})
const keyPair = Session.keyPair;
keyPair.email = data.email;
keyPair.userName = data.nikeName;
keyPair.keyPasswordOK = true;
keyPair.keyPassword = Session.keyPairPassword = data.password;
keyPair.keyBitLength = parseInt ( data.keyLength );
CallBack ( null, Session )
Session.newKeyPairProcessRunning = true;
Async.series ([
next => {
const command = `views/api/NewKeyPair`
Session.newKeyProcessPid = new api_util.runCallBack ( command, Session.keyPair, null, next )
},
next => api_util.checkInitFile ( Session, next ),
next => api_util.saveConfig ( Session, next )
], err => {
if ( err )
return console.log ( 'aWait_NewKeyPair had error:', err )
socket.join ('/root')
Session.newKeyPairProcessRunning = false
Session.newKeyProcessPid = null
io.emit ( 'NewKeyPair-CallBack', Session.keyPair )
})
io.emit ( 'NewKeyPairRunning' )
})
socket.on ( 'testImapConnect', ( n: IinputData, CallBack ) => {
if ( n.systemPassword !== Session.keyPairPassword )
return CallBack ( 'no_login' )
Async.series ([
next => checkOnline ( next ),
next => testImapAccount.testImapCommand ( n.imapUserName, n.imapUserPassword, n.imapServer, n.imapSsl, parseInt ( n.imapPortNumber ), next ),
next => {
socket.emit ( 'testImapOK' )
n.imapTested = true;
smtp.testSMTP ( n.smtpServer, n.smtpUserName, n.smtpUserPassword, parseInt( n.smtpPortNumber ), n.smtpSsl, next )
}, next => {
socket.emit ( 'testSmtpOK')
n.smtpTested = true;
Session.imapArray = n;
sendConnectrequestEmailToVenEmail ( next )
}, next => api_util.saveConfig ( Session, next )
], ( err, data ) => {
if ( err ) {
return CallBack ( err.message )
}
socket.emit ( 'sentMailOK')
needConnect()
})
})
// delete imap config
socket.on( 'deleteImapArray', ( n: IinputData, CallBack ) => {
if ( ! Session.keyPair.keyPasswordOK || ! Session.imapArray || !n || Session.imapArray.account != n.account )
return CallBack ( 'no_login' )
if ( Session.imapConnected && imapConnect ) {
imapConnect.destroy ()
Session.imapConnected = false
imapConnect = null
}
Session.imapArray = null;
Session.vpnServerConnectData = null;
return api_util.saveConfig ( Session, () => {
CallBack ()
})
})
socket.on ( 'sendActivePassword', ( text: string, CallBack ) => {
sendActiveCommand ( text, CallBack )
})
socket.on ( 'windowsSocketReady', () => {
windowsSocketClient = socket;
console.log ('windowsSocketClient ready!')
})
})
// send mail to vpnEmail via smtp
const sendConnectrequestEmailToVenEmail = ( CallBack: ICallBack ) => {
const timeRound = 1000 * 60 // one min
const oldSentTime = Session.sentEmail
const nowTime = new Date().getTime();
if ( nowTime - oldSentTime < timeRound )
return CallBack();
console.log ( 'needConnect: try send email to request vpn.email connect' )
Session.sentEmail = nowTime;
Session.imapArray.machineID = api_util.machineuuid ()
Session.imapArray.serverMailBoxName = api_util.machineuuid ()
smtp.tryConnectEmail ( Session )
CallBack ()
}
// callback listen event
const newEmailCallBack = datas => {
const vpnData = Session.vpnServerConnectData;
const command: IClientEmailCommand = datas;
if ( command.command ) {
if ( /^echo$/.test ( command.command )) {
if ( echoTimeOut ) {
clearTimeout ( echoTimeOut )
echoTimeOut = null;
} else {
sendEcho()
}
}
}
Session.vpnEmailServerKeepConnected = true;
console.log ( 'get new email & do /root emit: ', vpnData )
io.emit ( 'vpnEmailOnline', true )
io.to( '/root').emit ( 'email', vpnData )
api_util.saveConfig ( Session, ()=> {})
}
// connect
const needConnect = () => {
if ( ! Session.keyPair.keyPasswordOK || ! Session.imapArray || ! Session.imapArray.imapTested || ! Session.imapArray.smtpTested ) {
console.log ( 'needConnect: imapArray error!' )
return;
}
if ( ! Session.imapConnected ) {
console.log ( 'needConnect: try connect to IMAP server!' )
imapConnect = new testImapAccount.connectImap ( Session, newEmailCallBack );
}
if ( ! Session.vpnEmailServerKeepConnected ) {
return trySendEchoCommand ()
}
api_util.saveConfig ( Session, () => {})
io.emit ( 'vpnEmailOnline', true )
}
const sendCommandToDcoker = ( command: IClientEmailCommand, CallBack ) => {
imapConnect.saveToVpnEmail ( Session.vpnServerConnectData.serverMailFolder, command, CallBack )
}
const sendActiveCommand = ( text: string, CallBack ) => {
needConnect ()
if ( ! Session.vpnEmailServerKeepConnected ) {
return setTimeout (() => {
sendActiveCommand ( text, CallBack )
}, 1000 * 10 )
}
Async.waterfall ([
next => api_util.Decryption ( text, Session.keyPairPassword, Session.keyPair.privateKeyUTF8, Session.vpnEmailPublicKey, next ),
( data, next ) => {
const command :IClientEmailCommand = {
command: 'activePassword',
data: data.data,
account: Session.imapArray.account
}
sendCommandToDcoker ( command, next )
}
], ( err, data ) => {
if ( err )
CallBack ( err )
CallBack ()
})
}
const trySendEchoCommand = ( ) => {
if ( ! Session.dockerPublicKey || ! Session.dockerPublicKey.length || ! Session.keyPair || ! Session.keyPair.keyPasswordOK ||
! Session.vpnServerConnectData || Session.vpnServerConnectData.accountType === 'free' ) {
return sendConnectrequestEmailToVenEmail(() => {})
}
sendEcho()
}
const sendEcho = () => {
const command :IClientEmailCommand = {
command: 'echo',
data: null,
account: Session.imapArray.account
}
sendCommandToDcoker ( command, ()=>{})
echoTimeOut = setTimeout (() => {
Session.vpnEmailServerKeepConnected = false;
io.emit ( 'vpnEmailOnline', false )
sendConnectrequestEmailToVenEmail(() => {})
}, 1000 * 10 )
}
//
}