diff --git a/Dockerfile b/Dockerfile index ca9e604..0cac198 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ FROM node:boron-alpine as builder +RUN apk add -U build-base python WORKDIR /usr/src/app COPY . /usr/src/app -RUN apk add -U build-base python && \ - yarn && \ +RUN yarn && \ yarn build && \ yarn install --production --ignore-scripts --prefer-offline @@ -16,4 +16,4 @@ RUN apk add -U openssh && \ EXPOSE 3000 COPY --from=builder /usr/src/app /app -CMD yarn start +ENTRYPOINT [ "/usr/local/bin/yarn", "start" ] diff --git a/README.md b/README.md index 7212f83..c2d9b9c 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ $ node index.js ``` Open your browser on `http://yourserver:3000/` and you will prompted to login. -Or go too `http://yourserver:3000/ssh/` to specify the user before +Or go to `http://yourserver:3000/ssh/` to specify the user before hand. ### Flags @@ -63,6 +63,10 @@ connect. By default WeTTy will try to ssh to port `22`, if your host uses an alternative ssh port this can be specified with the flag `--sshport`. +If you'd prefer an HTTP base prefix other than `/wetty`, you can specify that +with `--base`. Do not set this to `/ssh/${something}`, as this will break +username matching code. + ### https Always use https especially with a terminal to your server. You can add https by @@ -89,6 +93,10 @@ As said earlier you can use a proxy to add https to WeTTy. **Note** that if your proxy is configured for https you should run WeTTy without SSL +If your proxy uses a base path other than `/wetty`, +specify the path with the `--base` flag, +or the `BASE` environment variable. + #### Nginx Put the following configuration in nginx's conf: diff --git a/lib/command.mjs b/lib/command.mjs index 68ca2bd..fa4e2fe 100644 --- a/lib/command.mjs +++ b/lib/command.mjs @@ -24,7 +24,7 @@ export default ( }); function address(headers, user, host) { - const match = headers.referer.match('.+/ssh/.+$'); + const match = headers.referer.match('.+/ssh/([^/]+)$'); const fallback = user ? `${user}@${host}` : host; - return match ? `${match[0].split('/ssh/').pop()}@${host}` : fallback; + return match ? `${match[1]}@${host}` : fallback; } diff --git a/lib/emitter.mjs b/lib/emitter.mjs index e31fa48..93c496e 100644 --- a/lib/emitter.mjs +++ b/lib/emitter.mjs @@ -18,6 +18,7 @@ class WeTTy extends EventEmitter { * @param {string} [ssh.host=localhost] machine to ssh too * @param {string} [ssh.auth=password] authtype to use * @param {number} [ssh.port=22] port to connect to over ssh + * @param {number} [basePath=/wetty/] base part of URL * @param {number} [serverPort=3000] Port to run server on * @param {Object} [ssl] SSL settings * @param {?string} [ssl.key] Path to ssl key @@ -26,11 +27,12 @@ class WeTTy extends EventEmitter { */ start( { user = '', host = 'localhost', auth = 'password', port = 22 }, + basePath = '/wetty/', serverPort = 3000, { key, cert } ) { return loadSSL(key, cert).then(ssl => { - const io = server(serverPort, ssl); + const io = server(basePath, serverPort, ssl); /** * Wetty server connected too * @fires WeTTy#connnection diff --git a/lib/index.mjs b/lib/index.mjs index 3cc7884..dce17d5 100644 --- a/lib/index.mjs +++ b/lib/index.mjs @@ -29,6 +29,11 @@ const opts = optimist description: 'defaults to "password", you can use "publickey,password" instead', }, + base: { + demand: false, + alias: 'b', + description: 'base path to wetty', + }, port: { demand: false, alias: 'p', @@ -47,7 +52,8 @@ export default class { sshuser = process.env.SSHUSER || '', sshhost = process.env.SSHHOST || 'localhost', sshauth = process.env.SSHAUTH || 'password', - sshport = process.env.SSHPORT || 22, + sshport = process.env.SSHPOST || 22, + base = process.env.BASE || '/wetty/', port = process.env.PORT || 3000, sslkey, sslcert, @@ -70,6 +76,7 @@ export default class { auth: sshauth, port: sshport, }, + base, port, { key: sslkey, cert: sslcert } ); diff --git a/lib/server.mjs b/lib/server.mjs index 8b71a90..51b68f0 100644 --- a/lib/server.mjs +++ b/lib/server.mjs @@ -12,22 +12,26 @@ import logger from './logger.mjs'; import events from './emitter.mjs'; const pubDir = path.join(__dirname, '..', 'public'); +const distDir = path.join(__dirname, '..', 'dist'); -export default function createServer(port, { key, cert }) { - events.emit('debug', `key: ${key}, cert: ${cert}, port: ${port}`); +export default function createServer(base, port, { key, cert }) { + base = base.replace(/\/*$/, ""); + events.emit('debug', `key: ${key}, cert: ${cert}, port: ${port}, base: ${base}`); const app = express(); - const wetty = (req, res) => res.sendFile(path.join(pubDir, 'index.html')); + const html = (req, res) => res.sendFile(path.join(pubDir, 'index.html')); + const css = (req, res) => res.sendFile(path.join(distDir, 'main.css')); + const js = (req, res) => res.sendFile(path.join(distDir, 'main.js')); app .use(morgan('combined', { stream: logger.stream })) .use(helmet()) .use(compression()) .use(favicon(path.join(pubDir, 'favicon.ico'))) - .get('/wetty/ssh/:user', wetty) - .get('/wetty/', wetty) - .use('/wetty', express.static(path.join(__dirname, '..', 'dist'))) - .get('/ssh/:user', wetty) - .get('/', wetty) - .use('/', express.static(path.join(__dirname, '..', 'dist'))); + .get(`${base}/`, html) + .get(`${base}/main.css`, css) + .get(`${base}/main.js`, js) + .get(`${base}/ssh/main.css`, css) + .get(`${base}/ssh/main.js`, js) + .get(`${base}/ssh/:user`, html) return socket( !isUndefined(key) && !isUndefined(cert) @@ -37,6 +41,6 @@ export default function createServer(port, { key, cert }) { : http.createServer(app).listen(port, () => { events.server(port, 'http'); }), - { path: '/wetty/socket.io' } + { path: `${base}/socket.io` } ); } diff --git a/public/index.html b/public/index.html index 475c0dc..0eb7dc6 100644 --- a/public/index.html +++ b/public/index.html @@ -5,7 +5,7 @@ WeTTy - The Web Terminal Emulator - +
@@ -15,6 +15,6 @@
- + diff --git a/src/index.js b/src/index.js index c32ab7b..705312d 100644 --- a/src/index.js +++ b/src/index.js @@ -5,7 +5,9 @@ import * as fit from './fit'; import './wetty.scss'; Terminal.applyAddon(fit); -const socket = io(window.location.origin, { path: '/wetty/socket.io' }); +var userRegex = new RegExp("ssh/\[^/]+$"); +var socketPath = window.location.pathname.replace(userRegex, ""); +var socket = io(window.location.origin, { path: socketPath + "socket.io" }); socket.on('connect', () => { const term = new Terminal();