Skip to content

Commit

Permalink
Replace hterm with Xterm.js (#29)
Browse files Browse the repository at this point in the history
* switch too xterm and webpack

* handle disconects clearner

* stop browser from over rulling ctrl+shift+c

* update pkg.json

* replace log statements with events

* restructure cli

* reduce use of shared state

* remove ssh wrapper

* minify, uglify and tree shake code bundle

* use seperate containers for building frontend

* fit sizing errors

* add helmet

* fix term resize

* add loger

* use custom fix function

* stop server crashing after disconnect

* make better on mobile

* use a pty as a buffer to handle all keyboard keys

* unwrap var

* clean up structure of code

* update readme

* add api

* refactor event emitter

* expand emmitter class

* fix event emitter calls

* format docs

* fix docs

* clean up webpack
  • Loading branch information
butlerx authored Feb 21, 2018
1 parent c7c6dc8 commit 616ba39
Show file tree
Hide file tree
Showing 35 changed files with 4,674 additions and 20,366 deletions.
11 changes: 0 additions & 11 deletions .babelrc

This file was deleted.

8 changes: 8 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
node_modules
.esm-cache
dist
*.yml
*.md
*.log
*.png
**/*.conf
**/*.service
Dockerfile
3 changes: 1 addition & 2 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
node_modules/
public/
.esm-cache
*hterm*
dist
42 changes: 11 additions & 31 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,16 @@
module.exports = {
env: {
es6 : true,
es6: true,
node: true,
browser: true
},
extends: ['airbnb'],
rules : {
'linebreak-style' : ['error', 'unix'],
'arrow-parens' : ['error', 'as-needed'],
'no-param-reassign' : ['error', { props: false }],
'func-style' : ['error', 'declaration', { allowArrowFunctions: true }],
'no-use-before-define': ['error', { functions: false }],
'no-shadow' : [
'error',
{
builtinGlobals: true,
hoist : 'functions',
allow : ['resolve', 'reject', 'err'],
},
],
'no-console': [
'error',
{
allow: ['warn', 'trace', 'log', 'error'],
},
],
'consistent-return': 0,
'key-spacing' : [
'error',
{
multiLine: { beforeColon: false, afterColon: true },
align : { beforeColon: false, afterColon: true, on: 'colon', mode: 'strict' },
},
],
},
root: true,
extends: ["airbnb-base", "plugin:prettier/recommended"],
rules: {
"linebreak-style": ["error", "unix"],
"arrow-parens": ["error", "as-needed"],
"no-param-reassign": ["error", { props: false }],
"func-style": ["error", "declaration", { allowArrowFunctions: true }],
"no-use-before-define": ["error", { functions: false }]
}
};
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ results
npm-debug.log
node_modules/*
.esm-cache
libapps
dist
13 changes: 13 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = {
singleQuote: true,
trailingComma: 'all',
proseWrap: 'always',
overrides: [
{
files: ['*.js', '*.mjs'],
options: {
printWidth: 80,
},
},
],
};
22 changes: 16 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
FROM node:8-alpine
MAINTAINER butlerx@notthe.cloud
FROM node:alpine as builder
WORKDIR /usr/src/app
COPY . /usr/src/app
RUN apk add -U build-base python && \
yarn && \
yarn build && \
yarn install --production --ignore-scripts --prefer-offline

FROM node:alpine
LABEL maintainer="butlerx@notthe.cloud"
WORKDIR /app
RUN adduser -D -h /home/term -s /bin/sh term && \
echo "term:term" | chpasswd
ENV NODE_ENV=production
RUN apk add -U openssh && \
adduser -D -h /home/term -s /bin/sh term && \
echo "term:term" | chpasswd
EXPOSE 3000
COPY . /app
RUN apk add --update build-base python openssh && yarn
COPY --from=builder /usr/src/app /app

CMD yarn start
203 changes: 106 additions & 97 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,145 +1,155 @@
Wetty = Web + tty
-----------------
## WeTTy = Web + TTy

Terminal over HTTP and HTTPS. Wetty is an alternative to
ajaxterm/anyterm but much better than them because wetty uses ChromeOS'
terminal emulator (hterm) which is a full fledged implementation of
terminal emulation written entirely in Javascript. Also it uses
websockets instead of Ajax and hence better response time.
Terminal over HTTP and https. WeTTy is an alternative to ajaxterm and anyterm
but much better than them because WeTTy uses xterm.js which is a full fledged
implementation of terminal emulation written entirely in JavaScript. WeTTy uses
websockets rather then Ajax and hence better response time.

[hterm source](https://chromium.googlesource.com/apps/libapps/+/master/hterm/)
![WeTTy](/terminal.png?raw=true)

![Wetty](/terminal.png?raw=true)

This fork has a few of the open PR's from the original merged in as well as scripts to make running
in docker better.
This fork was originally bug fixes and updates, but has since evolved in to a
full rewrite to use xterm.js to have better support and make it more
maintainable.

## Install

- `git clone https://github.com/butlerx/wetty`
- `cd wetty`
- `yarn`
WeTTy can be installed from source or from npm. To install from source run:

```bash
$ git clone https://github.com/butlerx/wetty
$ cd wetty
$ yarn
```

or
or install it globally with yarn, `yarn -g add wetty.js`, or npm,
`npm i -g wetty.js`

`yarn add wetty.js`
## Running WeTTy

## Run on HTTP
Wettu can either be run as a standalone service or from another node script. To
see how to use WeTTy from node see the [API Doc](./docs)

``` bash
node bin/index.js -p 3000
```bash
$ node index.js
```

If you run it as root it will launch `/bin/login` (where you can specify
the user name), else it will launch `ssh` and connect by default to
`localhost`.
Open your browser on `http://yourserver:3000/` and you will prompted to login.
Or go too `http://yourserver:3000/ssh/<username>` to specify the user before
hand.

If instead you wish to connect to a remote host you can specify the
`--sshhost` option, the SSH port using the `--sshport` option and the
SSH user using the `--sshuser` option.
### Flags

You can also specify the SSH user name in the address bar like this:
WeTTy can be run with the `--help` flag to get a full list of flags.

`http://yourserver:3000/wetty/ssh/<username>`
WeTTy runs on port `3000` by default. You can change the default port by tunning
with the `--port` or `-p` flag.

or
If WeTTy is run as root while the host is set as the local machine it will use
the `login` binary rather than ssh. If no host is specified it will use
`localhost` as the ssh host.

`http://yourserver:3000/ssh/<username>`
If instead you wish to connect to a remote host you can specify the host with
the `--sshhost` flag and pass the IP or DNS address of the host you want to
connect to.

## Run on HTTPS
You can specify the default user used to ssh to a host using the `--sshuser`.
This user can overwritten by going to `http://yourserver:3000/ssh/<username>`.
If this is left blank a user will be prompted to enter their username when they
connect.

Always use HTTPS. If you don't have SSL certificates from a CA you can
create a self signed certificate using this command:
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`.

```
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 30000 -nodes
```
### https

And then run:
Always use https especially with a terminal to your server. You can add https by
either using WeTTy behind a proxy or directly.

```
node bin/index.js --sslkey key.pem --sslcert cert.pem -p 3000
```
If you don't have SSL certificates from a CA you can create a self signed
certificate using this command:

Again, if you run it as root it will launch `/bin/login`, else it will
launch SSH to `localhost` or a specified host as explained above.
```bash
$ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 30000 -nodes
```

## Run wetty behind nginx or apache
To run WeTTy directly with ssl use both the `--sslkey` and `--sslcert` flags and
pass them the path too your cert and key as follows:

Put the following configuration in nginx's conf:
```bash
node index.js --sslkey key.pem --sslcert cert.pem -p 3000
```

location /wetty {
proxy_pass http://127.0.0.1:3000/wetty;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 43200000;
### Behind a Proxy

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
}
As said earlier you can use a proxy to add https to WeTTy.

Put the following configuration in apache's conf:
**Note** that if your proxy is configured for https you should run WeTTy without
SSL

RewriteCond %{REQUEST_URI} ^/wetty/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /wetty/socket.io/(.*) ws://localhost:9123/wetty/socket.io/$1 [P,L]
#### Nginx

<LocationMatch ^/wetty/(.*)>
DirectorySlash On
Require all granted
ProxyPassMatch http://127.0.0.1:9123
ProxyPassReverse /wetty/
</LocationMatch>
Put the following configuration in nginx's conf:

If you are running `bin/index.js` as `root` and have an Nginx proxy you have to use:
```nginx
location /wetty {
proxy_pass http://127.0.0.1:3000/wetty;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 43200000;
```
http://yourserver.com/wetty
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
}
```

Else if you are running `bin/index.js` as a regular user you can use:
#### Apache

```
http://yourserver.com/wetty/ssh/<username>
```
Put the following configuration in apache's conf:

or
```apache
RewriteCond %{REQUEST_URI} ^/wetty/socket.io [NC]
RewriteCond %{QUERY_STRING} transport=websocket [NC]
RewriteRule /wetty/socket.io/(.*) ws://localhost:3000/wetty/socket.io/$1 [P,L]
<LocationMatch ^/wetty/(.*)>
DirectorySlash On
Require all granted
ProxyPassMatch http://127.0.0.1:3000
ProxyPassReverse /wetty/
</LocationMatch>
```
http://yourserver.com/wetty
```

**Note that if your Nginx is configured for HTTPS you should run wetty without SSL.**

## Dockerized Version
### Dockerized Version

This repo includes a Dockerfile you can use to run a Dockerized version of wetty. You can run
whatever you want!
WeTTy can be run from a container to ssh to a remote host or the host system.
This is handy for quick deployments. Just modify `docker-compose.yml` for your
host and run:

Just modify docker-compose and run:

```
docker-compose up -d
```sh
$ docker-compose up -d
```

Visit the appropriate URL in your browser (`[localhost|$(boot2docker ip)]:PORT`).
Visit the appropriate URL in your browser
(`[localhost|$(boot2docker ip)]:PORT`).

The default username is `term` and the password is `term`, if you did not modify `SSHHOST`
The default username is `term` and the password is `term`, if you did not modify
`SSHHOST`

If you dont want to build the image yourself just remove the line `build; .`
In the docker version all flags can be accessed as environment variables such as
`SSHHOST` or `SSHPORT`.

## Run wetty as a service daemon
## Run WeTTy as a service daemon

Install wetty globally with global option:
Install WeTTy globally with global option:

### init.d

```bash
$ sudo yarn global add wetty.js
$ sudo cp /usr/local/lib/node_modules/wetty.js/bin/wetty.conf /etc/init
$ sudo cp ~/.config/yarn/global/node_modules/wetty.js/bin/wetty.conf /etc/init
$ sudo start wetty
```

Expand All @@ -152,18 +162,17 @@ $ systemctl --user enable wetty
$ systemctl --user start wetty
```

This will start wetty on port 3000. If you want to change the port or redirect
This will start WeTTy on port 3000. If you want to change the port or redirect
stdout/stderr you should change the last line in `wetty.conf` file, something
like this:
```

```systemd
exec sudo -u root wetty -p 80 >> /var/log/wetty.log 2>&1
```

## FAQ

### What browsers are supported?

Wetty supports all browsers that Google's hterm supports. Wetty has been [reported](https://github.com/krishnasrinivas/wetty/issues/45#issuecomment-181448586) to work on Google Chrome, Firefox and IE 11.

### Why isn't Wetty working with IE?

[This fix](https://stackoverflow.com/questions/13102116/access-denied-for-localstorage-in-ie10#20848924) has been known to help some users.
WeTTy supports all browsers that
[xterm.js supports](https://github.com/xtermjs/xterm.js#browser-support).
3 changes: 0 additions & 3 deletions bin/index.js

This file was deleted.

Loading

0 comments on commit 616ba39

Please sign in to comment.