| 
						
						
						
					 | 
				
				 | 
				
					@ -1,14 +1,92 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const { spawn } = require('child_process'); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const { EOL } = require('os'); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const Telegraf = require('telegraf'); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const config = require('./config') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const { path } = require('./util/index.js'); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const config = require('./config.js'); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const validator = require('./lib/validator'); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const responder = require('./lib/responseHandler.js'); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const dateOptions = { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						weekday: 'long', | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						year: 'numeric', | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						month: 'long', | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						day: 'numeric', | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						hour: 'numeric', | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						minute: 'numeric', | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const bot = new Telegraf(config.botApiKey); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const sessions = []; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					sessions.history = []; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					bot.use((ctx, next) =>  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						validator(ctx) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							.then(next) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							.catch(responder.fail( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								`Username Not authenticated!` | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							))); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					bot.command('start', | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						ctx => { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							ctx.replyWithHTML('Welcome to tsh -- <code>Telegram Shell!</code>'); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							const newProc = spawn('bash', { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								cwd: '/home' | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							}); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							newProc.stdout.setEncoding('utf8'); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							sessions.push(newProc); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							sessions.currentSession = newProc; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						}); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					bot.command('ls', | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						ctx => ctx.reply( | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							sessions.reduce((acc, _, index) => | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
								acc ? `${acc}\n${index}` : `${index}`, '') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							|| `No sessions found. Start one with /start.` | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					bot.command('attach', | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						ctx => { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							const text = path(['update', 'message', 'text'], ctx); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							const sessionIndex = parseInt(text.replace('/attach ', '').trim()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(Number.isNaN(sessionIndex) || !sessions[sessionIndex]) return responder.fail('Session not found. /ls for list of sessions')(ctx); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							sessions.currentSession = sessions[sessionIndex]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							return responder.success(`Reattached to shell ${sessionIndex}`)(ctx); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						}); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					const bot = new Telegraf(config.apiKey) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					bot.command('detach', | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						ctx => { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							const text = path(['update', 'message', 'text'], ctx); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							const sessionIndex = parseInt(text.replace('/detach ', '').trim()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							const currentSession = text.trim() === '/detach' ? sessions.currentSession : sessions[sessionIndex]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(!currentSession) return responder.fail('Session not found. /ls for list of sessions.')(ctx); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							sessions.currentSession = undefined; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							return responder.success(`Detached from shell ${sessionIndex}`)(ctx); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						}); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					bot.command('start', ctx => { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						return ctx.reply('Bot succesfully started!'); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					bot.command('kill', | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						ctx => { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							const text = path(['update', 'message', 'text'], ctx); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							const sessionIndex = parseInt(text.replace('/kill ', '').trim()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(Number.isNaN(sessionIndex) || !sessions[sessionIndex]) return responder.fail('Session not found. /ls for list of sessions.')(ctx); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							const disconnect = sessions[sessionIndex]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							delete sessions[sessionIndex]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							if(disconnect === sessions.currentSession) sessions.currentSession = undefined; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							disconnect.kill(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
							ctx.reply('Session killed. /ls for list of sessions.') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						}) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					bot.hears('hi', ctx => { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						return ctx.reply('Hey!, How are you?'); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					bot.use(ctx => { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						if(!sessions.currentSession) return responder.fail('No active session. Start one with /start or view list of sessions by sending /ls.')(ctx); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						const cmd = ctx.update.message.text; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						const history = `${new Date().toLocaleDateString('en-IN', dateOptions)}: ${cmd}`; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						sessions.history.push(history); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						console.log(history); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						sessions.currentSession.stdin.write(cmd + EOL); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						sessions.currentSession.stdout.on('data', d => responder.success(d)(ctx)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
						sessions.currentSession.stdout.on('error', e => responder.success(e)(ctx)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					bot.startPolling(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					console.log(`Polling for updates.`); | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
					 | 
				
				 | 
				
					
  |