diff --git a/app.js b/app.js index 4ad7511..e9474b3 100644 --- a/app.js +++ b/app.js @@ -9,12 +9,10 @@ const Telegraf = require('telegraf'); //Config const config = require('./config.js'); -// Utils -const { path, getText, extractCommand } = require('./util/index.js'); - // Lib const validator = require('./lib/validator.js'); const responder = require('./lib/responseHandler.js'); +const sessionFinder = require('./lib/sessionFinder.js'); const listeners = require('./lib/listeners.js'); const dateOptions = { @@ -28,8 +26,11 @@ const dateOptions = { const bot = new Telegraf(config.botApiKey); const sessions = []; +let identifierState = 0; sessions.history = []; +const getSession = sessionFinder(sessions); + bot.use((ctx, next) => validator(ctx) .then(next) @@ -48,7 +49,9 @@ bot.command('start', const newProc = spawn(defaultShell, { cwd: home }); - sessions.push(newProc); + newProc.identifier = identifierState; + sessions[identifierState] = newProc; + identifierState++; sessions.currentSession = newProc; listeners.add(sessions.currentSession, responder, ctx); return ctx.replyWithHTML(`Welcome to tsh -- Telegram Shell!\n\n` @@ -65,39 +68,32 @@ bot.command('ls', bot.command('attach', ctx => { - const text = getText(ctx); - const sessionIndex = parseInt(extractCommand('attach')(text)); - if(Number.isNaN(sessionIndex) || !sessions[sessionIndex]) + const session = getSession(ctx)('attach'); + if(!session) return responder.fail('Session not found. /ls for list of sessions')(ctx); - sessions.currentSession = sessions[sessionIndex]; + sessions.currentSession = session; listeners.add(sessions.currentSession, responder, ctx); - return responder.success(`Reattached to shell ${sessionIndex}`)(ctx); + return responder.success(`Reattached to shell ${session.identifier}`)(ctx); }); bot.command('detach', ctx => { - const text = getText(ctx); - const sessionIndex = parseInt(extractCommand('detach')(text)); - const currentSession = - text.trim() === '/detach' - ? sessions.currentSession : sessions[sessionIndex]; - if(!currentSession) + const session = getSession(ctx)('detach') || sessions.currentSession; + if(!session) return responder.fail('Session not found. /ls for list of sessions.')(ctx); - listeners.remove(sessions.currentSession); + listeners.remove(session); sessions.currentSession = undefined; - return responder.success(`Detached from shell ${sessionIndex}`)(ctx); + return responder.success(`Detached from shell ${session.identifier}`)(ctx); }); bot.command('kill', ctx => { - const text = getText(ctx); - const sessionIndex = parseInt(extractCommand('kill')(text)); - if(Number.isNaN(sessionIndex) || !sessions[sessionIndex]) + const session = getSession(ctx)('kill') || sessions.currentSession; + if(!session) 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(); + delete sessions[session.identifier]; + if(session === sessions.currentSession) sessions.currentSession = undefined; + session.kill(); ctx.reply('Session killed. /ls for list of sessions.') }) diff --git a/lib/sessionFinder.js b/lib/sessionFinder.js new file mode 100644 index 0000000..a086385 --- /dev/null +++ b/lib/sessionFinder.js @@ -0,0 +1,12 @@ +const { compose, getText, extractCommandText } = require('../util/index.js'); + +const sessionFinder = sessions => ctx => command => { + const identifier = compose( + extractCommandText(command), + getText, + )(ctx); + + return sessions[identifier]; +}; + +module.exports = sessionFinder; \ No newline at end of file diff --git a/util/index.js b/util/index.js index d8466b8..934ce60 100644 --- a/util/index.js +++ b/util/index.js @@ -1,11 +1,11 @@ const path = (path, obj) => path.reduce((result, segment) => result && result[segment], obj); const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args))); const getText = ctx => path(['update', 'message', 'text'], ctx) || ''; -const extractCommand = cmd => text => text.replace(`/${cmd}`, '').trim(); +const extractCommandText = cmd => text => text.replace(`/${cmd}`, '').trim(); module.exports = { path, compose, getText, - extractCommand, + extractCommandText, };