Browse Source

Release 2.1.1

Bugfix: remove `-` from the start of usernames
pull/342/head v2.1.1
butlerx 3 years ago
parent
commit
0770647af5
No known key found for this signature in database GPG Key ID: B37CA765BAA89170
  1. 16
      .eslintrc.json
  2. 4
      package.json
  3. 48
      src/client/wetty/download.spec.ts
  4. 15
      src/server/shared/shell.spec.ts
  5. 2
      src/server/shared/shell.ts

16
.eslintrc.json

@ -1,6 +1,6 @@
{ {
"parser": "@typescript-eslint/parser", "parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "prettier", "mocha"], "plugins": ["@typescript-eslint", "prettier"],
"env": { "env": {
"es6": true, "es6": true,
"node": true, "node": true,
@ -67,5 +67,17 @@
"extensions": [".ts", ".js"] "extensions": [".ts", ".js"]
} }
} }
} },
"overrides": [
{
"files": ["*.spec.ts"],
"extends": ["plugin:mocha/recommended"],
"plugins": ["mocha"],
"rules": {
"import/no-extraneous-dependencies": ["off"],
"mocha/no-mocha-arrows": ["off"],
"no-unused-expressions": ["off"]
}
}
]
} }

4
package.json

@ -1,6 +1,6 @@
{ {
"name": "wetty", "name": "wetty",
"version": "2.1.0", "version": "2.1.1",
"description": "WeTTY = Web + TTY. Terminal access in browser over http/https", "description": "WeTTY = Web + TTY. Terminal access in browser over http/https",
"homepage": "https://github.com/butlerx/wetty", "homepage": "https://github.com/butlerx/wetty",
"license": "MIT", "license": "MIT",
@ -17,7 +17,7 @@
"build": "snowpack build", "build": "snowpack build",
"dev": "NODE_ENV=development concurrently --kill-others --success first \"snowpack dev\" \"nodemon .\"", "dev": "NODE_ENV=development concurrently --kill-others --success first \"snowpack dev\" \"nodemon .\"",
"prepublishOnly": "snowpack build", "prepublishOnly": "snowpack build",
"lint": "eslint src/**/*.ts", "lint": "eslint src",
"start": "NODE_ENV=production node .", "start": "NODE_ENV=production node .",
"contributor": "all-contributors", "contributor": "all-contributors",
"test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha -r ts-node/register src/**/*.spec.ts", "test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha -r ts-node/register src/**/*.spec.ts",

48
src/client/wetty/download.spec.ts

@ -1,5 +1,3 @@
/* eslint-disable */
import { expect } from 'chai'; import { expect } from 'chai';
import 'mocha'; import 'mocha';
import * as sinon from 'sinon'; import * as sinon from 'sinon';
@ -7,15 +5,17 @@ import * as sinon from 'sinon';
import { JSDOM } from 'jsdom'; import { JSDOM } from 'jsdom';
import { FileDownloader } from './download'; import { FileDownloader } from './download';
const noop = (): void => {}; // eslint-disable-line @typescript-eslint/no-empty-function
describe('FileDownloader', () => { describe('FileDownloader', () => {
const FILE_BEGIN = 'BEGIN'; const FILE_BEGIN = 'BEGIN';
const FILE_END = 'END'; const FILE_END = 'END';
let fileDownloader: any; let fileDownloader: FileDownloader;
beforeEach(() => { beforeEach(() => {
const { window } = new JSDOM(`...`); const { window } = new JSDOM(`...`);
global.document = window.document; global.document = window.document;
fileDownloader = new FileDownloader(() => {}, FILE_BEGIN, FILE_END); fileDownloader = new FileDownloader(noop, FILE_BEGIN, FILE_END);
}); });
afterEach(() => { afterEach(() => {
@ -81,7 +81,7 @@ describe('FileDownloader', () => {
}); });
it('should buffer across incomplete file begin marker sequence on two calls', () => { it('should buffer across incomplete file begin marker sequence on two calls', () => {
fileDownloader = new FileDownloader(() => {}, 'BEGIN', 'END'); fileDownloader = new FileDownloader(noop, 'BEGIN', 'END');
const onCompleteFileCallbackStub = sinon.stub( const onCompleteFileCallbackStub = sinon.stub(
fileDownloader, fileDownloader,
'onCompleteFileCallback', 'onCompleteFileCallback',
@ -94,7 +94,7 @@ describe('FileDownloader', () => {
}); });
it('should buffer across incomplete file begin marker sequence on n calls', () => { it('should buffer across incomplete file begin marker sequence on n calls', () => {
fileDownloader = new FileDownloader(() => {}, 'BEGIN', 'END'); fileDownloader = new FileDownloader(noop, 'BEGIN', 'END');
const onCompleteFileCallbackStub = sinon.stub( const onCompleteFileCallbackStub = sinon.stub(
fileDownloader, fileDownloader,
'onCompleteFileCallback', 'onCompleteFileCallback',
@ -104,25 +104,25 @@ describe('FileDownloader', () => {
expect(fileDownloader.buffer('E')).to.equal(''); expect(fileDownloader.buffer('E')).to.equal('');
expect(fileDownloader.buffer('G')).to.equal(''); expect(fileDownloader.buffer('G')).to.equal('');
expect(fileDownloader.buffer('I')).to.equal(''); expect(fileDownloader.buffer('I')).to.equal('');
expect(fileDownloader.buffer('NFILE' + 'END')).to.equal(''); expect(fileDownloader.buffer('NFILEEND')).to.equal('');
expect(onCompleteFileCallbackStub.calledOnce).to.be.true; expect(onCompleteFileCallbackStub.calledOnce).to.be.true;
expect(onCompleteFileCallbackStub.getCall(0).args[0]).to.equal('FILE'); expect(onCompleteFileCallbackStub.getCall(0).args[0]).to.equal('FILE');
}); });
it('should buffer across incomplete file begin marker sequence with data on the left and right on multiple calls', () => { it('should buffer across incomplete file begin marker sequence with data on the left and right on multiple calls', () => {
fileDownloader = new FileDownloader(() => {}, 'BEGIN', 'END'); fileDownloader = new FileDownloader(noop, 'BEGIN', 'END');
const onCompleteFileCallbackStub = sinon.stub( const onCompleteFileCallbackStub = sinon.stub(
fileDownloader, fileDownloader,
'onCompleteFileCallback', 'onCompleteFileCallback',
); );
expect(fileDownloader.buffer('DATA AT THE LEFT' + 'B')).to.equal( expect(fileDownloader.buffer('DATA AT THE LEFTB')).to.equal(
'DATA AT THE LEFT', 'DATA AT THE LEFT',
); );
expect(fileDownloader.buffer('E')).to.equal(''); expect(fileDownloader.buffer('E')).to.equal('');
expect(fileDownloader.buffer('G')).to.equal(''); expect(fileDownloader.buffer('G')).to.equal('');
expect(fileDownloader.buffer('I')).to.equal(''); expect(fileDownloader.buffer('I')).to.equal('');
expect(fileDownloader.buffer('NFILE' + 'ENDDATA AT THE RIGHT')).to.equal( expect(fileDownloader.buffer('NFILEENDDATA AT THE RIGHT')).to.equal(
'DATA AT THE RIGHT', 'DATA AT THE RIGHT',
); );
expect(onCompleteFileCallbackStub.calledOnce).to.be.true; expect(onCompleteFileCallbackStub.calledOnce).to.be.true;
@ -130,13 +130,13 @@ describe('FileDownloader', () => {
}); });
it('should buffer across incomplete file begin marker sequence then handle false positive', () => { it('should buffer across incomplete file begin marker sequence then handle false positive', () => {
fileDownloader = new FileDownloader(() => {}, 'BEGIN', 'END'); fileDownloader = new FileDownloader(noop, 'BEGIN', 'END');
const onCompleteFileCallbackStub = sinon.stub( const onCompleteFileCallbackStub = sinon.stub(
fileDownloader, fileDownloader,
'onCompleteFileCallback', 'onCompleteFileCallback',
); );
expect(fileDownloader.buffer('DATA AT THE LEFT' + 'B')).to.equal( expect(fileDownloader.buffer('DATA AT THE LEFTB')).to.equal(
'DATA AT THE LEFT', 'DATA AT THE LEFT',
); );
expect(fileDownloader.buffer('E')).to.equal(''); expect(fileDownloader.buffer('E')).to.equal('');
@ -150,7 +150,7 @@ describe('FileDownloader', () => {
}); });
it('should buffer across incomplete file end marker sequence on two calls', () => { it('should buffer across incomplete file end marker sequence on two calls', () => {
fileDownloader = new FileDownloader(() => {}, 'BEGIN', 'END'); fileDownloader = new FileDownloader(noop, 'BEGIN', 'END');
const mockFilePart1 = 'DATA AT THE LEFTBEGINFILEE'; const mockFilePart1 = 'DATA AT THE LEFTBEGINFILEE';
const mockFilePart2 = 'NDDATA AT THE RIGHT'; const mockFilePart2 = 'NDDATA AT THE RIGHT';
@ -166,13 +166,13 @@ describe('FileDownloader', () => {
}); });
it('should buffer across incomplete file end and file begin marker sequence with data on the left and right on multiple calls', () => { it('should buffer across incomplete file end and file begin marker sequence with data on the left and right on multiple calls', () => {
fileDownloader = new FileDownloader(() => {}, 'BEGIN', 'END'); fileDownloader = new FileDownloader(noop, 'BEGIN', 'END');
const onCompleteFileCallbackStub = sinon.stub( const onCompleteFileCallbackStub = sinon.stub(
fileDownloader, fileDownloader,
'onCompleteFileCallback', 'onCompleteFileCallback',
); );
expect(fileDownloader.buffer('DATA AT THE LEFT' + 'BE')).to.equal( expect(fileDownloader.buffer('DATA AT THE LEFTBE')).to.equal(
'DATA AT THE LEFT', 'DATA AT THE LEFT',
); );
expect(fileDownloader.buffer('G')).to.equal(''); expect(fileDownloader.buffer('G')).to.equal('');
@ -187,7 +187,7 @@ describe('FileDownloader', () => {
}); });
it('should be able to handle multiple files', () => { it('should be able to handle multiple files', () => {
fileDownloader = new FileDownloader(() => {}, 'BEGIN', 'END'); fileDownloader = new FileDownloader(noop, 'BEGIN', 'END');
const onCompleteFileCallbackStub = sinon.stub( const onCompleteFileCallbackStub = sinon.stub(
fileDownloader, fileDownloader,
'onCompleteFileCallback', 'onCompleteFileCallback',
@ -202,7 +202,7 @@ describe('FileDownloader', () => {
'SECOND DATA' + 'SECOND DATA' +
'BEGIN', 'BEGIN',
), ),
).to.equal('DATA AT THE LEFT' + 'SECOND DATA'); ).to.equal('DATA AT THE LEFTSECOND DATA');
expect(onCompleteFileCallbackStub.calledOnce).to.be.true; expect(onCompleteFileCallbackStub.calledOnce).to.be.true;
expect(onCompleteFileCallbackStub.getCall(0).args[0]).to.equal('FILE1'); expect(onCompleteFileCallbackStub.getCall(0).args[0]).to.equal('FILE1');
@ -214,19 +214,19 @@ describe('FileDownloader', () => {
}); });
it('should be able to handle multiple files with an ending marker', () => { it('should be able to handle multiple files with an ending marker', () => {
fileDownloader = new FileDownloader(() => {}, 'BEGIN', 'END'); fileDownloader = new FileDownloader(noop, 'BEGIN', 'END');
const onCompleteFileCallbackStub = sinon.stub( const onCompleteFileCallbackStub = sinon.stub(
fileDownloader, fileDownloader,
'onCompleteFileCallback', 'onCompleteFileCallback',
); );
expect( expect(fileDownloader.buffer('DATA AT THE LEFTBEGINFILE1EN')).to.equal(
fileDownloader.buffer('DATA AT THE LEFT' + 'BEGIN' + 'FILE1' + 'EN'), 'DATA AT THE LEFT',
).to.equal('DATA AT THE LEFT'); );
expect(onCompleteFileCallbackStub.calledOnce).to.be.false; expect(onCompleteFileCallbackStub.calledOnce).to.be.false;
expect( expect(fileDownloader.buffer('DSECOND DATABEGINFILE2EN')).to.equal(
fileDownloader.buffer('D' + 'SECOND DATA' + 'BEGIN' + 'FILE2' + 'EN'), 'SECOND DATA',
).to.equal('SECOND DATA'); );
expect(onCompleteFileCallbackStub.calledOnce).to.be.true; expect(onCompleteFileCallbackStub.calledOnce).to.be.true;
expect(onCompleteFileCallbackStub.getCall(0).args[0]).to.equal('FILE1'); expect(onCompleteFileCallbackStub.getCall(0).args[0]).to.equal('FILE1');
expect(fileDownloader.buffer('D')).to.equal(''); expect(fileDownloader.buffer('D')).to.equal('');

15
src/server/shared/shell.spec.ts

@ -0,0 +1,15 @@
import 'mocha';
import { expect } from 'chai';
import { escapeShell } from './shell';
describe('Values passed to escapeShell should be safe to pass woth sub processes', () => {
it('should escape remove subcommands', () => {
const cmd = escapeShell('test`echo hello`');
expect(cmd).to.equal('testechohello');
});
it('should ensure args cant be flags', () => {
const cmd = escapeShell("-oProxyCommand='bash' -c `wget localhost:2222`");
expect(cmd).to.equal('oProxyCommandbash-cwgetlocalhost2222');
});
});

2
src/server/shared/shell.ts

@ -1,2 +1,2 @@
export const escapeShell = (username: string): string => export const escapeShell = (username: string): string =>
username.replace(/[^a-zA-Z0-9-_]/g, ''); username.replace(/^-|[^a-zA-Z0-9_-]/g, '');

Loading…
Cancel
Save