diff --git a/app.js b/app.js index 8cfc4a4..cabc197 100644 --- a/app.js +++ b/app.js @@ -1,30 +1,12 @@ -// LinuxServer Guacamole Client -const path = require('path'); -const express = require('express'); const http = require('http'); -const cloudcmd = require('cloudcmd'); -const { pamAuthenticate } = require('node-linux-pam'); const GuacamoleLite = require('guacamole-lite'); -const { clientOptions, connectionOptions } = require('./options'); -const { - encrypt, - trimTrailingSlash, - deepMerge, - loadConfig, -} = require('./utils'); - -// Application Variables -const baseurl = process.env.SUBFOLDER || '/'; -const CUSTOM_PORT = process.env.CUSTOM_PORT || 3000; - -const app = express(); -app.set('view engine', 'ejs'); -app.set('x-powered-by', false); +const { app } = require('./lib/server'); +const { clientOptions } = require('./lib/options'); const server = http.Server(app); -const baserouter = express.Router(); -const credentials = loadConfig(__dirname); + +const CUSTOM_PORT = process.env.CUSTOM_PORT || 3000; // Spinup the Guac websocket proxy on port 3000 if guacd is running // eslint-disable-next-line no-unused-vars @@ -36,69 +18,7 @@ const guacServer = new GuacamoleLite({ port: 4822, }, clientOptions); -// Public JS and CSS -baserouter.use('/public', express.static(path.join(__dirname, '/public'))); - -// Embedded guac -baserouter.get('/', (req, res) => { - const { crypt: { key, cypher } } = clientOptions; - - const token = req.query.login - ? encrypt(connectionOptions, cypher, key) - : encrypt(deepMerge(connectionOptions, { - connection: { - settings: credentials, - }, - }), cypher, key); - - res.render(path.join(__dirname, '/rdp.ejs'), { - token, - baseurl, - }); -}); - -// Web File Browser -baserouter.use(express.json()); -baserouter.use(express.urlencoded()); - -baserouter.get('/files', (req, res) => { - res.send('Unauthorized'); - res.end(); -}); - -baserouter.post('/files', (req, res, next) => { - pamAuthenticate({ - username: credentials.username, - password: req.body.password, - }, (err) => { - if (err) { - res.send('Unauthorized'); - res.end(); - return; - } - - next(); - }); -}); - -baserouter.use('/files', cloudcmd({ - config: { - root: '/', - prefix: `${trimTrailingSlash(baseurl)}/files`, - terminal: false, - console: false, - configDialog: false, - contact: false, - auth: false, - name: 'Files', - log: false, - keysPanel: false, - oneFilePanel: true, - }, -})); - // Spin up application on CUSTOM_PORT with fallback to port 3000 -app.use('/', baserouter); server.listen(CUSTOM_PORT, () => { console.log(`listening on *: ${CUSTOM_PORT}`); }); diff --git a/options.js b/lib/options.js similarity index 100% rename from options.js rename to lib/options.js diff --git a/rdp.ejs b/lib/rdp.ejs similarity index 100% rename from rdp.ejs rename to lib/rdp.ejs diff --git a/lib/server.js b/lib/server.js new file mode 100644 index 0000000..d1a07de --- /dev/null +++ b/lib/server.js @@ -0,0 +1,93 @@ +// LinuxServer Guacamole Client +const path = require('path'); +const express = require('express'); +const cloudcmd = require('cloudcmd'); +const { pamAuthenticate } = require('node-linux-pam'); + +const { clientOptions, connectionOptions } = require('./options'); +const { + encrypt, + trimTrailingSlash, + deepMerge, + loadConfig, +} = require('./utils'); + +// Application Variables +const baseurl = process.env.SUBFOLDER || '/'; + +const app = express(); +app.set('view engine', 'ejs'); +app.set('x-powered-by', false); + +const baserouter = express.Router(); +const credentials = loadConfig(path.resolve(__dirname, '..')); + +// Public JS and CSS +baserouter.use('/public', express.static(path.join(__dirname, '..', '/public'))); + +// Embedded guac +baserouter.get('/', (req, res) => { + const { crypt: { key, cypher } } = clientOptions; + + const token = req.query.login + ? encrypt(connectionOptions, cypher, key) + : encrypt(deepMerge(connectionOptions, { + connection: { + settings: credentials, + }, + }), cypher, key); + + res.render(path.join(__dirname, '/rdp.ejs'), { + token, + baseurl, + }); +}); + +// Web File Browser +baserouter.use(express.json()); +baserouter.use(express.urlencoded({ + extended: true, +})); + +baserouter.get('/files', (req, res) => { + res.status(401).send('Unauthorized'); +}); + +baserouter.post('/files', (req, res, next) => { + if (!req.body.password) { + res.status(401).send('Unauthorized'); + return; + } + + pamAuthenticate({ + username: credentials.username, + password: req.body.password, + }, (err) => { + if (!err) { + next(); + return; + } + + res.status(401).send('Unauthorized'); + }); +}); + +baserouter.use('/files', cloudcmd({ + config: { + root: '/', + prefix: `${trimTrailingSlash(baseurl)}/files`, + terminal: false, + console: false, + configDialog: false, + contact: false, + auth: false, + name: 'Files', + log: false, + keysPanel: false, + oneFilePanel: true, + }, +})); + +app.use('/', baserouter); + +exports.app = app; diff --git a/lib/token.js b/lib/token.js new file mode 100644 index 0000000..e326b2a --- /dev/null +++ b/lib/token.js @@ -0,0 +1,23 @@ +const { clientOptions, connectionOptions } = require('./options'); +const { encrypt, deepMerge } = require('./utils'); + +const makeToken = (credentials) => { + if (!('username' in credentials)) { + throw new Error('credential is missing `username`'); + } + + if (!('password' in credentials)) { + throw new Error('credential is missing `password`'); + } + + return encrypt(deepMerge(connectionOptions, { + connection: { + settings: { + username: credentials.username, + password: credentials.password, + }, + }, + }), clientOptions.crypt.cypher, clientOptions.crypt.key); +}; + +exports.makeToken = makeToken; diff --git a/utils.js b/lib/utils.js similarity index 100% rename from utils.js rename to lib/utils.js diff --git a/maketoken.js b/maketoken.js index 1a8d1e6..eb3d681 100644 --- a/maketoken.js +++ b/maketoken.js @@ -1,14 +1,4 @@ -const { clientOptions, connectionOptions } = require('./options'); -const { encrypt, deepMerge, loadConfig } = require('./utils'); +const { makeToken } = require('./lib/token'); +const { loadConfig } = require('./lib/utils'); -const credentials = loadConfig(__dirname); -const options = deepMerge(connectionOptions, { - connection: { - settings: { - username: 'abc', - password: credentials.password, - }, - }, -}); - -console.log(encrypt(options, clientOptions.crypt.cypher, clientOptions.crypt.key)); +console.log(makeToken(loadConfig(__dirname))); diff --git a/package.json b/package.json index 7d7c0dc..a321e43 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "app.js", "scripts": { "test": "jest --coverage --detectOpenHandles", - "lint": "eslint *.js" + "lint": "eslint *.js lib/*.js" }, "repository": { "type": "git",