const { Client } = require( 'ssh2' );
+const createError = require('http-errors');
-const parseVpnStatus = (output) => {
+/**
+ *
+ * @param {string} output
+ * @returns {any[]|*[]}
+ */
+const parseVpnStatus = ( output ) => {
// Split once and reuse
- const lines = output.split('\n').map(line => line.trim()).filter(Boolean);
+ const lines = output.split( '\n' ).map( line => line.trim() ).filter( Boolean );
// Find indices using a single pass
let sIndex = -1, mIndex = -1, eIndex = -1;
- lines.forEach((line, i) => {
- if (sIndex === -1 && line.startsWith('Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since')) sIndex = i;
- else if (mIndex === -1 && line.startsWith('ROUTING TABLE')) mIndex = i;
- else if (eIndex === -1 && line.startsWith('GLOBAL STATS')) eIndex = i;
- });
+ lines.forEach( ( line, i ) => {
+ if (sIndex === -1 && line.startsWith( 'Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since' )) sIndex = i;
+ else if (mIndex === -1 && line.startsWith( 'ROUTING TABLE' )) mIndex = i;
+ else if (eIndex === -1 && line.startsWith( 'GLOBAL STATS' )) eIndex = i;
+ } );
// Early return if indices not found
if (sIndex === -1 || mIndex === -1 || eIndex === -1) return [];
// Parse clients and routing table together in a single pass
const clientsMap = new Map();
for (let i = sIndex + 1; i < mIndex; i++) {
- const parts = lines[i].split(',');
- clientsMap.set(parts[0], {
- name: parts[0],
- ip: parts[1],
- connectedSince: parts[4],
- virtual_ip: ''
- });
+ const parts = lines[i].split( ',' );
+ clientsMap.set( parts[0], {
+ name:parts[0],
+ ip:parts[1],
+ connectedSince:parts[4],
+ virtual_ip:''
+ } );
}
// Assign virtual IPs
for (let i = mIndex + 2; i < eIndex; i++) {
- const parts = lines[i].split(',');
- const client = clientsMap.get(parts[1]);
+ const parts = lines[i].split( ',' );
+ const client = clientsMap.get( parts[1] );
if (client) client.virtual_ip = parts[0];
}
- return Array.from(clientsMap.values());
+ return Array.from( clientsMap.values() );
};
module.exports = {
} ).on( 'error', ( err ) => {
res.status( 500 ).json( { error:`SSH connection failed: ${ err.message }` } );
} ).connect( sshConfig );
- }, revokeClient:( req, res, next ) => {
+ },
+ revokeClient:( req, res, next ) => {
const { clientName } = req.body;
if (!clientName) {
return res.status( 400 ).json( { error:'Client name required' } );
} ).on( 'error', ( err ) => {
res.status( 500 ).json( { error:`SSH connection failed: ${ err.message }` } );
} ).connect( sshConfig );
- }, getClients:async ( req, res, next ) => {
+ },
+ getClients:async ( req, res, next ) => {
const conn = new Client();
conn.on( 'ready', () => {
- const command = `cat /var/log/openvpn/openvpn-status.log`;
+ const error = new createError( 500, `SSH connection failed:` );
+ next( error );
+ /*const command = `cat /var/log/openvpn/openvpn-status.log`;
conn.exec( command, ( err, stream ) => {
if (err) {
conn.end();
stream.on( 'close', ( code ) => {
conn.end();
if (code === 0) {
-
- const clients = parseVpnStatus(output);
- res.json({clients});
- /*const lines = output.split( '\n' );
- const sIndex = lines.findIndex( line => line.startsWith( 'Common Name,Real Address,Bytes Received,Bytes Sent,Connected Since' ) );
- const mIndex = lines.findIndex( line => line.startsWith( 'ROUTING TABLE' ) );
- const eIndex = lines.findIndex( line => line.startsWith( 'GLOBAL STATS' ) );
- const C = [...lines].slice(sIndex +1, mIndex).filter( line => line.trim() );
- const R = [...lines].slice(mIndex +2, eIndex).filter( line => line.trim() );
- const clients = C.map( line => {
- const parts = line.split( ',' );
- const vLine = R.find( l => l.includes( parts[0] ) && l !== line );
- return { name:parts[0], ip:parts[1], virtual_ip:vLine.split( ',' )[0], connectedSince:parts[4] };
- } );
- res.json( { clients } );*/
+ const clients = parseVpnStatus( output );
+ res.json( { clients } );
} else {
- res.status( 500 ).json( { error:`Command failed: ${ output }` } );
+ const error = new createError( 500, `Command failed: ${ output }` );
+ next( error );
}
} );
- } );
+ } );*/
} ).on( 'error', ( err ) => {
- res.status( 500 ).json( { error:`SSH connection failed: ${ err.message }` } );
+ const error = new createError( 500, `SSH connection failed: ${ err.message }` );
+ next( error );
+ // res.status( 500 ).json( { error:`SSH connection failed: ${ err.message }` } );
} ).connect( sshConfig );
}
};
\ No newline at end of file