1
1
mirror of https://github.com/pterodactyl/panel.git synced 2024-11-22 17:12:30 +01:00

Merge branch 'develop' into feature/PTDL-472

This commit is contained in:
Dane Everitt 2017-07-01 12:33:30 -05:00
commit 2f4ec64f2a
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
20 changed files with 633 additions and 463 deletions

View File

@ -3,6 +3,23 @@ This file is a running track of new features and fixes to each version of the pa
This project follows [Semantic Versioning](http://semver.org) guidelines.
## v0.6.4 (Courageous Carniadactylus)
### Fixed
* Fixed the console rendering on page load, I guess people don't like watching it load line-by-line for 10 minutes. Who would have guessed...
* Re-added support for up/down arrows loading previous commands in the console window.
### Changed
* Panel API for Daemon now responds with a `HTTP/401 Unauthorized` error when unable to locate a node with a given authentication token, rather than a `HTTP/404 Not Found` response.
* Added better colors and styling for the terminal that can be adjusted per-theme.
* Session timeout adjusted to be 7 days by default.
## v0.6.3 (Courageous Carniadactylus)
### Fixed
* **[Security]** — Addresses an oversight in how the terminal rendered information sent from the server feed which allowed a malicious user to execute arbitrary commands on the game-server process itself by using a specifically crafted in-game command.
### Changed
* Removed `jquery.terminal` and replaced it with an in-house developed terminal with less potential for security issues.
## v0.6.2 (Courageous Carniadactylus)
### Fixed
* Fixes a few typos throughout the panel, there are more don't worry.

View File

@ -39,6 +39,8 @@ AdminLTE - [license](https://github.com/almasaeed2010/AdminLTE/blob/master/LICEN
Animate.css - [license](https://github.com/daneden/animate.css/blob/master/LICENSE) - [homepage](http://daneden.github.io/animate.css/)
AnsiUp - [license](https://github.com/drudru/ansi_up/blob/master/Readme.md#license) - [homepage](https://github.com/drudru/ansi_up)
Async.js - [license](https://github.com/caolan/async/blob/master/LICENSE) - [homepage](https://github.com/caolan/async/)
Bootstrap - [license](https://github.com/twbs/bootstrap/blob/master/LICENSE) - [homepage](http://getbootstrap.com)
@ -53,8 +55,6 @@ FontAwesome Animations - [license](https://github.com/l-lin/font-awesome-animati
jQuery - [license](https://github.com/jquery/jquery/blob/master/LICENSE.txt) - [homepage](http://jquery.com)
jQuery Terminal - [license](https://github.com/jcubic/jquery.terminal/blob/master/LICENSE) - [homepage](http://terminal.jcubic.pl)
Laravel Framework - [license](https://github.com/laravel/framework/blob/5.4/LICENSE.md) - [homepage](https://laravel.com)
Lodash - [license](https://github.com/lodash/lodash/blob/master/LICENSE) - [homepage](https://lodash.com/)

View File

@ -76,7 +76,7 @@ class DaemonAuthenticate
$node = Node::where('daemonSecret', $request->header('X-Access-Node'))->first();
if (! $node) {
return abort(404);
return abort(401);
}
return $next($request);

View File

@ -29,7 +29,7 @@ return [
|
*/
'lifetime' => 120,
'lifetime' => 10080,
'expire_on_close' => false,

View File

@ -1,5 +1,5 @@
/* global define, KeyboardEvent, module */
// https://github.com/cvan/keyboardevent-key-polyfill/blob/master/LICENSE.md
(function () {
var keyboardeventKeyPolyfill = {

View File

@ -257,22 +257,6 @@ span[aria-labelledby="select2-pUserId-container"] {
position: relative;
}
.terminal-notify {
position: absolute;
right: 27px;
bottom: 10px;
padding: 3.5px 7px;
border-radius: 3px 3px 0 0;
background: #ccc;
color: #000;
opacity: .5;
cursor: pointer;
}
.terminal-notify:hover {
opacity: .9;
}
.no-margin-bottom {
margin-bottom: 0 !important;
}

View File

@ -0,0 +1,102 @@
/*Design for Terminal*/
@import url('https://fonts.googleapis.com/css?family=Source+Code+Pro');
#terminal-body {
background: rgb(26, 26, 26);
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
#terminal {
font-family: 'Source Code Pro', monospace;
color: rgb(223, 223, 223);
background: rgb(26, 26, 26);
font-size: 12px;
line-height: 14px;
padding: 10px 10px 0;
box-sizing: border-box;
height: 500px;
max-height: 500px;
overflow-y: auto;
overflow-x: hidden;
border-radius: 5px 5px 0 0;
}
#terminal > .cmd {
padding: 1px 0;
}
#terminal_input {
width: 100%;
background: rgb(26, 26, 26);
border-radius: 0 0 5px 5px;
padding: 0 0 0 10px !important;
}
.terminal_input--input, .terminal_input--prompt {
font-family: 'Source Code Pro', monospace;
margin-bottom: 0;
border: 0 !important;
background: transparent !important;
color: rgb(223, 223, 223);
font-size: 12px;
padding: 1px 0 4px !important;
}
.terminal_input--input {
margin-left: 6px;
line-height: 1;
outline: none !important;
}
.terminal-notify {
position: absolute;
right: 30px;
bottom: 30px;
padding: 3.5px 7px;
border-radius: 3px;
background: #fff;
color: #000;
opacity: .5;
font-size: 16px;
cursor: pointer;
}
.terminal-notify:hover {
opacity: .9;
}
.ansi-black-fg { color: rgb(0, 0, 0); }
.ansi-red-fg { color: rgb(166, 0, 44); }
.ansi-green-fg { color: rgb(55, 106, 27); }
.ansi-yellow-fg { color: rgb(241, 133, 24); }
.ansi-blue-fg { color: rgb(17, 56, 163); }
.ansi-magenta-fg { color: rgb(67, 0, 117); }
.ansi-cyan-fg { color: rgb(18, 95, 105); }
.ansi-white-fg { color: rgb(255, 255, 255); }
.ansi-bright-black-fg { color: rgb(51, 51, 51); }
.ansi-bright-red-fg { color: rgb(223, 45, 39); }
.ansi-bright-green-fg { color: rgb(105, 175, 45); }
.ansi-bright-yellow-fg { color: rgb(254, 232, 57); }
.ansi-bright-blue-fg { color: rgb(68, 145, 240); }
.ansi-bright-magenta-fg { color: rgb(151, 50, 174); }
.ansi-bright-cyan-fg{ color: rgb(37, 173, 98); }
.ansi-bright-white-fg { color: rgb(208, 208, 208); }
.ansi-black-bg { background: rgb(0, 0, 0); }
.ansi-red-bg { background: rgb(166, 0, 44); }
.ansi-green-bg { background: rgb(55, 106, 27); }
.ansi-yellow-bg { background: rgb(241, 133, 24); }
.ansi-blue-bg { background: rgb(17, 56, 163); }
.ansi-magenta-bg { background: rgb(67, 0, 117); }
.ansi-cyan-bg { background: rgb(18, 95, 105); }
.ansi-white-bg { background: rgb(255, 255, 255); }
.ansi-bright-black-bg { background: rgb(51, 51, 51); }
.ansi-bright-red-bg { background: rgb(223, 45, 39); }
.ansi-bright-green-bg { background: rgb(105, 175, 45); }
.ansi-bright-yellow-bg { background: rgb(254, 232, 57); }
.ansi-bright-blue-bg { background: rgb(68, 145, 240); }
.ansi-bright-magenta-bg { background: rgb(151, 50, 174); }
.ansi-bright-cyan-bg { background: rgb(37, 173, 98); }
.ansi-bright-white-bg { background: rgb(208, 208, 208); }

View File

@ -17,42 +17,129 @@
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
var CONSOLE_PUSH_COUNT = Pterodactyl.config.console_count || 10;
var CONSOLE_PUSH_COUNT = Pterodactyl.config.console_count || 50;
var CONSOLE_PUSH_FREQ = Pterodactyl.config.console_freq || 200;
var CONSOLE_OUTPUT_LIMIT = Pterodactyl.config.console_limit || 2000;
var InitialLogSent = false;
var KEYCODE_UP_ARROW = 38;
var KEYCODE_DOWN_ARROW = 40;
var AnsiUp = new AnsiUp;
AnsiUp.use_classes = true;
var $terminal = $('#terminal');
var $terminalInput = $('.terminal_input--input');
var $scrollNotify = $('#terminalNotify');
$(document).ready(function () {
var storage = window.localStorage;
var activeHx = [];
var currentHxIndex = 0;
var currentKeyCount = 0;
var storedConsoleHistory = storage.getItem('console_hx_' + Pterodactyl.server.uuid);
try {
activeHx = JSON.parse(storedConsoleHistory) || [];
currentKeyCount = activeHx.length - 1;
} catch (ex) {
//
}
$terminalInput.focus();
$('.terminal_input--prompt, #terminal_input, #terminal, #terminalNotify').on('click', function () {
$terminalInput.focus();
});
$terminalInput.on('keyup', function (e) {
if (e.which === KEYCODE_DOWN_ARROW || e.which === KEYCODE_UP_ARROW) {
var value = consoleHistory(e.which);
if (value !== false) {
$terminalInput.val(value);
}
}
if (e.which === 27) {
$(this).val('');
}
if (e.which === 13) {
saveToHistory($(this).val());
Socket.emit((ConsoleServerStatus !== 0) ? 'send command' : 'set status', $(this).val());
$(this).val('');
}
});
function consoleHistory(key) {
// Get previous
if (key === KEYCODE_UP_ARROW) {
// currentHxIndex++;
var index = activeHx.length - (currentHxIndex + 1);
if (typeof activeHx[index - 1] === 'undefined') {
return activeHx[index];
}
currentHxIndex++;
return activeHx[index];
}
// Get more recent
if (key === KEYCODE_DOWN_ARROW) {
var index = activeHx.length - currentHxIndex;
if (typeof activeHx[index + 1] === 'undefined') {
return activeHx[index];
}
currentHxIndex--;
return activeHx[index];
}
}
function saveToHistory(command) {
if (command.length === 0) {
return;
}
if (activeHx.length >= 50) {
activeHx.pop();
}
currentHxIndex = 0;
currentKeyCount++;
activeHx[currentKeyCount] = command;
storage.setItem('console_hx_' + Pterodactyl.server.uuid, JSON.stringify(activeHx));
}
});
$terminal.on('scroll', function () {
if ($(this).scrollTop() + $(this).innerHeight() < $(this)[0].scrollHeight) {
$scrollNotify.removeClass('hidden');
} else {
$scrollNotify.addClass('hidden');
}
});
window.scrollToBottom = function () {
$terminal.scrollTop($terminal[0].scrollHeight);
};
function pushToTerminal(string) {
$terminal.append('<div class="cmd">' + AnsiUp.ansi_to_html(string + '\u001b[0m') + '</div>');
}
(function initConsole() {
window.TerminalQueue = [];
window.ConsoleServerStatus = 0;
window.Terminal = $('#terminal').terminal(function (command, term) {
Socket.emit((ConsoleServerStatus !== 0) ? 'send command' : 'set status', command);
}, {
greetings: '',
name: Pterodactyl.server.uuid,
height: 450,
exit: false,
echoCommand: false,
outputLimit: CONSOLE_OUTPUT_LIMIT,
prompt: Pterodactyl.server.username + ':~$ ',
scrollOnEcho: false,
scrollBottomOffset: 5,
onBlur: function (terminal) {
return false;
}
window.ConsoleElements = 0;
$scrollNotify.on('click', function () {
window.scrollToBottom();
$scrollNotify.addClass('hidden');
});
window.TerminalNotifyElement = $('#terminalNotify');
TerminalNotifyElement.on('click', function () {
Terminal.scroll_to_bottom();
TerminalNotifyElement.addClass('hidden');
})
Terminal.on('scroll', function () {
if (Terminal.is_bottom()) {
TerminalNotifyElement.addClass('hidden');
}
})
})();
(function pushOutputQueue() {
@ -62,16 +149,20 @@ var InitialLogSent = false;
if (TerminalQueue.length > 0) {
for (var i = 0; i < CONSOLE_PUSH_COUNT && TerminalQueue.length > 0; i++) {
Terminal.echo(TerminalQueue[0], { flush: false });
pushToTerminal(TerminalQueue[0]);
if (! $scrollNotify.is(':visible')) {
window.scrollToBottom();
}
window.ConsoleElements++;
TerminalQueue.shift();
}
// Flush after looping through all.
Terminal.flush();
// Show Warning
if (! Terminal.is_bottom()) {
TerminalNotifyElement.removeClass('hidden');
var removeElements = window.ConsoleElements - CONSOLE_OUTPUT_LIMIT;
if (removeElements > 0) {
$('#terminal').find('.cmd').slice(0, removeElements).remove();
window.ConsoleElements = window.ConsoleElements - removeElements;
}
}
@ -82,12 +173,10 @@ var InitialLogSent = false;
// Update Listings on Initial Status
Socket.on('initial status', function (data) {
ConsoleServerStatus = data.status;
if (! InitialLogSent) {
updateServerPowerControls(data.status);
updateServerPowerControls(data.status);
if (data.status === 1 || data.status === 2) {
Socket.emit('send server log');
}
if (data.status === 1 || data.status === 2) {
Socket.emit('send server log');
}
});
@ -97,20 +186,23 @@ var InitialLogSent = false;
updateServerPowerControls(data.status);
});
// Skips the queue so we don't wait
// 10 minutes to load the log...
Socket.on('server log', function (data) {
if (! InitialLogSent) {
Terminal.clear();
TerminalQueue.push(data);
InitialLogSent = true;
}
$('#terminal').html('');
data.split(/\n/g).forEach(function (item) {
pushToTerminal(item);
window.scrollToBottom();
});
});
Socket.on('console', function (data) {
TerminalQueue.push(data.line);
data.line.split(/\n/g).forEach(function (item) {
TerminalQueue.push(item);
});
});
})();
function updateServerPowerControls (data) {
// Server is On or Starting
if(data == 1 || data == 2) {

View File

@ -0,0 +1,335 @@
/* ansi_up.js
* author : Dru Nelson
* license : MIT
* http://github.com/drudru/ansi_up
*/
(function (factory) {
var v;
if (typeof module === "object" && typeof module.exports === "object") {
v = factory(require, exports);
if ("undefined" !== typeof v) module.exports = v;
}
else if ("function" === typeof define && define.amd) {
define(["require", "exports"], factory);
}
else {
var req, exp = {};
v = factory(req, exp);
window.AnsiUp = exp.default;
}
})(function (require, exports) {
"use strict";
function rgx(tmplObj) {
var subst = [];
for (var _i = 1; _i < arguments.length; _i++) {
subst[_i - 1] = arguments[_i];
}
var regexText = tmplObj.raw[0];
var wsrgx = /^\s+|\s+\n|\s+#[\s\S]+?\n/gm;
var txt2 = regexText.replace(wsrgx, '');
return new RegExp(txt2, 'm');
}
var AnsiUp = (function () {
function AnsiUp() {
this.VERSION = "2.0.1";
this.ansi_colors = [
[
{ rgb: [0, 0, 0], class_name: "ansi-black" },
{ rgb: [187, 0, 0], class_name: "ansi-red" },
{ rgb: [0, 187, 0], class_name: "ansi-green" },
{ rgb: [187, 187, 0], class_name: "ansi-yellow" },
{ rgb: [0, 0, 187], class_name: "ansi-blue" },
{ rgb: [187, 0, 187], class_name: "ansi-magenta" },
{ rgb: [0, 187, 187], class_name: "ansi-cyan" },
{ rgb: [255, 255, 255], class_name: "ansi-white" }
],
[
{ rgb: [85, 85, 85], class_name: "ansi-bright-black" },
{ rgb: [255, 85, 85], class_name: "ansi-bright-red" },
{ rgb: [0, 255, 0], class_name: "ansi-bright-green" },
{ rgb: [255, 255, 85], class_name: "ansi-bright-yellow" },
{ rgb: [85, 85, 255], class_name: "ansi-bright-blue" },
{ rgb: [255, 85, 255], class_name: "ansi-bright-magenta" },
{ rgb: [85, 255, 255], class_name: "ansi-bright-cyan" },
{ rgb: [255, 255, 255], class_name: "ansi-bright-white" }
]
];
this.htmlFormatter = {
transform: function (fragment, instance) {
var txt = fragment.text;
if (txt.length === 0)
return txt;
if (instance._escape_for_html)
txt = instance.old_escape_for_html(txt);
if (!fragment.bright && fragment.fg === null && fragment.bg === null)
return txt;
var styles = [];
var classes = [];
var fg = fragment.fg;
var bg = fragment.bg;
if (fg === null && fragment.bright)
fg = instance.ansi_colors[1][7];
if (!instance._use_classes) {
if (fg)
styles.push("color:rgb(" + fg.rgb.join(',') + ")");
if (bg)
styles.push("background-color:rgb(" + bg.rgb + ")");
}
else {
if (fg) {
if (fg.class_name !== 'truecolor') {
classes.push(fg.class_name + "-fg");
}
else {
styles.push("color:rgb(" + fg.rgb.join(',') + ")");
}
}
if (bg) {
if (bg.class_name !== 'truecolor') {
classes.push(bg.class_name + "-bg");
}
else {
styles.push("background-color:rgb(" + bg.rgb.join(',') + ")");
}
}
}
var class_string = '';
var style_string = '';
if (classes.length)
class_string = " class=\"" + classes.join(' ') + "\"";
if (styles.length)
style_string = " style=\"" + styles.join(';') + "\"";
return "<span" + class_string + style_string + ">" + txt + "</span>";
},
compose: function (segments, instance) {
return segments.join("");
}
};
this.textFormatter = {
transform: function (fragment, instance) {
return fragment.text;
},
compose: function (segments, instance) {
return segments.join("");
}
};
this.setup_256_palette();
this._use_classes = false;
this._escape_for_html = true;
this.bright = false;
this.fg = this.bg = null;
this._buffer = '';
}
Object.defineProperty(AnsiUp.prototype, "use_classes", {
get: function () {
return this._use_classes;
},
set: function (arg) {
this._use_classes = arg;
},
enumerable: true,
configurable: true
});
Object.defineProperty(AnsiUp.prototype, "escape_for_html", {
get: function () {
return this._escape_for_html;
},
set: function (arg) {
this._escape_for_html = arg;
},
enumerable: true,
configurable: true
});
AnsiUp.prototype.setup_256_palette = function () {
var _this = this;
this.palette_256 = [];
this.ansi_colors.forEach(function (palette) {
palette.forEach(function (rec) {
_this.palette_256.push(rec);
});
});
var levels = [0, 95, 135, 175, 215, 255];
for (var r = 0; r < 6; ++r) {
for (var g = 0; g < 6; ++g) {
for (var b = 0; b < 6; ++b) {
var col = { rgb: [levels[r], levels[g], levels[b]], class_name: 'truecolor' };
this.palette_256.push(col);
}
}
}
var grey_level = 8;
for (var i = 0; i < 24; ++i, grey_level += 10) {
var gry = { rgb: [grey_level, grey_level, grey_level], class_name: 'truecolor' };
this.palette_256.push(gry);
}
};
AnsiUp.prototype.old_escape_for_html = function (txt) {
return txt.replace(/[&<>]/gm, function (str) {
if (str === "&")
return "&amp;";
if (str === "<")
return "&lt;";
if (str === ">")
return "&gt;";
});
};
AnsiUp.prototype.old_linkify = function (txt) {
return txt.replace(/(https?:\/\/[^\s]+)/gm, function (str) {
return "<a href=\"" + str + "\">" + str + "</a>";
});
};
AnsiUp.prototype.detect_incomplete_ansi = function (txt) {
return !(/.*?[\x40-\x7e]/.test(txt));
};
AnsiUp.prototype.detect_incomplete_link = function (txt) {
var found = false;
for (var i = txt.length - 1; i > 0; i--) {
if (/\s|\x1B/.test(txt[i])) {
found = true;
break;
}
}
if (!found) {
if (/(https?:\/\/[^\s]+)/.test(txt))
return 0;
else
return -1;
}
var prefix = txt.substr(i + 1, 4);
if (prefix.length === 0)
return -1;
if ("http".indexOf(prefix) === 0)
return (i + 1);
};
AnsiUp.prototype.ansi_to = function (txt, formatter) {
var pkt = this._buffer + txt;
this._buffer = '';
var raw_text_pkts = pkt.split(/\x1B\[/);
if (raw_text_pkts.length === 1)
raw_text_pkts.push('');
this.handle_incomplete_sequences(raw_text_pkts);
var first_chunk = this.with_state(raw_text_pkts.shift());
var blocks = new Array(raw_text_pkts.length);
for (var i = 0, len = raw_text_pkts.length; i < len; ++i) {
blocks[i] = (formatter.transform(this.process_ansi(raw_text_pkts[i]), this));
}
if (first_chunk.text.length > 0)
blocks.unshift(formatter.transform(first_chunk, this));
return formatter.compose(blocks, this);
};
AnsiUp.prototype.ansi_to_html = function (txt) {
return this.ansi_to(txt, this.htmlFormatter);
};
AnsiUp.prototype.ansi_to_text = function (txt) {
return this.ansi_to(txt, this.textFormatter);
};
AnsiUp.prototype.with_state = function (text) {
return { bright: this.bright, fg: this.fg, bg: this.bg, text: text };
};
AnsiUp.prototype.handle_incomplete_sequences = function (chunks) {
var last_chunk = chunks[chunks.length - 1];
if ((last_chunk.length > 0) && this.detect_incomplete_ansi(last_chunk)) {
this._buffer = "\x1B[" + last_chunk;
chunks.pop();
chunks.push('');
}
else {
if (last_chunk.slice(-1) === "\x1B") {
this._buffer = "\x1B";
console.log("raw", chunks);
chunks.pop();
chunks.push(last_chunk.substr(0, last_chunk.length - 1));
console.log(chunks);
console.log(last_chunk);
}
if (chunks.length === 2 &&
chunks[1] === "" &&
chunks[0].slice(-1) === "\x1B") {
this._buffer = "\x1B";
last_chunk = chunks.shift();
chunks.unshift(last_chunk.substr(0, last_chunk.length - 1));
}
}
};
AnsiUp.prototype.process_ansi = function (block) {
if (!this._sgr_regex) {
this._sgr_regex = (_a = ["\n ^ # beginning of line\n ([!<-?]?) # a private-mode char (!, <, =, >, ?)\n ([d;]*) # any digits or semicolons\n ([ -/]? # an intermediate modifier\n [@-~]) # the command\n ([sS]*) # any text following this CSI sequence\n "], _a.raw = ["\n ^ # beginning of line\n ([!\\x3c-\\x3f]?) # a private-mode char (!, <, =, >, ?)\n ([\\d;]*) # any digits or semicolons\n ([\\x20-\\x2f]? # an intermediate modifier\n [\\x40-\\x7e]) # the command\n ([\\s\\S]*) # any text following this CSI sequence\n "], rgx(_a));
}
var matches = block.match(this._sgr_regex);
if (!matches) {
return this.with_state(block);
}
var orig_txt = matches[4];
if (matches[1] !== '' || matches[3] !== 'm') {
return this.with_state(orig_txt);
}
var sgr_cmds = matches[2].split(';');
while (sgr_cmds.length > 0) {
var sgr_cmd_str = sgr_cmds.shift();
var num = parseInt(sgr_cmd_str, 10);
if (isNaN(num) || num === 0) {
this.fg = this.bg = null;
this.bright = false;
}
else if (num === 1) {
this.bright = true;
}
else if (num === 22) {
this.bright = false;
}
else if (num === 39) {
this.fg = null;
}
else if (num === 49) {
this.bg = null;
}
else if ((num >= 30) && (num < 38)) {
var bidx = this.bright ? 1 : 0;
this.fg = this.ansi_colors[bidx][(num - 30)];
}
else if ((num >= 90) && (num < 98)) {
this.fg = this.ansi_colors[1][(num - 90)];
}
else if ((num >= 40) && (num < 48)) {
this.bg = this.ansi_colors[0][(num - 40)];
}
else if ((num >= 100) && (num < 108)) {
this.bg = this.ansi_colors[1][(num - 100)];
}
else if (num === 38 || num === 48) {
if (sgr_cmds.length > 0) {
var is_foreground = (num === 38);
var mode_cmd = sgr_cmds.shift();
if (mode_cmd === '5' && sgr_cmds.length > 0) {
var palette_index = parseInt(sgr_cmds.shift(), 10);
if (palette_index >= 0 && palette_index <= 255) {
if (is_foreground)
this.fg = this.palette_256[palette_index];
else
this.bg = this.palette_256[palette_index];
}
}
if (mode_cmd === '2' && sgr_cmds.length > 2) {
var r = parseInt(sgr_cmds.shift(), 10);
var g = parseInt(sgr_cmds.shift(), 10);
var b = parseInt(sgr_cmds.shift(), 10);
if ((r >= 0 && r <= 255) && (g >= 0 && g <= 255) && (b >= 0 && b <= 255)) {
var c = { rgb: [r, g, b], class_name: 'truecolor' };
if (is_foreground)
this.fg = c;
else
this.bg = c;
}
}
}
}
}
return this.with_state(orig_txt);
var _a;
};
return AnsiUp;
}());
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = AnsiUp;
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,318 +0,0 @@
/**@license
* __ _____ ________ __
* / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / /
* __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ /
* / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__
* \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/
* \/ /____/
* http://terminal.jcubic.pl
*
* This is example of how to create custom formatter for jQuery Terminal
*
* Copyright (c) 2014-2016 Jakub Jankiewicz <http://jcubic.pl/me>
* Released under the MIT license
*
*/
(function($) {
if (!$.terminal) {
throw new Error('$.terminal is not defined');
}
// ---------------------------------------------------------------------
// :: Replace overtyping (from man) formatting with terminal formatting
// ---------------------------------------------------------------------
$.terminal.overtyping = function(string) {
return string.replace(/((?:_\x08.|.\x08_)+)/g, function(full) {
var striped = full.replace(/_x08|\x08_|_\u0008|\u0008_/g, '');
return '[[u;;]' + striped + ']';
}).replace(/((?:.\x08.)+)/g, function(full) {
return '[[b;#fff;]' + full.replace(/(.)(?:\x08|\u0008)\1/g,
function(full, g) {
return g;
}) + ']';
});
};
// ---------------------------------------------------------------------
// :: Html colors taken from ANSI formatting in Linux Terminal
// ---------------------------------------------------------------------
$.terminal.ansi_colors = {
normal: {
black: '#000',
red: '#A00',
green: '#008400',
yellow: '#A50',
blue: '#00A',
magenta: '#A0A',
cyan: '#0AA',
white: '#AAA'
},
faited: {
black: '#000',
red: '#640000',
green: '#006100',
yellow: '#737300',
blue: '#000087',
magenta: '#650065',
cyan: '#008787',
white: '#818181'
},
bold: {
black: '#000',
red: '#F55',
green: '#44D544',
yellow: '#FF5',
blue: '#55F',
magenta: '#F5F',
cyan: '#5FF',
white: '#FFF'
},
// XTerm 8-bit pallete
palette: [
'#000000', '#AA0000', '#00AA00', '#AA5500', '#0000AA', '#AA00AA',
'#00AAAA', '#AAAAAA', '#555555', '#FF5555', '#55FF55', '#FFFF55',
'#5555FF', '#FF55FF', '#55FFFF', '#FFFFFF', '#000000', '#00005F',
'#000087', '#0000AF', '#0000D7', '#0000FF', '#005F00', '#005F5F',
'#005F87', '#005FAF', '#005FD7', '#005FFF', '#008700', '#00875F',
'#008787', '#0087AF', '#0087D7', '#0087FF', '#00AF00', '#00AF5F',
'#00AF87', '#00AFAF', '#00AFD7', '#00AFFF', '#00D700', '#00D75F',
'#00D787', '#00D7AF', '#00D7D7', '#00D7FF', '#00FF00', '#00FF5F',
'#00FF87', '#00FFAF', '#00FFD7', '#00FFFF', '#5F0000', '#5F005F',
'#5F0087', '#5F00AF', '#5F00D7', '#5F00FF', '#5F5F00', '#5F5F5F',
'#5F5F87', '#5F5FAF', '#5F5FD7', '#5F5FFF', '#5F8700', '#5F875F',
'#5F8787', '#5F87AF', '#5F87D7', '#5F87FF', '#5FAF00', '#5FAF5F',
'#5FAF87', '#5FAFAF', '#5FAFD7', '#5FAFFF', '#5FD700', '#5FD75F',
'#5FD787', '#5FD7AF', '#5FD7D7', '#5FD7FF', '#5FFF00', '#5FFF5F',
'#5FFF87', '#5FFFAF', '#5FFFD7', '#5FFFFF', '#870000', '#87005F',
'#870087', '#8700AF', '#8700D7', '#8700FF', '#875F00', '#875F5F',
'#875F87', '#875FAF', '#875FD7', '#875FFF', '#878700', '#87875F',
'#878787', '#8787AF', '#8787D7', '#8787FF', '#87AF00', '#87AF5F',
'#87AF87', '#87AFAF', '#87AFD7', '#87AFFF', '#87D700', '#87D75F',
'#87D787', '#87D7AF', '#87D7D7', '#87D7FF', '#87FF00', '#87FF5F',
'#87FF87', '#87FFAF', '#87FFD7', '#87FFFF', '#AF0000', '#AF005F',
'#AF0087', '#AF00AF', '#AF00D7', '#AF00FF', '#AF5F00', '#AF5F5F',
'#AF5F87', '#AF5FAF', '#AF5FD7', '#AF5FFF', '#AF8700', '#AF875F',
'#AF8787', '#AF87AF', '#AF87D7', '#AF87FF', '#AFAF00', '#AFAF5F',
'#AFAF87', '#AFAFAF', '#AFAFD7', '#AFAFFF', '#AFD700', '#AFD75F',
'#AFD787', '#AFD7AF', '#AFD7D7', '#AFD7FF', '#AFFF00', '#AFFF5F',
'#AFFF87', '#AFFFAF', '#AFFFD7', '#AFFFFF', '#D70000', '#D7005F',
'#D70087', '#D700AF', '#D700D7', '#D700FF', '#D75F00', '#D75F5F',
'#D75F87', '#D75FAF', '#D75FD7', '#D75FFF', '#D78700', '#D7875F',
'#D78787', '#D787AF', '#D787D7', '#D787FF', '#D7AF00', '#D7AF5F',
'#D7AF87', '#D7AFAF', '#D7AFD7', '#D7AFFF', '#D7D700', '#D7D75F',
'#D7D787', '#D7D7AF', '#D7D7D7', '#D7D7FF', '#D7FF00', '#D7FF5F',
'#D7FF87', '#D7FFAF', '#D7FFD7', '#D7FFFF', '#FF0000', '#FF005F',
'#FF0087', '#FF00AF', '#FF00D7', '#FF00FF', '#FF5F00', '#FF5F5F',
'#FF5F87', '#FF5FAF', '#FF5FD7', '#FF5FFF', '#FF8700', '#FF875F',
'#FF8787', '#FF87AF', '#FF87D7', '#FF87FF', '#FFAF00', '#FFAF5F',
'#FFAF87', '#FFAFAF', '#FFAFD7', '#FFAFFF', '#FFD700', '#FFD75F',
'#FFD787', '#FFD7AF', '#FFD7D7', '#FFD7FF', '#FFFF00', '#FFFF5F',
'#FFFF87', '#FFFFAF', '#FFFFD7', '#FFFFFF', '#080808', '#121212',
'#1C1C1C', '#262626', '#303030', '#3A3A3A', '#444444', '#4E4E4E',
'#585858', '#626262', '#6C6C6C', '#767676', '#808080', '#8A8A8A',
'#949494', '#9E9E9E', '#A8A8A8', '#B2B2B2', '#BCBCBC', '#C6C6C6',
'#D0D0D0', '#DADADA', '#E4E4E4', '#EEEEEE'
]
};
// ---------------------------------------------------------------------
// :: Replace ANSI formatting with terminal formatting
// ---------------------------------------------------------------------
$.terminal.from_ansi = (function() {
var color_list = {
30: 'black',
31: 'red',
32: 'green',
33: 'yellow',
34: 'blue',
35: 'magenta',
36: 'cyan',
37: 'white',
39: 'inherit' // default color
};
var background_list = {
40: 'black',
41: 'red',
42: 'green',
43: 'yellow',
44: 'blue',
45: 'magenta',
46: 'cyan',
47: 'white',
49: 'transparent' // default background
};
function format_ansi(code) {
var controls = code.split(';');
var num;
var faited = false;
var reverse = false;
var bold = false;
var styles = [];
var output_color = '';
var output_background = '';
var _8bit_color = false;
var _8bit_background = false;
var process_8bit = false;
var palette = $.terminal.ansi_colors.palette;
function set_styles(num) {
switch (num) {
case 1:
styles.push('b');
bold = true;
faited = false;
break;
case 4:
styles.push('u');
break;
case 3:
styles.push('i');
break;
case 5:
process_8bit = true;
break;
case 38:
_8bit_color = true;
break;
case 48:
_8bit_background = true;
break;
case 2:
faited = true;
bold = false;
break;
case 7:
reverse = true;
break;
default:
if (controls.indexOf('5') === -1) {
if (color_list[num]) {
output_color = color_list[num];
}
if (background_list[num]) {
output_background = background_list[num];
}
}
}
}
for (var i in controls) {
if (controls.hasOwnProperty(i)) {
num = parseInt(controls[i], 10);
if (process_8bit && (_8bit_background || _8bit_color)) {
if (_8bit_color && palette[num]) {
output_color = palette[num];
}
if (_8bit_background && palette[num]) {
output_background = palette[num];
}
} else {
set_styles(num);
}
}
}
if (reverse) {
if (output_color || output_background) {
var tmp = output_background;
output_background = output_color;
output_color = tmp;
} else {
output_color = 'black';
output_background = 'white';
}
}
var colors, color, background, backgrounds;
if (bold) {
colors = backgrounds = $.terminal.ansi_colors.bold;
} else if (faited) {
colors = backgrounds = $.terminal.ansi_colors.faited;
} else {
colors = backgrounds = $.terminal.ansi_colors.normal;
}
if (_8bit_color) {
color = output_color;
} else if (output_color === 'inherit') {
color = output_color;
} else {
color = colors[output_color];
}
if (_8bit_background) {
background = output_background;
} else if (output_background === 'transparent') {
background = output_background;
} else {
background = backgrounds[output_background];
}
return [styles.join(''), color, background];
}
return function(input) {
//merge multiple codes
/*input = input.replace(/((?:\x1B\[[0-9;]*[A-Za-z])*)/g, function(group) {
return group.replace(/m\x1B\[/g, ';');
});*/
var splitted = input.split(/(\x1B\[[0-9;]*[A-Za-z])/g);
if (splitted.length === 1) {
return input;
}
var output = [];
//skip closing at the begining
if (splitted.length > 3) {
var str = splitted.slice(0, 3).join('');
if (str.match(/^\[0*m$/)) {
splitted = splitted.slice(3);
}
}
var prev_color, prev_background, code, match;
var inside = false;
for (var i = 0; i < splitted.length; ++i) {
match = splitted[i].match(/^\x1B\[([0-9;]*)([A-Za-z])$/);
if (match) {
switch (match[2]) {
case 'm':
if (+match[1] !== 0) {
code = format_ansi(match[1]);
}
if (inside) {
output.push(']');
if (+match[1] === 0) {
//just closing
inside = false;
prev_color = prev_background = '';
} else {
// someone forget to close - move to next
code[1] = code[1] || prev_color;
code[2] = code[2] || prev_background;
output.push('[[' + code.join(';') + ']');
// store colors to next use
if (code[1]) {
prev_color = code[1];
}
if (code[2]) {
prev_background = code[2];
}
}
} else if (+match[1] !== 0) {
inside = true;
code[1] = code[1] || prev_color;
code[2] = code[2] || prev_background;
output.push('[[' + code.join(';') + ']');
// store colors to next use
if (code[1]) {
prev_color = code[1];
}
if (code[2]) {
prev_background = code[2];
}
}
break;
}
} else {
output.push(splitted[i]);
}
}
if (inside) {
output.push(']');
}
return output.join(''); //.replace(/\[\[[^\]]+\]\]/g, '');
};
})();
$.terminal.defaults.formatters.push($.terminal.overtyping);
$.terminal.defaults.formatters.push($.terminal.from_ansi);
})(jQuery);

View File

@ -177,7 +177,7 @@
</footer>
</div>
@section('footer-scripts')
{!! Theme::js('vendor/terminal/keyboard.polyfill.js') !!}
{!! Theme::js('js/keyboard.polyfill.js') !!}
<script>keyboardeventKeyPolyfill.polyfill();</script>
{!! Theme::js('js/laroute.js') !!}
@ -186,7 +186,7 @@
{!! Theme::js('vendor/bootstrap/bootstrap.min.js') !!}
{!! Theme::js('vendor/slimscroll/jquery.slimscroll.min.js') !!}
{!! Theme::js('vendor/adminlte/app.min.js') !!}
{!! Theme::js('vendor/socketio/socket.io.min.js') !!}
{!! Theme::js('vendor/socketio/socket.io.v203.min.js') !!}
{!! Theme::js('vendor/bootstrap-notify/bootstrap-notify.min.js') !!}
{!! Theme::js('vendor/select2/select2.full.min.js') !!}
{!! Theme::js('js/admin/functions.js') !!}

View File

@ -268,7 +268,7 @@
<div class="control-sidebar-bg"></div>
</div>
@section('footer-scripts')
{!! Theme::js('vendor/terminal/keyboard.polyfill.js') !!}
{!! Theme::js('js/keyboard.polyfill.js') !!}
<script>keyboardeventKeyPolyfill.polyfill();</script>
{!! Theme::js('js/laroute.js') !!}
@ -277,7 +277,7 @@
{!! Theme::js('vendor/bootstrap/bootstrap.min.js') !!}
{!! Theme::js('vendor/slimscroll/jquery.slimscroll.min.js') !!}
{!! Theme::js('vendor/adminlte/app.min.js') !!}
{!! Theme::js('vendor/socketio/socket.io.min.js') !!}
{!! Theme::js('vendor/socketio/socket.io.v203.min.js') !!}
{!! Theme::js('vendor/bootstrap-notify/bootstrap-notify.min.js') !!}
{!! Theme::js('js/autocomplete.js') !!}
@if(config('pterodactyl.lang.in_context'))

View File

@ -22,28 +22,38 @@
<head>
<title>{{ Settings::get('company', 'Pterodactyl') }} - Console &rarr; {{ $server->name }}</title>
@include('layouts.scripts')
{!! Theme::css('vendor/terminal/jquery.terminal.css') !!}
{!! Theme::css('vendor/bootstrap/bootstrap.min.css') !!}
{!! Theme::css('css/terminal.css') !!}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body style="margin:0;width:100%;height:100%;">
<div id="terminal" style="width:100%"></div>
<body id="terminal-body">
<div id="terminal" style="width:100%;max-height: none !important;"></div>
<div id="terminal_input" class="form-group no-margin">
<div class="input-group">
<div class="input-group-addon terminal_input--prompt">{{ $server->username }}:~$</div>
<input type="text" class="form-control terminal_input--input">
</div>
</div>
<div id="terminalNotify" class="terminal-notify hidden">
<i class="fa fa-bell"></i>
</div>
</body>
<script>window.SkipConsoleCharts = true</script>
{!! Theme::js('js/laroute.js') !!}
{!! Theme::js('vendor/ansi/ansi_up.js') !!}
{!! Theme::js('vendor/jquery/jquery.min.js') !!}
{!! Theme::js('vendor/socketio/socket.io.min.js') !!}
{!! Theme::js('vendor/socketio/socket.io.v203.min.js') !!}
{!! Theme::js('vendor/bootstrap-notify/bootstrap-notify.min.js') !!}
{!! Theme::js('js/frontend/server.socket.js') !!}
{!! Theme::js('vendor/mousewheel/jquery.mousewheel-min.js') !!}
{!! Theme::js('vendor/terminal/jquery.terminal.min.js') !!}
{!! Theme::js('vendor/terminal/unix_formatting.js') !!}
{!! Theme::js('js/frontend/console.js') !!}
<script>
Terminal.resize($(window).innerWidth() - 20, $(window).innerHeight() - 20);
$terminal.height($(window).innerHeight() - 40);
$terminal.width($(window).innerWidth());
$(window).on('resize', function () {
Terminal.resize($(window).innerWidth() - 20, $(window).innerHeight() - 20);
window.scrollToBottom();
$terminal.height($(window).innerHeight() - 40);
$terminal.width($(window).innerWidth());
});
</script>
</html>

View File

@ -25,7 +25,7 @@
@section('scripts')
@parent
{!! Theme::css('vendor/terminal/jquery.terminal.css') !!}
{!! Theme::css('css/terminal.css') !!}
@endsection
@section('content-header')
@ -42,6 +42,12 @@
<div class="box">
<div class="box-body position-relative">
<div id="terminal" style="width:100%;"></div>
<div id="terminal_input" class="form-group no-margin">
<div class="input-group">
<div class="input-group-addon terminal_input--prompt">{{ $server->username }}:~$</div>
<input type="text" class="form-control terminal_input--input">
</div>
</div>
<div id="terminalNotify" class="terminal-notify hidden">
<i class="fa fa-bell"></i>
</div>
@ -81,10 +87,9 @@
@section('footer-scripts')
@parent
{!! Theme::js('vendor/ansi/ansi_up.js') !!}
{!! Theme::js('js/frontend/server.socket.js') !!}
{!! Theme::js('vendor/mousewheel/jquery.mousewheel-min.js') !!}
{!! Theme::js('vendor/terminal/jquery.terminal.min.js') !!}
{!! Theme::js('vendor/terminal/unix_formatting.js') !!}
{!! Theme::js('js/frontend/console.js') !!}
{!! Theme::js('vendor/chartjs/chart.min.js') !!}
{!! Theme::js('vendor/jquery/date-format.min.js') !!}