chore: convert ./app/client/src/js/index.js to typescript #242
This commit is contained in:
parent
e0ea6ae9f6
commit
55754d3820
9 changed files with 367 additions and 46 deletions
230
app/client/built/index.js
Normal file
230
app/client/built/index.js
Normal file
|
|
@ -0,0 +1,230 @@
|
||||||
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
|
import io from 'socket.io-client';
|
||||||
|
import { Terminal } from 'xterm';
|
||||||
|
import { FitAddon } from 'xterm-addon-fit';
|
||||||
|
import { library, dom } from '@fortawesome/fontawesome-svg-core';
|
||||||
|
import { faBars, faClipboard, faDownload, faKey, faCog } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
library.add(faBars, faClipboard, faDownload, faKey, faCog);
|
||||||
|
dom.watch();
|
||||||
|
const debug = require('debug')('WebSSH2');
|
||||||
|
require('xterm/css/xterm.css');
|
||||||
|
require('../css/style.css');
|
||||||
|
/* global Blob, logBtn, credentialsBtn, reauthBtn, downloadLogBtn */ // eslint-disable-line
|
||||||
|
let sessionLogEnable = false;
|
||||||
|
let loggedData = false;
|
||||||
|
let allowreplay = false;
|
||||||
|
let allowreauth = false;
|
||||||
|
let sessionLog;
|
||||||
|
let sessionFooter;
|
||||||
|
let logDate;
|
||||||
|
let currentDate;
|
||||||
|
let myFile;
|
||||||
|
let errorExists;
|
||||||
|
let socket;
|
||||||
|
const term = new Terminal();
|
||||||
|
// DOM properties
|
||||||
|
const status = document.getElementById('status');
|
||||||
|
const header = document.getElementById('header');
|
||||||
|
const dropupContent = document.getElementById('dropupContent');
|
||||||
|
const footer = document.getElementById('footer');
|
||||||
|
const countdown = document.getElementById('countdown');
|
||||||
|
const fitAddon = new FitAddon();
|
||||||
|
const terminalContainer = document.getElementById('terminal-container');
|
||||||
|
term.loadAddon(fitAddon);
|
||||||
|
term.open(terminalContainer);
|
||||||
|
term.focus();
|
||||||
|
fitAddon.fit();
|
||||||
|
// reauthenticate
|
||||||
|
function reauthSession() {
|
||||||
|
debug('re-authenticating');
|
||||||
|
window.location.href = '/ssh/reauth';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// cross browser method to "download" an element to the local system
|
||||||
|
// used for our client-side logging feature
|
||||||
|
function downloadLog() {
|
||||||
|
if (loggedData === true) {
|
||||||
|
myFile = `WebSSH2-${logDate.getFullYear()}${logDate.getMonth() + 1}${logDate.getDate()}_${logDate.getHours()}${logDate.getMinutes()}${logDate.getSeconds()}.log`;
|
||||||
|
// regex should eliminate escape sequences from being logged.
|
||||||
|
const blob = new Blob([
|
||||||
|
sessionLog.replace(
|
||||||
|
// eslint-disable-next-line no-control-regex
|
||||||
|
/[\u001b\u009b][[\]()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><;]/g, ''),
|
||||||
|
], {
|
||||||
|
// eslint-disable-line no-control-regex
|
||||||
|
type: 'text/plain',
|
||||||
|
});
|
||||||
|
if (window.navigator.msSaveOrOpenBlob) {
|
||||||
|
window.navigator.msSaveBlob(blob, myFile);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const elem = window.document.createElement('a');
|
||||||
|
elem.href = window.URL.createObjectURL(blob);
|
||||||
|
elem.download = myFile;
|
||||||
|
document.body.appendChild(elem);
|
||||||
|
elem.click();
|
||||||
|
document.body.removeChild(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
term.focus();
|
||||||
|
}
|
||||||
|
// Set variable to toggle log data from client/server to a varialble
|
||||||
|
// for later download
|
||||||
|
function toggleLog() {
|
||||||
|
if (sessionLogEnable === true) {
|
||||||
|
sessionLogEnable = false;
|
||||||
|
loggedData = true;
|
||||||
|
logBtn.innerHTML = '<i class="fas fa-clipboard fa-fw"></i> Start Log';
|
||||||
|
// console.log(`stopping log, ${sessionLogEnable}`);
|
||||||
|
currentDate = new Date();
|
||||||
|
sessionLog = `${sessionLog}\r\n\r\nLog End for ${sessionFooter}: ${currentDate.getFullYear()}/${currentDate.getMonth() + 1}/${currentDate.getDate()} @ ${currentDate.getHours()}:${currentDate.getMinutes()}:${currentDate.getSeconds()}\r\n`;
|
||||||
|
logDate = currentDate;
|
||||||
|
term.focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sessionLogEnable = true;
|
||||||
|
loggedData = true;
|
||||||
|
logBtn.innerHTML = '<i class="fas fa-cog fa-spin fa-fw"></i> Stop Log';
|
||||||
|
downloadLogBtn.style.color = '#000';
|
||||||
|
downloadLogBtn.addEventListener('click', downloadLog);
|
||||||
|
// console.log(`starting log, ${sessionLogEnable}`);
|
||||||
|
currentDate = new Date();
|
||||||
|
sessionLog = `Log Start for ${sessionFooter}: ${currentDate.getFullYear()}/${currentDate.getMonth() + 1}/${currentDate.getDate()} @ ${currentDate.getHours()}:${currentDate.getMinutes()}:${currentDate.getSeconds()}\r\n\r\n`;
|
||||||
|
logDate = currentDate;
|
||||||
|
term.focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// replay password to server, requires
|
||||||
|
function replayCredentials() {
|
||||||
|
socket.emit('control', 'replayCredentials');
|
||||||
|
// console.log('replaying credentials');
|
||||||
|
term.focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// draw/re-draw menu and reattach listeners
|
||||||
|
// when dom is changed, listeners are abandonded
|
||||||
|
function drawMenu(data) {
|
||||||
|
dropupContent.innerHTML = data;
|
||||||
|
logBtn.addEventListener('click', toggleLog);
|
||||||
|
if (allowreauth) {
|
||||||
|
reauthBtn.addEventListener('click', reauthSession);
|
||||||
|
}
|
||||||
|
if (allowreplay) {
|
||||||
|
credentialsBtn.addEventListener('click', replayCredentials);
|
||||||
|
}
|
||||||
|
if (loggedData) {
|
||||||
|
downloadLogBtn.addEventListener('click', downloadLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function resizeScreen() {
|
||||||
|
fitAddon.fit();
|
||||||
|
socket.emit('resize', { cols: term.cols, rows: term.rows });
|
||||||
|
}
|
||||||
|
window.addEventListener('resize', resizeScreen, false);
|
||||||
|
socket = io.connect({
|
||||||
|
path: '/ssh/socket.io',
|
||||||
|
});
|
||||||
|
term.onData((data) => {
|
||||||
|
socket.emit('data', data);
|
||||||
|
});
|
||||||
|
socket.on('data', (data) => {
|
||||||
|
term.write(data);
|
||||||
|
if (sessionLogEnable) {
|
||||||
|
sessionLog += data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
socket.on('connect', () => {
|
||||||
|
socket.emit('geometry', term.cols, term.rows);
|
||||||
|
});
|
||||||
|
socket.on('setTerminalOpts', (data) => {
|
||||||
|
term.setOption('cursorBlink', data.cursorBlink);
|
||||||
|
term.setOption('scrollback', data.scrollback);
|
||||||
|
term.setOption('tabStopWidth', data.tabStopWidth);
|
||||||
|
term.setOption('bellStyle', data.bellStyle);
|
||||||
|
});
|
||||||
|
socket.on('title', (data) => {
|
||||||
|
document.title = data;
|
||||||
|
});
|
||||||
|
socket.on('menu', (data) => {
|
||||||
|
drawMenu(data);
|
||||||
|
});
|
||||||
|
socket.on('status', (data) => {
|
||||||
|
status.innerHTML = data;
|
||||||
|
});
|
||||||
|
socket.on('ssherror', (data) => {
|
||||||
|
status.innerHTML = data;
|
||||||
|
status.style.backgroundColor = 'red';
|
||||||
|
errorExists = true;
|
||||||
|
});
|
||||||
|
socket.on('headerBackground', (data) => {
|
||||||
|
header.style.backgroundColor = data;
|
||||||
|
});
|
||||||
|
socket.on('header', (data) => {
|
||||||
|
if (data) {
|
||||||
|
header.innerHTML = data;
|
||||||
|
header.style.display = 'block';
|
||||||
|
// header is 19px and footer is 19px, recaculate new terminal-container and resize
|
||||||
|
terminalContainer.style.height = 'calc(100% - 38px)';
|
||||||
|
resizeScreen();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
socket.on('footer', (data) => {
|
||||||
|
sessionFooter = data;
|
||||||
|
footer.innerHTML = data;
|
||||||
|
});
|
||||||
|
socket.on('statusBackground', (data) => {
|
||||||
|
status.style.backgroundColor = data;
|
||||||
|
});
|
||||||
|
socket.on('allowreplay', (data) => {
|
||||||
|
if (data === true) {
|
||||||
|
debug(`allowreplay: ${data}`);
|
||||||
|
allowreplay = true;
|
||||||
|
drawMenu(`${dropupContent.innerHTML}<a id="credentialsBtn"><i class="fas fa-key fa-fw"></i> Credentials</a>`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
allowreplay = false;
|
||||||
|
debug(`allowreplay: ${data}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
socket.on('allowreauth', (data) => {
|
||||||
|
if (data === true) {
|
||||||
|
debug(`allowreauth: ${data}`);
|
||||||
|
allowreauth = true;
|
||||||
|
drawMenu(`${dropupContent.innerHTML}<a id="reauthBtn"><i class="fas fa-key fa-fw"></i> Switch User</a>`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
allowreauth = false;
|
||||||
|
debug(`allowreauth: ${data}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
socket.on('disconnect', (err) => {
|
||||||
|
if (!errorExists) {
|
||||||
|
status.style.backgroundColor = 'red';
|
||||||
|
status.innerHTML = `WEBSOCKET SERVER DISCONNECTED: ${err}`;
|
||||||
|
}
|
||||||
|
socket.io.reconnection(false);
|
||||||
|
countdown.classList.remove('active');
|
||||||
|
});
|
||||||
|
socket.on('error', (err) => {
|
||||||
|
if (!errorExists) {
|
||||||
|
status.style.backgroundColor = 'red';
|
||||||
|
status.innerHTML = `ERROR: ${err}`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
socket.on('reauth', () => {
|
||||||
|
if (allowreauth) {
|
||||||
|
reauthSession();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// safe shutdown
|
||||||
|
let hasCountdownStarted = false;
|
||||||
|
socket.on('shutdownCountdownUpdate', (remainingSeconds) => {
|
||||||
|
if (!hasCountdownStarted) {
|
||||||
|
countdown.classList.add('active');
|
||||||
|
hasCountdownStarted = true;
|
||||||
|
}
|
||||||
|
countdown.innerText = `Shutting down in ${remainingSeconds}s`;
|
||||||
|
});
|
||||||
|
term.onTitleChange((title) => {
|
||||||
|
document.title = title;
|
||||||
|
});
|
||||||
|
|
@ -15,7 +15,12 @@
|
||||||
<div id="bottomdiv">
|
<div id="bottomdiv">
|
||||||
<div class="dropup" id="menu">
|
<div class="dropup" id="menu">
|
||||||
<i class="fas fa-bars fa-fw"></i> Menu
|
<i class="fas fa-bars fa-fw"></i> Menu
|
||||||
<div id="dropupContent" class="dropup-content"></div>
|
<div id="dropupContent" class="dropup-content">
|
||||||
|
<a id="logBtn"><i class="fas fa-clipboard fa-fw"></i> Start Log</a>
|
||||||
|
<a id="downloadLogBtn"><i class="fas fa-download fa-fw"></i> Download Log</a>
|
||||||
|
<a id="reauthBtn" style="display: none;"><i class="fas fa-key fa-fw"></i> Switch User</a>
|
||||||
|
<a id="credentialsBtn" style="display: none;"><i class="fas fa-key fa-fw"></i> Credentials</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="footer"></div>
|
<div id="footer"></div>
|
||||||
<div id="status"></div>
|
<div id="status"></div>
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -15,7 +15,12 @@
|
||||||
<div id="bottomdiv">
|
<div id="bottomdiv">
|
||||||
<div class="dropup" id="menu">
|
<div class="dropup" id="menu">
|
||||||
<i class="fas fa-bars fa-fw"></i> Menu
|
<i class="fas fa-bars fa-fw"></i> Menu
|
||||||
<div id="dropupContent" class="dropup-content"></div>
|
<div id="dropupContent" class="dropup-content">
|
||||||
|
<a id="logBtn"><i class="fas fa-clipboard fa-fw"></i> Start Log</a>
|
||||||
|
<a id="downloadLogBtn"><i class="fas fa-download fa-fw"></i> Download Log</a>
|
||||||
|
<a id="reauthBtn" style="display: none;"><i class="fas fa-key fa-fw"></i> Switch User</a>
|
||||||
|
<a id="credentialsBtn" style="display: none;"><i class="fas fa-key fa-fw"></i> Credentials</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="footer"></div>
|
<div id="footer"></div>
|
||||||
<div id="status"></div>
|
<div id="status"></div>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/* eslint-disable import/no-extraneous-dependencies */
|
/* eslint-disable import/no-extraneous-dependencies */
|
||||||
import io from 'socket.io-client';
|
import { io } from 'socket.io-client';
|
||||||
import { Terminal } from 'xterm';
|
import { Terminal } from 'xterm';
|
||||||
import { FitAddon } from 'xterm-addon-fit';
|
import { FitAddon } from 'xterm-addon-fit';
|
||||||
import { library, dom } from '@fortawesome/fontawesome-svg-core';
|
import { library, dom } from '@fortawesome/fontawesome-svg-core';
|
||||||
|
|
@ -17,18 +17,27 @@ let sessionLogEnable = false;
|
||||||
let loggedData = false;
|
let loggedData = false;
|
||||||
let allowreplay = false;
|
let allowreplay = false;
|
||||||
let allowreauth = false;
|
let allowreauth = false;
|
||||||
let sessionLog;
|
let sessionLog: string;
|
||||||
let sessionFooter;
|
let sessionFooter: any;
|
||||||
let logDate;
|
let logDate: {
|
||||||
let currentDate;
|
getFullYear: () => any;
|
||||||
let myFile;
|
getMonth: () => number;
|
||||||
let errorExists;
|
getDate: () => any;
|
||||||
let socket, termid // eslint-disable-line
|
getHours: () => any;
|
||||||
|
getMinutes: () => any;
|
||||||
|
getSeconds: () => any;
|
||||||
|
};
|
||||||
|
let currentDate: Date;
|
||||||
|
let myFile: string;
|
||||||
|
let errorExists: boolean;
|
||||||
const term = new Terminal();
|
const term = new Terminal();
|
||||||
// DOM properties
|
// DOM properties
|
||||||
|
const logBtn = document.getElementById('logBtn');
|
||||||
|
const credentialsBtn = document.getElementById('credentialsBtn');
|
||||||
|
const reauthBtn = document.getElementById('reauthBtn');
|
||||||
|
const downloadLogBtn = document.getElementById('downloadLogBtn');
|
||||||
const status = document.getElementById('status');
|
const status = document.getElementById('status');
|
||||||
const header = document.getElementById('header');
|
const header = document.getElementById('header');
|
||||||
const dropupContent = document.getElementById('dropupContent');
|
|
||||||
const footer = document.getElementById('footer');
|
const footer = document.getElementById('footer');
|
||||||
const countdown = document.getElementById('countdown');
|
const countdown = document.getElementById('countdown');
|
||||||
const fitAddon = new FitAddon();
|
const fitAddon = new FitAddon();
|
||||||
|
|
@ -38,6 +47,10 @@ term.open(terminalContainer);
|
||||||
term.focus();
|
term.focus();
|
||||||
fitAddon.fit();
|
fitAddon.fit();
|
||||||
|
|
||||||
|
const socket = io({
|
||||||
|
path: '/ssh/socket.io',
|
||||||
|
});
|
||||||
|
|
||||||
// reauthenticate
|
// reauthenticate
|
||||||
function reauthSession () { // eslint-disable-line
|
function reauthSession () { // eslint-disable-line
|
||||||
debug('re-authenticating');
|
debug('re-authenticating');
|
||||||
|
|
@ -120,17 +133,19 @@ function replayCredentials () { // eslint-disable-line
|
||||||
|
|
||||||
// draw/re-draw menu and reattach listeners
|
// draw/re-draw menu and reattach listeners
|
||||||
// when dom is changed, listeners are abandonded
|
// when dom is changed, listeners are abandonded
|
||||||
function drawMenu(data) {
|
function drawMenu() {
|
||||||
dropupContent.innerHTML = data;
|
|
||||||
logBtn.addEventListener('click', toggleLog);
|
logBtn.addEventListener('click', toggleLog);
|
||||||
if (allowreauth) {
|
if (allowreauth) {
|
||||||
reauthBtn.addEventListener('click', reauthSession);
|
reauthBtn.addEventListener('click', reauthSession);
|
||||||
|
reauthBtn.style.display = 'block';
|
||||||
}
|
}
|
||||||
if (allowreplay) {
|
if (allowreplay) {
|
||||||
credentialsBtn.addEventListener('click', replayCredentials);
|
credentialsBtn.addEventListener('click', replayCredentials);
|
||||||
|
credentialsBtn.style.display = 'block';
|
||||||
}
|
}
|
||||||
if (loggedData) {
|
if (loggedData) {
|
||||||
downloadLogBtn.addEventListener('click', downloadLog);
|
downloadLogBtn.addEventListener('click', downloadLog);
|
||||||
|
downloadLogBtn.style.display = 'block';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,15 +156,11 @@ function resizeScreen() {
|
||||||
|
|
||||||
window.addEventListener('resize', resizeScreen, false);
|
window.addEventListener('resize', resizeScreen, false);
|
||||||
|
|
||||||
socket = io.connect({
|
|
||||||
path: '/ssh/socket.io',
|
|
||||||
});
|
|
||||||
|
|
||||||
term.onData((data) => {
|
term.onData((data) => {
|
||||||
socket.emit('data', data);
|
socket.emit('data', data);
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('data', (data) => {
|
socket.on('data', (data: string | Uint8Array) => {
|
||||||
term.write(data);
|
term.write(data);
|
||||||
if (sessionLogEnable) {
|
if (sessionLogEnable) {
|
||||||
sessionLog += data;
|
sessionLog += data;
|
||||||
|
|
@ -160,36 +171,39 @@ socket.on('connect', () => {
|
||||||
socket.emit('geometry', term.cols, term.rows);
|
socket.emit('geometry', term.cols, term.rows);
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('setTerminalOpts', (data) => {
|
socket.on(
|
||||||
term.setOption('cursorBlink', data.cursorBlink);
|
'setTerminalOpts',
|
||||||
term.setOption('scrollback', data.scrollback);
|
(data: { cursorBlink: any; scrollback: any; tabStopWidth: any; bellStyle: any }) => {
|
||||||
term.setOption('tabStopWidth', data.tabStopWidth);
|
term.setOption('cursorBlink', data.cursorBlink);
|
||||||
term.setOption('bellStyle', data.bellStyle);
|
term.setOption('scrollback', data.scrollback);
|
||||||
});
|
term.setOption('tabStopWidth', data.tabStopWidth);
|
||||||
|
term.setOption('bellStyle', data.bellStyle);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
socket.on('title', (data) => {
|
socket.on('title', (data: string) => {
|
||||||
document.title = data;
|
document.title = data;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('menu', (data) => {
|
socket.on('menu', () => {
|
||||||
drawMenu(data);
|
drawMenu();
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('status', (data) => {
|
socket.on('status', (data: string) => {
|
||||||
status.innerHTML = data;
|
status.innerHTML = data;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('ssherror', (data) => {
|
socket.on('ssherror', (data: string) => {
|
||||||
status.innerHTML = data;
|
status.innerHTML = data;
|
||||||
status.style.backgroundColor = 'red';
|
status.style.backgroundColor = 'red';
|
||||||
errorExists = true;
|
errorExists = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('headerBackground', (data) => {
|
socket.on('headerBackground', (data: string) => {
|
||||||
header.style.backgroundColor = data;
|
header.style.backgroundColor = data;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('header', (data) => {
|
socket.on('header', (data: string) => {
|
||||||
if (data) {
|
if (data) {
|
||||||
header.innerHTML = data;
|
header.innerHTML = data;
|
||||||
header.style.display = 'block';
|
header.style.display = 'block';
|
||||||
|
|
@ -199,42 +213,38 @@ socket.on('header', (data) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('footer', (data) => {
|
socket.on('footer', (data: string) => {
|
||||||
sessionFooter = data;
|
sessionFooter = data;
|
||||||
footer.innerHTML = data;
|
footer.innerHTML = data;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('statusBackground', (data) => {
|
socket.on('statusBackground', (data: string) => {
|
||||||
status.style.backgroundColor = data;
|
status.style.backgroundColor = data;
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('allowreplay', (data) => {
|
socket.on('allowreplay', (data: boolean) => {
|
||||||
if (data === true) {
|
if (data === true) {
|
||||||
debug(`allowreplay: ${data}`);
|
debug(`allowreplay: ${data}`);
|
||||||
allowreplay = true;
|
allowreplay = true;
|
||||||
drawMenu(
|
drawMenu();
|
||||||
`${dropupContent.innerHTML}<a id="credentialsBtn"><i class="fas fa-key fa-fw"></i> Credentials</a>`
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
allowreplay = false;
|
allowreplay = false;
|
||||||
debug(`allowreplay: ${data}`);
|
debug(`allowreplay: ${data}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('allowreauth', (data) => {
|
socket.on('allowreauth', (data: boolean) => {
|
||||||
if (data === true) {
|
if (data === true) {
|
||||||
debug(`allowreauth: ${data}`);
|
debug(`allowreauth: ${data}`);
|
||||||
allowreauth = true;
|
allowreauth = true;
|
||||||
drawMenu(
|
drawMenu();
|
||||||
`${dropupContent.innerHTML}<a id="reauthBtn"><i class="fas fa-key fa-fw"></i> Switch User</a>`
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
allowreauth = false;
|
allowreauth = false;
|
||||||
debug(`allowreauth: ${data}`);
|
debug(`allowreauth: ${data}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('disconnect', (err) => {
|
socket.on('disconnect', (err: any) => {
|
||||||
if (!errorExists) {
|
if (!errorExists) {
|
||||||
status.style.backgroundColor = 'red';
|
status.style.backgroundColor = 'red';
|
||||||
status.innerHTML = `WEBSOCKET SERVER DISCONNECTED: ${err}`;
|
status.innerHTML = `WEBSOCKET SERVER DISCONNECTED: ${err}`;
|
||||||
|
|
@ -243,7 +253,7 @@ socket.on('disconnect', (err) => {
|
||||||
countdown.classList.remove('active');
|
countdown.classList.remove('active');
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('error', (err) => {
|
socket.on('error', (err: any) => {
|
||||||
if (!errorExists) {
|
if (!errorExists) {
|
||||||
status.style.backgroundColor = 'red';
|
status.style.backgroundColor = 'red';
|
||||||
status.innerHTML = `ERROR: ${err}`;
|
status.innerHTML = `ERROR: ${err}`;
|
||||||
|
|
@ -259,7 +269,7 @@ socket.on('reauth', () => {
|
||||||
// safe shutdown
|
// safe shutdown
|
||||||
let hasCountdownStarted = false;
|
let hasCountdownStarted = false;
|
||||||
|
|
||||||
socket.on('shutdownCountdownUpdate', (remainingSeconds) => {
|
socket.on('shutdownCountdownUpdate', (remainingSeconds: any) => {
|
||||||
if (!hasCountdownStarted) {
|
if (!hasCountdownStarted) {
|
||||||
countdown.classList.add('active');
|
countdown.classList.add('active');
|
||||||
hasCountdownStarted = true;
|
hasCountdownStarted = true;
|
||||||
9
app/client/tsconfig.json
Normal file
9
app/client/tsconfig.json
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./built",
|
||||||
|
"allowJs": true,
|
||||||
|
"target": "es6",
|
||||||
|
"moduleResolution": "node"
|
||||||
|
},
|
||||||
|
"include": ["./src/**/*"],
|
||||||
|
}
|
||||||
46
app/package-lock.json
generated
46
app/package-lock.json
generated
|
|
@ -551,6 +551,12 @@
|
||||||
"through": ">=2.2.7 <3"
|
"through": ">=2.2.7 <3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"abab": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"accepts": {
|
"accepts": {
|
||||||
"version": "1.3.7",
|
"version": "1.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||||
|
|
@ -4666,6 +4672,34 @@
|
||||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"source-map-js": {
|
||||||
|
"version": "0.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz",
|
||||||
|
"integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"source-map-loader": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-UzOTTQhoNPeTNzOxwFw220RSRzdGSyH4lpNyWjR7Qm34P4/N0W669YSUFdH07+YNeN75h765XLHmNsF/bm97RQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"abab": "^2.0.5",
|
||||||
|
"iconv-lite": "^0.6.2",
|
||||||
|
"source-map-js": "^0.6.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"iconv-lite": {
|
||||||
|
"version": "0.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
|
||||||
|
"integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"source-map-support": {
|
"source-map-support": {
|
||||||
"version": "0.5.19",
|
"version": "0.5.19",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
|
||||||
|
|
@ -5063,6 +5097,18 @@
|
||||||
"integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=",
|
"integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"ts-loader": {
|
||||||
|
"version": "9.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.1.2.tgz",
|
||||||
|
"integrity": "sha512-ryMgATvLLl+z8zQvdlm6Pep0slmwxFWIEnq/5VdiLVjqQXnFJgO+qNLGIIP+d2N2jsFZ9MibZCVDb2bSp7OmEA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"chalk": "^4.1.0",
|
||||||
|
"enhanced-resolve": "^5.0.0",
|
||||||
|
"micromatch": "^4.0.0",
|
||||||
|
"semver": "^7.3.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"tsconfig-paths": {
|
"tsconfig-paths": {
|
||||||
"version": "3.9.0",
|
"version": "3.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz",
|
||||||
|
|
|
||||||
|
|
@ -73,8 +73,10 @@
|
||||||
"prettier": "^2.3.0",
|
"prettier": "^2.3.0",
|
||||||
"snazzy": "^9.0.0",
|
"snazzy": "^9.0.0",
|
||||||
"socket.io-client": "^4.1.1",
|
"socket.io-client": "^4.1.1",
|
||||||
|
"source-map-loader": "^2.0.1",
|
||||||
"standard-version": "^9.3.0",
|
"standard-version": "^9.3.0",
|
||||||
"terser-webpack-plugin": "^5.1.2",
|
"terser-webpack-plugin": "^5.1.2",
|
||||||
|
"ts-loader": "^9.1.2",
|
||||||
"typescript": "^4.2.4",
|
"typescript": "^4.2.4",
|
||||||
"webpack": "^5.37.0",
|
"webpack": "^5.37.0",
|
||||||
"webpack-cli": "^4.7.0",
|
"webpack-cli": "^4.7.0",
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,12 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
context: path.resolve('__dirname', '../'),
|
context: path.resolve('__dirname', '../'),
|
||||||
|
resolve: {
|
||||||
|
// Add '.ts' and '.tsx' as resolvable extensions.
|
||||||
|
extensions: ['', '.webpack.js', '.web.js', '.ts', '.tsx', '.js'],
|
||||||
|
},
|
||||||
entry: {
|
entry: {
|
||||||
webssh2: './client/src/js/index.js',
|
webssh2: './client/src/js/index.ts',
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new CleanWebpackPlugin(),
|
new CleanWebpackPlugin(),
|
||||||
|
|
@ -26,6 +30,16 @@ module.exports = {
|
||||||
test: /\.css$/,
|
test: /\.css$/,
|
||||||
use: [MiniCssExtractPlugin.loader, 'css-loader'],
|
use: [MiniCssExtractPlugin.loader, 'css-loader'],
|
||||||
},
|
},
|
||||||
|
// All files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'.
|
||||||
|
{
|
||||||
|
test: /\.tsx?$/,
|
||||||
|
loader: 'ts-loader',
|
||||||
|
},
|
||||||
|
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
|
||||||
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
loader: 'source-map-loader',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue