const qr = require('qr-image') const { setupSession, deleteSession, reloadSession, validateSession, flushSessions, sessions } = require('../sessions') const { sendErrorResponse, waitForNestedObject } = require('../utils') const { logger } = require('../logger') /** * Starts a session for the given session ID. * * @function * @async * @param {Object} req - The HTTP request object. * @param {Object} res - The HTTP response object. * @param {string} req.params.sessionId - The session ID to start. * @returns {Promise} * @throws {Error} If there was an error starting the session. */ const startSession = async (req, res) => { // #swagger.summary = 'Start new session' // #swagger.description = 'Starts a session for the given session ID.' const sessionId = req.params.sessionId try { const setupSessionReturn = await setupSession(sessionId) if (!setupSessionReturn.success) { /* #swagger.responses[422] = { description: "Unprocessable Entity.", content: { "application/json": { schema: { "$ref": "#/definitions/ErrorResponse" } } } } */ sendErrorResponse(res, 422, setupSessionReturn.message) return } /* #swagger.responses[200] = { description: "Status of the initiated session.", content: { "application/json": { schema: { "$ref": "#/definitions/StartSessionResponse" } } } } */ // wait until the client is created await waitForNestedObject(setupSessionReturn.client, 'pupPage') res.json({ success: true, message: setupSessionReturn.message }) } catch (error) { logger.error({ sessionId, err: error }, 'Failed to start session') sendErrorResponse(res, 500, error.message) } } /** * Status of the session with the given session ID. * * @function * @async * @param {Object} req - The HTTP request object. * @param {Object} res - The HTTP response object. * @param {string} req.params.sessionId - The session ID to start. * @returns {Promise} * @throws {Error} If there was an error getting status of the session. */ const statusSession = async (req, res) => { // #swagger.summary = 'Get session status' // #swagger.description = 'Status of the session with the given session ID.' const sessionId = req.params.sessionId try { const sessionData = await validateSession(sessionId) /* #swagger.responses[200] = { description: "Status of the session.", content: { "application/json": { schema: { "$ref": "#/definitions/StatusSessionResponse" } } } } */ res.json(sessionData) } catch (error) { logger.error({ sessionId, err: error }, 'Failed to get session status') sendErrorResponse(res, 500, error.message) } } /** * QR code of the session with the given session ID. * * @function * @async * @param {Object} req - The HTTP request object. * @param {Object} res - The HTTP response object. * @param {string} req.params.sessionId - The session ID to start. * @returns {Promise} * @throws {Error} If there was an error getting status of the session. */ const sessionQrCode = async (req, res) => { // #swagger.summary = 'Get session QR code' // #swagger.description = 'QR code of the session with the given session ID.' const sessionId = req.params.sessionId try { const session = sessions.get(sessionId) if (!session) { return res.json({ success: false, message: 'session_not_found' }) } if (session.qr) { return res.json({ success: true, qr: session.qr }) } return res.json({ success: false, message: 'qr code not ready or already scanned' }) } catch (error) { logger.error({ sessionId, err: error }, 'Failed to get session qr code') sendErrorResponse(res, 500, error.message) } } /** * QR code as image of the session with the given session ID. * * @function * @async * @param {Object} req - The HTTP request object. * @param {Object} res - The HTTP response object. * @param {string} req.params.sessionId - The session ID to start. * @returns {Promise} * @throws {Error} If there was an error getting status of the session. */ const sessionQrCodeImage = async (req, res) => { // #swagger.summary = 'Get session QR code as image' // #swagger.description = 'QR code as image of the session with the given session ID.' const sessionId = req.params.sessionId try { const session = sessions.get(sessionId) if (!session) { return res.json({ success: false, message: 'session_not_found' }) } if (session.qr) { const qrImage = qr.image(session.qr) /* #swagger.responses[200] = { description: "QR image.", content: { "image/png": {} } } */ res.writeHead(200, { 'Content-Type': 'image/png' }) return qrImage.pipe(res) } return res.json({ success: false, message: 'qr code not ready or already scanned' }) } catch (error) { logger.error({ sessionId, err: error }, 'Failed to get session qr code image') sendErrorResponse(res, 500, error.message) } } /** * Restarts the session with the given session ID. * * @function * @async * @param {Object} req - The HTTP request object. * @param {Object} res - The HTTP response object. * @param {string} req.params.sessionId - The session ID to terminate. * @returns {Promise} * @throws {Error} If there was an error terminating the session. */ const restartSession = async (req, res) => { // #swagger.summary = 'Restart session' // #swagger.description = 'Restarts the session with the given session ID.' const sessionId = req.params.sessionId try { const validation = await validateSession(sessionId) if (validation.message === 'session_not_found') { return res.json(validation) } await reloadSession(sessionId) /* #swagger.responses[200] = { description: "Sessions restarted.", content: { "application/json": { schema: { "$ref": "#/definitions/RestartSessionResponse" } } } } */ res.json({ success: true, message: 'Restarted successfully' }) } catch (error) { logger.error({ sessionId, err: error }, 'Failed to restart session') sendErrorResponse(res, 500, error.message) } } /** * Terminates the session with the given session ID. * * @function * @async * @param {Object} req - The HTTP request object. * @param {Object} res - The HTTP response object. * @param {string} req.params.sessionId - The session ID to terminate. * @returns {Promise} * @throws {Error} If there was an error terminating the session. */ const terminateSession = async (req, res) => { // #swagger.summary = 'Terminate session' // #swagger.description = 'Terminates the session with the given session ID.' const sessionId = req.params.sessionId try { const validation = await validateSession(sessionId) if (validation.message === 'session_not_found') { return res.json(validation) } await deleteSession(sessionId, validation) /* #swagger.responses[200] = { description: "Sessions terminated.", content: { "application/json": { schema: { "$ref": "#/definitions/TerminateSessionResponse" } } } } */ res.json({ success: true, message: 'Logged out successfully' }) } catch (error) { logger.error({ sessionId, err: error }, 'Failed to terminate session') sendErrorResponse(res, 500, error.message) } } /** * Terminates all inactive sessions. * * @function * @async * @param {Object} req - The HTTP request object. * @param {Object} res - The HTTP response object. * @returns {Promise} * @throws {Error} If there was an error terminating the sessions. */ const terminateInactiveSessions = async (req, res) => { // #swagger.summary = 'Terminate inactive sessions' // #swagger.description = 'Terminates all inactive sessions.' try { await flushSessions(true) /* #swagger.responses[200] = { description: "Sessions terminated.", content: { "application/json": { schema: { "$ref": "#/definitions/TerminateSessionsResponse" } } } } */ res.json({ success: true, message: 'Flush completed successfully' }) } catch (error) { logger.error(error, 'Failed to terminate inactive sessions') sendErrorResponse(res, 500, error.message) } } /** * Terminates all sessions. * * @function * @async * @param {Object} req - The HTTP request object. * @param {Object} res - The HTTP response object. * @returns {Promise} * @throws {Error} If there was an error terminating the sessions. */ const terminateAllSessions = async (req, res) => { // #swagger.summary = 'Terminate all sessions' // #swagger.description = 'Terminates all sessions.' try { await flushSessions(false) /* #swagger.responses[200] = { description: "Sessions terminated.", content: { "application/json": { schema: { "$ref": "#/definitions/TerminateSessionsResponse" } } } } */ res.json({ success: true, message: 'Flush completed successfully' }) } catch (error) { logger.error(error, 'Failed to terminate all sessions') sendErrorResponse(res, 500, error.message) } } module.exports = { startSession, statusSession, sessionQrCode, sessionQrCodeImage, restartSession, terminateSession, terminateInactiveSessions, terminateAllSessions }