Update all places in the code referencing named routes using JS that doesn't exist now
This commit is contained in:
parent
14b1f13fe0
commit
447c4291ad
20 changed files with 12 additions and 2115 deletions
|
@ -39,7 +39,7 @@ $(document).ready(function() {
|
|||
|
||||
$('#pUserId').select2({
|
||||
ajax: {
|
||||
url: Router.route('admin.users.json'),
|
||||
url: '/admin/users/accounts.json',
|
||||
dataType: 'json',
|
||||
delay: 250,
|
||||
data: function (params) {
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// 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 TwoFactorModal = (function () {
|
||||
|
||||
function bindListeners() {
|
||||
$(document).ready(function () {
|
||||
$('#close_reload').click(function () {
|
||||
location.reload();
|
||||
});
|
||||
$('#do_2fa').submit(function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
$.ajax({
|
||||
type: 'PUT',
|
||||
url: Router.route('account.security.totp'),
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
||||
}
|
||||
}).done(function (data) {
|
||||
var image = new Image();
|
||||
image.src = data.qrImage;
|
||||
$(image).on('load', function () {
|
||||
$('#hide_img_load').slideUp(function () {
|
||||
$('#qr_image_insert').attr('src', image.src).slideDown();
|
||||
});
|
||||
});
|
||||
$('#open2fa').modal('show');
|
||||
}).fail(function (jqXHR) {
|
||||
alert('An error occurred while attempting to load the 2FA setup modal. Please try again.');
|
||||
console.error(jqXHR);
|
||||
});
|
||||
|
||||
});
|
||||
$('#2fa_token_verify').submit(function (event) {
|
||||
event.preventDefault();
|
||||
$('#submit_action').html('<i class="fa fa-spinner fa-spin"></i> Submit').addClass('disabled');
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Router.route('account.security.totp'),
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
||||
},
|
||||
data: {
|
||||
token: $('#2fa_token').val()
|
||||
}
|
||||
}).done(function (data) {
|
||||
$('#notice_box_2fa').hide();
|
||||
if (data === 'true') {
|
||||
$('#notice_box_2fa').html('<div class="alert alert-success">2-Factor Authentication has been enabled on your account. Press \'Close\' below to reload the page.</div>').slideDown();
|
||||
} else {
|
||||
$('#notice_box_2fa').html('<div class="alert alert-danger">The token provided was invalid.</div>').slideDown();
|
||||
}
|
||||
}).fail(function (jqXHR) {
|
||||
$('#notice_box_2fa').html('<div class="alert alert-danger">There was an error while attempting to enable 2-Factor Authentication on this account.</div>').slideDown();
|
||||
console.error(jqXHR);
|
||||
}).always(function () {
|
||||
$('#submit_action').html('Submit').removeClass('disabled');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
init: function () {
|
||||
bindListeners();
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
TwoFactorModal.init();
|
|
@ -1,392 +0,0 @@
|
|||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// 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 || 50;
|
||||
var CONSOLE_PUSH_FREQ = Pterodactyl.config.console_freq || 200;
|
||||
var CONSOLE_OUTPUT_LIMIT = Pterodactyl.config.console_limit || 2000;
|
||||
|
||||
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, #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 state', $(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 (isTerminalScrolledDown()) {
|
||||
$scrollNotify.addClass('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
function isTerminalScrolledDown() {
|
||||
return $terminal.scrollTop() + $terminal.innerHeight() + 50 > $terminal[0].scrollHeight;
|
||||
}
|
||||
|
||||
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.ConsoleElements = 0;
|
||||
|
||||
$scrollNotify.on('click', function () {
|
||||
window.scrollToBottom();
|
||||
$scrollNotify.addClass('hidden');
|
||||
});
|
||||
})();
|
||||
|
||||
(function pushOutputQueue() {
|
||||
if (TerminalQueue.length > CONSOLE_PUSH_COUNT) {
|
||||
// console throttled warning show
|
||||
}
|
||||
|
||||
if (TerminalQueue.length > 0) {
|
||||
var scrolledDown = isTerminalScrolledDown();
|
||||
|
||||
for (var i = 0; i < CONSOLE_PUSH_COUNT && TerminalQueue.length > 0; i++) {
|
||||
pushToTerminal(TerminalQueue[0]);
|
||||
|
||||
window.ConsoleElements++;
|
||||
TerminalQueue.shift();
|
||||
}
|
||||
|
||||
if (scrolledDown) {
|
||||
window.scrollToBottom();
|
||||
} else if ($scrollNotify.hasClass('hidden')) {
|
||||
$scrollNotify.removeClass('hidden');
|
||||
}
|
||||
|
||||
var removeElements = window.ConsoleElements - CONSOLE_OUTPUT_LIMIT;
|
||||
if (removeElements > 0) {
|
||||
$('#terminal').find('.cmd').slice(0, removeElements).remove();
|
||||
window.ConsoleElements = window.ConsoleElements - removeElements;
|
||||
}
|
||||
}
|
||||
|
||||
window.setTimeout(pushOutputQueue, CONSOLE_PUSH_FREQ);
|
||||
})();
|
||||
|
||||
(function setupSocketListeners() {
|
||||
// Update Listings on Initial Status
|
||||
Socket.on('initial status', function (data) {
|
||||
ConsoleServerStatus = data.status;
|
||||
updateServerPowerControls(data.status);
|
||||
|
||||
if (data.status === 1 || data.status === 2) {
|
||||
Socket.emit('send server log');
|
||||
}
|
||||
});
|
||||
|
||||
// Update Listings on Status
|
||||
Socket.on('status', function (data) {
|
||||
ConsoleServerStatus = data.status;
|
||||
updateServerPowerControls(data.status);
|
||||
});
|
||||
|
||||
// Skips the queue so we don't wait
|
||||
// 10 minutes to load the log...
|
||||
Socket.on('server log', function (data) {
|
||||
$('#terminal').html('');
|
||||
data.split(/\n/g).forEach(function (item) {
|
||||
pushToTerminal(item);
|
||||
});
|
||||
window.scrollToBottom();
|
||||
});
|
||||
|
||||
Socket.on('console', function (data) {
|
||||
if(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) {
|
||||
$('[data-attr="power"][data-action="start"]').addClass('disabled');
|
||||
$('[data-attr="power"][data-action="stop"], [data-attr="power"][data-action="restart"]').removeClass('disabled');
|
||||
} else {
|
||||
if (data == 0) {
|
||||
$('[data-attr="power"][data-action="start"]').removeClass('disabled');
|
||||
}
|
||||
$('[data-attr="power"][data-action="stop"], [data-attr="power"][data-action="restart"]').addClass('disabled');
|
||||
}
|
||||
|
||||
if(data !== 0) {
|
||||
$('[data-attr="power"][data-action="kill"]').removeClass('disabled');
|
||||
} else {
|
||||
$('[data-attr="power"][data-action="kill"]').addClass('disabled');
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
$('[data-attr="power"]').click(function (event) {
|
||||
if (! $(this).hasClass('disabled')) {
|
||||
Socket.emit('set state', $(this).data('action'));
|
||||
}
|
||||
});
|
||||
|
||||
(function setupChartElements() {
|
||||
if (typeof SkipConsoleCharts !== 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
Socket.on('proc', function (proc) {
|
||||
if (CPUData.length > 10) {
|
||||
CPUData.shift();
|
||||
MemoryData.shift();
|
||||
TimeLabels.shift();
|
||||
}
|
||||
|
||||
var cpuUse = (Pterodactyl.server.cpu > 0) ? parseFloat(((proc.data.cpu.total / Pterodactyl.server.cpu) * 100).toFixed(3).toString()) : proc.data.cpu.total;
|
||||
CPUData.push(cpuUse);
|
||||
MemoryData.push(parseInt(proc.data.memory.total / (1024 * 1024)));
|
||||
|
||||
TimeLabels.push($.format.date(new Date(), 'HH:mm:ss'));
|
||||
|
||||
|
||||
// memory.cmax is the maximum given by the container
|
||||
// memory.amax is given by the json config
|
||||
// use the maximum of both
|
||||
// with no limit memory.cmax will always be higher
|
||||
// but with limit memory.amax is sometimes still smaller than memory.total
|
||||
MemoryChart.config.options.scales.yAxes[0].ticks.max = Math.max(proc.data.memory.cmax, proc.data.memory.amax) / (1000 * 1000);
|
||||
|
||||
if (Pterodactyl.server.cpu > 0) {
|
||||
// if there is a cpu limit defined use 100% as maximum
|
||||
CPUChart.config.options.scales.yAxes[0].ticks.max = 100;
|
||||
} else {
|
||||
// if there is no cpu limit defined use linux percentage
|
||||
// and find maximum in all values
|
||||
var maxCpu = 1;
|
||||
for(var i = 0; i < CPUData.length; i++) {
|
||||
maxCpu = Math.max(maxCpu, parseFloat(CPUData[i]))
|
||||
}
|
||||
|
||||
maxCpu = Math.ceil(maxCpu / 100) * 100;
|
||||
CPUChart.config.options.scales.yAxes[0].ticks.max = maxCpu;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CPUChart.update();
|
||||
MemoryChart.update();
|
||||
});
|
||||
|
||||
var ctc = $('#chart_cpu');
|
||||
var TimeLabels = [];
|
||||
var CPUData = [];
|
||||
var CPUChart = new Chart(ctc, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: TimeLabels,
|
||||
datasets: [
|
||||
{
|
||||
label: "Percent Use",
|
||||
fill: false,
|
||||
lineTension: 0.03,
|
||||
backgroundColor: "#3c8dbc",
|
||||
borderColor: "#3c8dbc",
|
||||
borderCapStyle: 'butt',
|
||||
borderDash: [],
|
||||
borderDashOffset: 0.0,
|
||||
borderJoinStyle: 'miter',
|
||||
pointBorderColor: "#3c8dbc",
|
||||
pointBackgroundColor: "#fff",
|
||||
pointBorderWidth: 1,
|
||||
pointHoverRadius: 5,
|
||||
pointHoverBackgroundColor: "#3c8dbc",
|
||||
pointHoverBorderColor: "rgba(220,220,220,1)",
|
||||
pointHoverBorderWidth: 2,
|
||||
pointRadius: 1,
|
||||
pointHitRadius: 10,
|
||||
data: CPUData,
|
||||
spanGaps: false,
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'CPU Usage (as Percent Total)'
|
||||
},
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
animation: {
|
||||
duration: 1,
|
||||
},
|
||||
scales: {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var ctm = $('#chart_memory');
|
||||
MemoryData = [];
|
||||
MemoryChart = new Chart(ctm, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: TimeLabels,
|
||||
datasets: [
|
||||
{
|
||||
label: "Memory Use",
|
||||
fill: false,
|
||||
lineTension: 0.03,
|
||||
backgroundColor: "#3c8dbc",
|
||||
borderColor: "#3c8dbc",
|
||||
borderCapStyle: 'butt',
|
||||
borderDash: [],
|
||||
borderDashOffset: 0.0,
|
||||
borderJoinStyle: 'miter',
|
||||
pointBorderColor: "#3c8dbc",
|
||||
pointBackgroundColor: "#fff",
|
||||
pointBorderWidth: 1,
|
||||
pointHoverRadius: 5,
|
||||
pointHoverBackgroundColor: "#3c8dbc",
|
||||
pointHoverBorderColor: "rgba(220,220,220,1)",
|
||||
pointHoverBorderWidth: 2,
|
||||
pointRadius: 1,
|
||||
pointHitRadius: 10,
|
||||
data: MemoryData,
|
||||
spanGaps: false,
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Memory Usage (in Megabytes)'
|
||||
},
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
animation: {
|
||||
duration: 1,
|
||||
},
|
||||
scales: {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
});
|
|
@ -1,131 +0,0 @@
|
|||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// 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.
|
||||
(function () {
|
||||
window.Editor = ace.edit('editor');
|
||||
var Whitespace = ace.require('ace/ext/whitespace');
|
||||
var Modelist = ace.require('ace/ext/modelist');
|
||||
|
||||
Editor.setTheme('ace/theme/chrome');
|
||||
Editor.getSession().setUseWrapMode(true);
|
||||
Editor.setShowPrintMargin(false);
|
||||
|
||||
if (typeof Pterodactyl !== 'undefined') {
|
||||
if(typeof Pterodactyl.stat !== 'undefined') {
|
||||
Editor.getSession().setMode(Modelist.getModeForPath(Pterodactyl.stat.name).mode);
|
||||
}
|
||||
}
|
||||
|
||||
Editor.commands.addCommand({
|
||||
name: 'save',
|
||||
bindKey: {win: 'Ctrl-S', mac: 'Command-S'},
|
||||
exec: function(editor) {
|
||||
if ($('#save_file').length) {
|
||||
save();
|
||||
} else if ($('#create_file').length) {
|
||||
create();
|
||||
}
|
||||
},
|
||||
readOnly: false
|
||||
});
|
||||
|
||||
Editor.commands.addCommands(Whitespace.commands);
|
||||
|
||||
Whitespace.detectIndentation(Editor.session);
|
||||
|
||||
$('#save_file').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
save();
|
||||
});
|
||||
|
||||
$('#create_file').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
create();
|
||||
});
|
||||
|
||||
$('#aceMode').on('change', event => {
|
||||
Editor.getSession().setMode('ace/mode/' + $('#aceMode').val());
|
||||
});
|
||||
|
||||
function create() {
|
||||
if (_.isEmpty($('#file_name').val())) {
|
||||
$.notify({
|
||||
message: 'No filename was passed.'
|
||||
}, {
|
||||
type: 'danger'
|
||||
});
|
||||
return;
|
||||
}
|
||||
$('#create_file').html('<i class="fa fa-spinner fa fa-spin"></i> Creating File').addClass('disabled');
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Router.route('server.files.save', { server: Pterodactyl.server.uuidShort }),
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
||||
},
|
||||
data: {
|
||||
file: $('#file_name').val(),
|
||||
contents: Editor.getValue()
|
||||
}
|
||||
}).done(function (data) {
|
||||
window.location.replace(Router.route('server.files.edit', {
|
||||
server: Pterodactyl.server.uuidShort,
|
||||
file: $('#file_name').val(),
|
||||
}));
|
||||
}).fail(function (jqXHR) {
|
||||
$.notify({
|
||||
message: jqXHR.responseText
|
||||
}, {
|
||||
type: 'danger'
|
||||
});
|
||||
}).always(function () {
|
||||
$('#create_file').html('Create File').removeClass('disabled');
|
||||
});
|
||||
}
|
||||
|
||||
function save() {
|
||||
var fileName = $('input[name="file"]').val();
|
||||
$('#save_file').html('<i class="fa fw-fw fa-spinner fa-spin"></i> Saving File').addClass('disabled');
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Router.route('server.files.save', { server: Pterodactyl.server.uuidShort }),
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
||||
},
|
||||
data: {
|
||||
file: fileName,
|
||||
contents: Editor.getValue()
|
||||
}
|
||||
}).done(function (data) {
|
||||
$.notify({
|
||||
message: 'File was successfully saved.'
|
||||
}, {
|
||||
type: 'success'
|
||||
});
|
||||
}).fail(function (jqXHR) {
|
||||
$.notify({
|
||||
message: jqXHR.responseText
|
||||
}, {
|
||||
type: 'danger'
|
||||
});
|
||||
}).always(function () {
|
||||
$('#save_file').html('<i class="fa fa-fw fa-save"></i> Save File').removeClass('disabled');
|
||||
});
|
||||
}
|
||||
})();
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,549 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// 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.
|
||||
class ActionsClass {
|
||||
constructor(element, menu) {
|
||||
this.element = element;
|
||||
this.menu = menu;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.element = undefined;
|
||||
}
|
||||
|
||||
sanitizedString(value) {
|
||||
return $('<div>').text(value).html();
|
||||
}
|
||||
|
||||
folder(path) {
|
||||
let inputValue
|
||||
if (path) {
|
||||
inputValue = path
|
||||
} else {
|
||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
||||
const currentName = decodeURIComponent(nameBlock.data('name'));
|
||||
const currentPath = decodeURIComponent(nameBlock.data('path'));
|
||||
|
||||
if ($(this.element).data('type') === 'file') {
|
||||
inputValue = currentPath;
|
||||
} else {
|
||||
inputValue = `${currentPath}${currentName}/`;
|
||||
}
|
||||
}
|
||||
|
||||
swal({
|
||||
type: 'input',
|
||||
title: 'Create Folder',
|
||||
text: 'Please enter the path and folder name below.',
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
closeOnConfirm: false,
|
||||
showLoaderOnConfirm: true,
|
||||
inputValue: inputValue
|
||||
}, (val) => {
|
||||
if (val === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
headers: {
|
||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
||||
'X-Access-Server': Pterodactyl.server.uuid,
|
||||
},
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/folder`,
|
||||
timeout: 10000,
|
||||
data: JSON.stringify({
|
||||
path: val,
|
||||
}),
|
||||
}).done(data => {
|
||||
swal.close();
|
||||
Files.list();
|
||||
}).fail(jqXHR => {
|
||||
console.error(jqXHR);
|
||||
var error = 'An error occurred while trying to process this request.';
|
||||
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
|
||||
error = jqXHR.responseJSON.error;
|
||||
}
|
||||
swal({
|
||||
type: 'error',
|
||||
title: '',
|
||||
text: error,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
move() {
|
||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
||||
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
|
||||
const currentPath = decodeURIComponent(nameBlock.data('path'));
|
||||
|
||||
swal({
|
||||
type: 'input',
|
||||
title: 'Move File',
|
||||
text: 'Please enter the new path for the file below.',
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
closeOnConfirm: false,
|
||||
showLoaderOnConfirm: true,
|
||||
inputValue: `${currentPath}${currentName}`,
|
||||
}, (val) => {
|
||||
if (val === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
headers: {
|
||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
||||
'X-Access-Server': Pterodactyl.server.uuid,
|
||||
},
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/move`,
|
||||
timeout: 10000,
|
||||
data: JSON.stringify({
|
||||
from: `${currentPath}${currentName}`,
|
||||
to: `${val}`,
|
||||
}),
|
||||
}).done(data => {
|
||||
nameBlock.parent().addClass('warning').delay(200).fadeOut();
|
||||
swal.close();
|
||||
}).fail(jqXHR => {
|
||||
console.error(jqXHR);
|
||||
var error = 'An error occurred while trying to process this request.';
|
||||
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
|
||||
error = jqXHR.responseJSON.error;
|
||||
}
|
||||
swal({
|
||||
type: 'error',
|
||||
title: '',
|
||||
text: error,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
rename() {
|
||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
||||
const currentLink = nameBlock.find('a');
|
||||
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
|
||||
const attachEditor = `
|
||||
<input class="form-control input-sm" type="text" value="${currentName}" />
|
||||
<span class="input-loader"><i class="fa fa-refresh fa-spin fa-fw"></i></span>
|
||||
`;
|
||||
|
||||
nameBlock.html(attachEditor);
|
||||
const inputField = nameBlock.find('input');
|
||||
const inputLoader = nameBlock.find('.input-loader');
|
||||
|
||||
inputField.focus();
|
||||
inputField.on('blur keydown', e => {
|
||||
// Save Field
|
||||
if (
|
||||
(e.type === 'keydown' && e.which === 27)
|
||||
|| e.type === 'blur'
|
||||
|| (e.type === 'keydown' && e.which === 13 && currentName === inputField.val())
|
||||
) {
|
||||
if (!_.isEmpty(currentLink)) {
|
||||
nameBlock.html(currentLink);
|
||||
} else {
|
||||
nameBlock.html(currentName);
|
||||
}
|
||||
inputField.remove();
|
||||
ContextMenu.unbind().run();
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.type === 'keydown' && e.which !== 13) return;
|
||||
|
||||
inputLoader.show();
|
||||
const currentPath = decodeURIComponent(nameBlock.data('path'));
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
headers: {
|
||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
||||
'X-Access-Server': Pterodactyl.server.uuid,
|
||||
},
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/rename`,
|
||||
timeout: 10000,
|
||||
data: JSON.stringify({
|
||||
from: `${currentPath}${currentName}`,
|
||||
to: `${currentPath}${inputField.val()}`,
|
||||
}),
|
||||
}).done(data => {
|
||||
nameBlock.attr('data-name', inputField.val());
|
||||
if (!_.isEmpty(currentLink)) {
|
||||
let newLink = currentLink.attr('href');
|
||||
if (nameBlock.parent().data('type') !== 'folder') {
|
||||
newLink = newLink.substr(0, newLink.lastIndexOf('/')) + '/' + inputField.val();
|
||||
}
|
||||
currentLink.attr('href', newLink);
|
||||
nameBlock.html(
|
||||
currentLink.html(inputField.val())
|
||||
);
|
||||
} else {
|
||||
nameBlock.html(inputField.val());
|
||||
}
|
||||
inputField.remove();
|
||||
}).fail(jqXHR => {
|
||||
console.error(jqXHR);
|
||||
var error = 'An error occurred while trying to process this request.';
|
||||
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
|
||||
error = jqXHR.responseJSON.error;
|
||||
}
|
||||
nameBlock.addClass('has-error').delay(2000).queue(() => {
|
||||
nameBlock.removeClass('has-error').dequeue();
|
||||
});
|
||||
inputField.popover({
|
||||
animation: true,
|
||||
placement: 'top',
|
||||
content: error,
|
||||
title: 'Save Error'
|
||||
}).popover('show');
|
||||
}).always(() => {
|
||||
inputLoader.remove();
|
||||
ContextMenu.unbind().run();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
copy() {
|
||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
||||
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
|
||||
const currentPath = decodeURIComponent(nameBlock.data('path'));
|
||||
|
||||
swal({
|
||||
type: 'input',
|
||||
title: 'Copy File',
|
||||
text: 'Please enter the new path for the copied file below.',
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
closeOnConfirm: false,
|
||||
showLoaderOnConfirm: true,
|
||||
inputValue: `${currentPath}${currentName}`,
|
||||
}, (val) => {
|
||||
if (val === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
headers: {
|
||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
||||
'X-Access-Server': Pterodactyl.server.uuid,
|
||||
},
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/copy`,
|
||||
timeout: 10000,
|
||||
data: JSON.stringify({
|
||||
from: `${currentPath}${currentName}`,
|
||||
to: `${val}`,
|
||||
}),
|
||||
}).done(data => {
|
||||
swal({
|
||||
type: 'success',
|
||||
title: '',
|
||||
text: 'File successfully copied.'
|
||||
});
|
||||
Files.list();
|
||||
}).fail(jqXHR => {
|
||||
console.error(jqXHR);
|
||||
var error = 'An error occurred while trying to process this request.';
|
||||
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
|
||||
error = jqXHR.responseJSON.error;
|
||||
}
|
||||
swal({
|
||||
type: 'error',
|
||||
title: '',
|
||||
text: error,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
download() {
|
||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
||||
const fileName = decodeURIComponent(nameBlock.attr('data-name'));
|
||||
const filePath = decodeURIComponent(nameBlock.data('path'));
|
||||
|
||||
window.location = `/server/${Pterodactyl.server.uuidShort}/files/download/${filePath}${fileName}`;
|
||||
}
|
||||
|
||||
delete() {
|
||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
||||
const delPath = decodeURIComponent(nameBlock.data('path'));
|
||||
const delName = decodeURIComponent(nameBlock.data('name'));
|
||||
|
||||
swal({
|
||||
type: 'warning',
|
||||
title: '',
|
||||
text: 'Are you sure you want to delete <code>' + this.sanitizedString(delName) + '</code>?',
|
||||
html: true,
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
closeOnConfirm: false,
|
||||
showLoaderOnConfirm: true
|
||||
}, () => {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
headers: {
|
||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
||||
'X-Access-Server': Pterodactyl.server.uuid,
|
||||
},
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/delete`,
|
||||
timeout: 10000,
|
||||
data: JSON.stringify({
|
||||
items: [`${delPath}${delName}`]
|
||||
}),
|
||||
}).done(data => {
|
||||
nameBlock.parent().addClass('warning').delay(200).fadeOut();
|
||||
swal({
|
||||
type: 'success',
|
||||
title: 'File Deleted'
|
||||
});
|
||||
}).fail(jqXHR => {
|
||||
console.error(jqXHR);
|
||||
swal({
|
||||
type: 'error',
|
||||
title: 'Whoops!',
|
||||
html: true,
|
||||
text: 'An error occurred while attempting to delete this file. Please try again.',
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
toggleMassActions() {
|
||||
if ($('#file_listing input[type="checkbox"]:checked').length) {
|
||||
$('#mass_actions').removeClass('disabled');
|
||||
} else {
|
||||
$('#mass_actions').addClass('disabled');
|
||||
}
|
||||
}
|
||||
|
||||
toggleHighlight(event) {
|
||||
const parent = $(event.currentTarget);
|
||||
const item = $(event.currentTarget).find('input');
|
||||
|
||||
if($(item).is(':checked')) {
|
||||
$(item).prop('checked', false);
|
||||
parent.removeClass('warning').delay(200);
|
||||
} else {
|
||||
$(item).prop('checked', true);
|
||||
parent.addClass('warning').delay(200);
|
||||
}
|
||||
}
|
||||
|
||||
highlightAll(event) {
|
||||
let parent;
|
||||
const item = $(event.currentTarget).find('input');
|
||||
|
||||
if($(item).is(':checked')) {
|
||||
$('#file_listing input[type=checkbox]').prop('checked', false);
|
||||
$('#file_listing input[data-action="addSelection"]').each(function() {
|
||||
parent = $(this).closest('tr');
|
||||
parent.removeClass('warning').delay(200);
|
||||
});
|
||||
} else {
|
||||
$('#file_listing input[type=checkbox]').prop('checked', true);
|
||||
$('#file_listing input[data-action="addSelection"]').each(function() {
|
||||
parent = $(this).closest('tr');
|
||||
parent.addClass('warning').delay(200);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
deleteSelected() {
|
||||
let selectedItems = [];
|
||||
let selectedItemsElements = [];
|
||||
let parent;
|
||||
let nameBlock;
|
||||
let delLocation;
|
||||
|
||||
$('#file_listing input[data-action="addSelection"]:checked').each(function() {
|
||||
parent = $(this).closest('tr');
|
||||
nameBlock = $(parent).find('td[data-identifier="name"]');
|
||||
delLocation = decodeURIComponent(nameBlock.data('path')) + decodeURIComponent(nameBlock.data('name'));
|
||||
|
||||
selectedItems.push(delLocation);
|
||||
selectedItemsElements.push(parent);
|
||||
});
|
||||
|
||||
if (selectedItems.length != 0)
|
||||
{
|
||||
let formattedItems = "";
|
||||
let i = 0;
|
||||
let self = this;
|
||||
|
||||
$.each(selectedItems, function(key, value) {
|
||||
formattedItems += ("<code>" + self.sanitizedString(value) + "</code>, ");
|
||||
i++;
|
||||
return i < 5;
|
||||
});
|
||||
|
||||
formattedItems = formattedItems.slice(0, -2);
|
||||
if (selectedItems.length > 5) {
|
||||
formattedItems += ', and ' + (selectedItems.length - 5) + ' other(s)';
|
||||
}
|
||||
|
||||
swal({
|
||||
type: 'warning',
|
||||
title: '',
|
||||
text: 'Are you sure you want to delete the following files: ' + formattedItems + '?',
|
||||
html: true,
|
||||
showCancelButton: true,
|
||||
showConfirmButton: true,
|
||||
closeOnConfirm: false,
|
||||
showLoaderOnConfirm: true
|
||||
}, () => {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
headers: {
|
||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
||||
'X-Access-Server': Pterodactyl.server.uuid,
|
||||
},
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/delete`,
|
||||
timeout: 10000,
|
||||
data: JSON.stringify({
|
||||
items: selectedItems
|
||||
}),
|
||||
}).done(data => {
|
||||
$('#file_listing input:checked').each(function() {
|
||||
$(this).prop('checked', false);
|
||||
});
|
||||
|
||||
$.each(selectedItemsElements, function() {
|
||||
$(this).addClass('warning').delay(200).fadeOut();
|
||||
})
|
||||
|
||||
swal({
|
||||
type: 'success',
|
||||
title: 'Files Deleted'
|
||||
});
|
||||
}).fail(jqXHR => {
|
||||
console.error(jqXHR);
|
||||
swal({
|
||||
type: 'error',
|
||||
title: 'Whoops!',
|
||||
html: true,
|
||||
text: 'An error occurred while attempting to delete these files. Please try again.',
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
swal({
|
||||
type: 'warning',
|
||||
title: '',
|
||||
text: 'Please select files/folders to delete.',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
decompress() {
|
||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
||||
const compPath = decodeURIComponent(nameBlock.data('path'));
|
||||
const compName = decodeURIComponent(nameBlock.data('name'));
|
||||
|
||||
swal({
|
||||
title: '<i class="fa fa-refresh fa-spin"></i> Decompressing...',
|
||||
text: 'This might take a few seconds to complete.',
|
||||
html: true,
|
||||
allowOutsideClick: false,
|
||||
allowEscapeKey: false,
|
||||
showConfirmButton: false,
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/decompress`,
|
||||
headers: {
|
||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
||||
'X-Access-Server': Pterodactyl.server.uuid,
|
||||
},
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
data: JSON.stringify({
|
||||
files: `${compPath}${compName}`
|
||||
})
|
||||
}).done(data => {
|
||||
swal.close();
|
||||
Files.list(compPath);
|
||||
}).fail(jqXHR => {
|
||||
console.error(jqXHR);
|
||||
var error = 'An error occurred while trying to process this request.';
|
||||
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
|
||||
error = jqXHR.responseJSON.error;
|
||||
}
|
||||
swal({
|
||||
type: 'error',
|
||||
title: 'Whoops!',
|
||||
html: true,
|
||||
text: error
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
compress() {
|
||||
const nameBlock = $(this.element).find('td[data-identifier="name"]');
|
||||
const compPath = decodeURIComponent(nameBlock.data('path'));
|
||||
const compName = decodeURIComponent(nameBlock.data('name'));
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: `${Pterodactyl.node.scheme}://${Pterodactyl.node.fqdn}:${Pterodactyl.node.daemonListen}/v1/server/file/compress`,
|
||||
headers: {
|
||||
'X-Access-Token': Pterodactyl.server.daemonSecret,
|
||||
'X-Access-Server': Pterodactyl.server.uuid,
|
||||
},
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
data: JSON.stringify({
|
||||
files: `${compPath}${compName}`,
|
||||
to: compPath.toString()
|
||||
})
|
||||
}).done(data => {
|
||||
Files.list(compPath, err => {
|
||||
if (err) return;
|
||||
const fileListing = $('#file_listing').find(`[data-name="${data.saved_as}"]`).parent();
|
||||
fileListing.addClass('success pulsate').delay(3000).queue(() => {
|
||||
fileListing.removeClass('success pulsate').dequeue();
|
||||
});
|
||||
});
|
||||
}).fail(jqXHR => {
|
||||
console.error(jqXHR);
|
||||
var error = 'An error occurred while trying to process this request.';
|
||||
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
|
||||
error = jqXHR.responseJSON.error;
|
||||
}
|
||||
swal({
|
||||
type: 'error',
|
||||
title: 'Whoops!',
|
||||
html: true,
|
||||
text: this.sanitizedString(error)
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,203 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// 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.
|
||||
class ContextMenuClass {
|
||||
constructor() {
|
||||
this.activeLine = null;
|
||||
}
|
||||
|
||||
run() {
|
||||
this.directoryClick();
|
||||
this.rightClick();
|
||||
}
|
||||
|
||||
makeMenu(parent) {
|
||||
$(document).find('#fileOptionMenu').remove();
|
||||
if (!_.isNull(this.activeLine)) this.activeLine.removeClass('active');
|
||||
|
||||
let newFilePath = $('#file_listing').data('current-dir');
|
||||
if (parent.data('type') === 'folder') {
|
||||
const nameBlock = parent.find('td[data-identifier="name"]');
|
||||
const currentName = decodeURIComponent(nameBlock.attr('data-name'));
|
||||
const currentPath = decodeURIComponent(nameBlock.data('path'));
|
||||
newFilePath = `${currentPath}${currentName}`;
|
||||
}
|
||||
|
||||
let buildMenu = '<ul id="fileOptionMenu" class="dropdown-menu" role="menu" style="display:none" >';
|
||||
|
||||
if (Pterodactyl.permissions.moveFiles) {
|
||||
buildMenu += '<li data-action="rename"><a tabindex="-1" href="#"><i class="fa fa-fw fa-pencil-square-o"></i> Rename</a></li> \
|
||||
<li data-action="move"><a tabindex="-1" href="#"><i class="fa fa-fw fa-arrow-right"></i> Move</a></li>';
|
||||
}
|
||||
|
||||
if (Pterodactyl.permissions.copyFiles) {
|
||||
buildMenu += '<li data-action="copy"><a tabindex="-1" href="#"><i class="fa fa-fw fa-clone"></i> Copy</a></li>';
|
||||
}
|
||||
|
||||
if (Pterodactyl.permissions.compressFiles) {
|
||||
buildMenu += '<li data-action="compress" class="hidden"><a tabindex="-1" href="#"><i class="fa fa-fw fa-file-archive-o"></i> Compress</a></li>';
|
||||
}
|
||||
|
||||
if (Pterodactyl.permissions.decompressFiles) {
|
||||
buildMenu += '<li data-action="decompress" class="hidden"><a tabindex="-1" href="#"><i class="fa fa-fw fa-expand"></i> Decompress</a></li>';
|
||||
}
|
||||
|
||||
if (Pterodactyl.permissions.createFiles) {
|
||||
buildMenu += '<li class="divider"></li> \
|
||||
<li data-action="file"><a href="/server/'+ Pterodactyl.server.uuidShort +'/files/add/?dir=' + $('<div>').text(newFilePath).html() + '" class="text-muted"><i class="fa fa-fw fa-plus"></i> New File</a></li> \
|
||||
<li data-action="folder"><a tabindex="-1" href="#"><i class="fa fa-fw fa-folder"></i> New Folder</a></li>';
|
||||
}
|
||||
|
||||
if (Pterodactyl.permissions.downloadFiles || Pterodactyl.permissions.deleteFiles) {
|
||||
buildMenu += '<li class="divider"></li>';
|
||||
}
|
||||
|
||||
if (Pterodactyl.permissions.downloadFiles) {
|
||||
buildMenu += '<li data-action="download" class="hidden"><a tabindex="-1" href="#"><i class="fa fa-fw fa-download"></i> Download</a></li>';
|
||||
}
|
||||
|
||||
if (Pterodactyl.permissions.deleteFiles) {
|
||||
buildMenu += '<li data-action="delete" class="bg-danger"><a tabindex="-1" href="#"><i class="fa fa-fw fa-trash-o"></i> Delete</a></li>';
|
||||
}
|
||||
|
||||
buildMenu += '</ul>';
|
||||
return buildMenu;
|
||||
}
|
||||
|
||||
rightClick() {
|
||||
$('[data-action="toggleMenu"]').on('mousedown', event => {
|
||||
event.preventDefault();
|
||||
if ($(document).find('#fileOptionMenu').is(':visible')) {
|
||||
$('body').trigger('click');
|
||||
return;
|
||||
}
|
||||
this.showMenu(event);
|
||||
});
|
||||
$('#file_listing > tbody td').on('contextmenu', event => {
|
||||
this.showMenu(event);
|
||||
});
|
||||
}
|
||||
|
||||
showMenu(event) {
|
||||
const parent = $(event.target).closest('tr');
|
||||
const menu = $(this.makeMenu(parent));
|
||||
|
||||
if (parent.data('type') === 'disabled') return;
|
||||
event.preventDefault();
|
||||
|
||||
$(menu).appendTo('body');
|
||||
$(menu).data('invokedOn', $(event.target)).show().css({
|
||||
position: 'absolute',
|
||||
left: event.pageX - 150,
|
||||
top: event.pageY,
|
||||
});
|
||||
|
||||
this.activeLine = parent;
|
||||
this.activeLine.addClass('active');
|
||||
|
||||
// Handle Events
|
||||
const Actions = new ActionsClass(parent, menu);
|
||||
if (Pterodactyl.permissions.moveFiles) {
|
||||
$(menu).find('li[data-action="move"]').unbind().on('click', e => {
|
||||
e.preventDefault();
|
||||
Actions.move();
|
||||
});
|
||||
$(menu).find('li[data-action="rename"]').unbind().on('click', e => {
|
||||
e.preventDefault();
|
||||
Actions.rename();
|
||||
});
|
||||
}
|
||||
|
||||
if (Pterodactyl.permissions.copyFiles) {
|
||||
$(menu).find('li[data-action="copy"]').unbind().on('click', e => {
|
||||
e.preventDefault();
|
||||
Actions.copy();
|
||||
});
|
||||
}
|
||||
|
||||
if (Pterodactyl.permissions.compressFiles) {
|
||||
if (parent.data('type') === 'folder') {
|
||||
$(menu).find('li[data-action="compress"]').removeClass('hidden');
|
||||
}
|
||||
$(menu).find('li[data-action="compress"]').unbind().on('click', e => {
|
||||
e.preventDefault();
|
||||
Actions.compress();
|
||||
});
|
||||
}
|
||||
|
||||
if (Pterodactyl.permissions.decompressFiles) {
|
||||
if (_.without(['application/zip', 'application/gzip', 'application/x-gzip'], parent.data('mime')).length < 3) {
|
||||
$(menu).find('li[data-action="decompress"]').removeClass('hidden');
|
||||
}
|
||||
$(menu).find('li[data-action="decompress"]').unbind().on('click', e => {
|
||||
e.preventDefault();
|
||||
Actions.decompress();
|
||||
});
|
||||
}
|
||||
|
||||
if (Pterodactyl.permissions.createFiles) {
|
||||
$(menu).find('li[data-action="folder"]').unbind().on('click', e => {
|
||||
e.preventDefault();
|
||||
Actions.folder();
|
||||
});
|
||||
}
|
||||
|
||||
if (Pterodactyl.permissions.downloadFiles) {
|
||||
if (parent.data('type') === 'file') {
|
||||
$(menu).find('li[data-action="download"]').removeClass('hidden');
|
||||
}
|
||||
$(menu).find('li[data-action="download"]').unbind().on('click', e => {
|
||||
e.preventDefault();
|
||||
Actions.download();
|
||||
});
|
||||
}
|
||||
|
||||
if (Pterodactyl.permissions.deleteFiles) {
|
||||
$(menu).find('li[data-action="delete"]').unbind().on('click', e => {
|
||||
e.preventDefault();
|
||||
Actions.delete();
|
||||
});
|
||||
}
|
||||
|
||||
$(window).unbind().on('click', event => {
|
||||
if($(event.target).is('.disable-menu-hide')) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
$(menu).unbind().remove();
|
||||
if(!_.isNull(this.activeLine)) this.activeLine.removeClass('active');
|
||||
});
|
||||
}
|
||||
|
||||
directoryClick() {
|
||||
$('a[data-action="directory-view"]').on('click', function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
const path = $(this).parent().data('path') || '';
|
||||
const name = $(this).parent().data('name') || '';
|
||||
|
||||
window.location.hash = encodeURIComponent(path + name);
|
||||
Files.list();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
window.ContextMenu = new ContextMenuClass;
|
|
@ -1,139 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// 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.
|
||||
class FileManager {
|
||||
constructor() {
|
||||
this.list(this.decodeHash());
|
||||
}
|
||||
|
||||
list(path, next) {
|
||||
if (_.isUndefined(path)) {
|
||||
path = this.decodeHash();
|
||||
}
|
||||
|
||||
this.loader(true);
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: Pterodactyl.meta.directoryList,
|
||||
headers: {
|
||||
'X-CSRF-Token': Pterodactyl.meta.csrftoken,
|
||||
},
|
||||
data: {
|
||||
directory: path,
|
||||
},
|
||||
}).done(data => {
|
||||
this.loader(false);
|
||||
$('#load_files').slideUp(10).html(data).slideDown(10, () => {
|
||||
ContextMenu.run();
|
||||
this.reloadFilesButton();
|
||||
this.addFolderButton();
|
||||
this.selectItem();
|
||||
this.selectAll();
|
||||
this.selectiveDeletion();
|
||||
this.selectRow();
|
||||
if (_.isFunction(next)) {
|
||||
return next();
|
||||
}
|
||||
});
|
||||
$('#internal_alert').slideUp();
|
||||
|
||||
if (typeof Siofu === 'object') {
|
||||
Siofu.listenOnInput(document.getElementById("files_touch_target"));
|
||||
}
|
||||
}).fail(jqXHR => {
|
||||
this.loader(false);
|
||||
if (_.isFunction(next)) {
|
||||
return next(new Error('Failed to load file listing.'));
|
||||
}
|
||||
|
||||
if ((path !== '' && path !== '/') && jqXHR.status === 404) {
|
||||
return this.list('', next);
|
||||
}
|
||||
|
||||
swal({
|
||||
type: 'error',
|
||||
title: 'File Error',
|
||||
text: jqXHR.responseJSON.errors[0].detail || 'An error occurred while attempting to process this request. Please try again.',
|
||||
});
|
||||
console.error(jqXHR);
|
||||
});
|
||||
}
|
||||
|
||||
loader(show) {
|
||||
if (show){
|
||||
$('.file-overlay').fadeIn(100);
|
||||
} else {
|
||||
$('.file-overlay').fadeOut(100);
|
||||
}
|
||||
}
|
||||
|
||||
reloadFilesButton() {
|
||||
$('i[data-action="reload-files"]').unbind().on('click', () => {
|
||||
$('i[data-action="reload-files"]').addClass('fa-spin');
|
||||
this.list();
|
||||
});
|
||||
}
|
||||
|
||||
selectItem() {
|
||||
$('[data-action="addSelection"]').on('click', event => {
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
selectAll() {
|
||||
$('[data-action="selectAll"]').on('click', event => {
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
selectiveDeletion() {
|
||||
$('[data-action="selective-deletion"]').on('mousedown', event => {
|
||||
new ActionsClass().deleteSelected();
|
||||
});
|
||||
}
|
||||
|
||||
addFolderButton() {
|
||||
$('[data-action="add-folder"]').unbind().on('click', () => {
|
||||
new ActionsClass().folder($('#file_listing').data('current-dir') || '/');
|
||||
});
|
||||
}
|
||||
|
||||
selectRow() {
|
||||
$('#file_listing tr').on('mousedown', event => {
|
||||
if (event.which === 1) {
|
||||
if ($(event.target).is('th') || $(event.target).is('input[data-action="selectAll"]')) {
|
||||
new ActionsClass().highlightAll(event);
|
||||
} else if ($(event.target).is('td') || $(event.target).is('input[data-action="addSelection"]')) {
|
||||
new ActionsClass().toggleHighlight(event);
|
||||
}
|
||||
|
||||
new ActionsClass().toggleMassActions();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
decodeHash() {
|
||||
return decodeURIComponent(window.location.hash.substring(1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
window.Files = new FileManager;
|
|
@ -1,162 +0,0 @@
|
|||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// 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.
|
||||
(function initUploader() {
|
||||
var notifyUploadSocketError = false;
|
||||
uploadSocket = io(Pterodactyl.node.scheme + '://' + Pterodactyl.node.fqdn + ':' + Pterodactyl.node.daemonListen + '/v1/upload/' + Pterodactyl.server.uuid, {
|
||||
'query': 'token=' + Pterodactyl.server.daemonSecret,
|
||||
});
|
||||
|
||||
uploadSocket.io.on('connect_error', function (err) {
|
||||
if(typeof notifyUploadSocketError !== 'object') {
|
||||
notifyUploadSocketError = $.notify({
|
||||
message: 'There was an error attempting to establish a connection to the uploader endpoint.<br /><br />' + err,
|
||||
}, {
|
||||
type: 'danger',
|
||||
delay: 0
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
uploadSocket.on('error', err => {
|
||||
Siofu.destroy();
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
uploadSocket.on('connect', function () {
|
||||
if (notifyUploadSocketError !== false) {
|
||||
notifyUploadSocketError.close();
|
||||
notifyUploadSocketError = false;
|
||||
}
|
||||
});
|
||||
|
||||
window.Siofu = new SocketIOFileUpload(uploadSocket);
|
||||
Siofu.listenOnDrop(document.getElementById("load_files"));
|
||||
|
||||
if (document.getElementById("files_touch_target")) {
|
||||
Siofu.listenOnInput(document.getElementById("files_touch_target"));
|
||||
}
|
||||
|
||||
window.addEventListener('dragover', function (event) {
|
||||
event.preventDefault();
|
||||
}, false);
|
||||
|
||||
window.addEventListener('drop', function (event) {
|
||||
event.preventDefault();
|
||||
}, false);
|
||||
|
||||
window.foldersDetectedInDrag = function (event) {
|
||||
var folderDetected = false;
|
||||
var files = event.dataTransfer.files;
|
||||
for (var i = 0, f; f = files[i]; i++) {
|
||||
if (!f.type && f.size === 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return folderDetected;
|
||||
};
|
||||
|
||||
var dropCounter = 0;
|
||||
$('#load_files').bind({
|
||||
dragenter: function (event) {
|
||||
event.preventDefault();
|
||||
dropCounter++;
|
||||
$(this).addClass('hasFileHover');
|
||||
},
|
||||
dragleave: function (event) {
|
||||
dropCounter--;
|
||||
if (dropCounter === 0) {
|
||||
$(this).removeClass('hasFileHover');
|
||||
}
|
||||
},
|
||||
drop: function (event) {
|
||||
if (window.foldersDetectedInDrag(event.originalEvent)) {
|
||||
$.notify({
|
||||
message: 'Folder uploads are not supported. Please use SFTP to upload whole directories.',
|
||||
}, {
|
||||
type: 'warning',
|
||||
delay: 0
|
||||
});
|
||||
}
|
||||
|
||||
dropCounter = 0;
|
||||
$(this).removeClass('hasFileHover');
|
||||
}
|
||||
});
|
||||
|
||||
Siofu.addEventListener('start', function (event) {
|
||||
window.onbeforeunload = function () {
|
||||
return 'A file upload in in progress, are you sure you want to continue?';
|
||||
};
|
||||
event.file.meta.path = $('#file_listing').data('current-dir');
|
||||
event.file.meta.identifier = Math.random().toString(36).slice(2);
|
||||
|
||||
$('#append_files_to').append('<tr id="file-upload-' + event.file.meta.identifier +'"> \
|
||||
<td><i class="fa fa-file-text-o" style="margin-left: 2px;"></i></td> \
|
||||
<td>' + event.file.name + '</td> \
|
||||
<td colspan=2"> </td> \
|
||||
</tr><tr> \
|
||||
<td colspan="5" class="has-progress"> \
|
||||
<div class="progress progress-table-bottom active"> \
|
||||
<div class="progress-bar progress-bar-info prog-bar-' + event.file.meta.identifier +'" style="width: 0%"></div> \
|
||||
</div> \
|
||||
</td> \
|
||||
</tr>\
|
||||
');
|
||||
});
|
||||
|
||||
Siofu.addEventListener('progress', function(event) {
|
||||
window.onbeforeunload = function () {
|
||||
return 'A file upload in in progress, are you sure you want to continue?';
|
||||
};
|
||||
var percent = event.bytesLoaded / event.file.size * 100;
|
||||
if (percent >= 100) {
|
||||
$('.prog-bar-' + event.file.meta.identifier).css('width', '100%').removeClass('progress-bar-info').addClass('progress-bar-success').parent().removeClass('active');
|
||||
} else {
|
||||
$('.prog-bar-' + event.file.meta.identifier).css('width', percent + '%');
|
||||
}
|
||||
});
|
||||
|
||||
// Do something when a file is uploaded:
|
||||
Siofu.addEventListener('complete', function(event) {
|
||||
window.onbeforeunload = function () {};
|
||||
if (!event.success) {
|
||||
$('.prog-bar-' + event.file.meta.identifier).css('width', '100%').removeClass('progress-bar-info').addClass('progress-bar-danger');
|
||||
$.notify({
|
||||
message: 'An error was encountered while attempting to upload this file.'
|
||||
}, {
|
||||
type: 'danger',
|
||||
delay: 5000
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Siofu.addEventListener('error', function(event) {
|
||||
window.onbeforeunload = function () {};
|
||||
console.error(event);
|
||||
$('.prog-bar-' + event.file.meta.identifier).css('width', '100%').removeClass('progress-bar-info').addClass('progress-bar-danger');
|
||||
$.notify({
|
||||
message: 'An error was encountered while attempting to upload this file: <strong>' + event.message + '.</strong>',
|
||||
}, {
|
||||
type: 'danger',
|
||||
delay: 8000
|
||||
});
|
||||
});
|
||||
})();
|
|
@ -1,131 +0,0 @@
|
|||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// 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.
|
||||
$('#console-popout').on('click', function (event) {
|
||||
event.preventDefault();
|
||||
window.open($(this).attr('href'), 'Pterodactyl Console', 'width=800,height=400');
|
||||
});
|
||||
var Server = (function () {
|
||||
|
||||
function initSocket() {
|
||||
if (typeof $.notifyDefaults !== 'function') {
|
||||
console.error('Notify does not appear to be loaded.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof io !== 'function') {
|
||||
console.error('Socket.io is required to use this panel.');
|
||||
return;
|
||||
}
|
||||
|
||||
$.notifyDefaults({
|
||||
placement: {
|
||||
from: 'bottom',
|
||||
align: 'right'
|
||||
},
|
||||
newest_on_top: true,
|
||||
delay: 2000,
|
||||
offset: {
|
||||
x: 20,
|
||||
y: 60,
|
||||
},
|
||||
animate: {
|
||||
enter: 'animated bounceInUp',
|
||||
exit: 'animated bounceOutDown'
|
||||
}
|
||||
});
|
||||
|
||||
var notifySocketError = false;
|
||||
|
||||
window.Socket = io(Pterodactyl.node.scheme + '://' + Pterodactyl.node.fqdn + ':' + Pterodactyl.node.daemonListen + '/v1/ws/' + Pterodactyl.server.uuid, {
|
||||
'query': 'token=' + Pterodactyl.server.daemonSecret,
|
||||
});
|
||||
|
||||
Socket.on('error', function (err) {
|
||||
if(typeof notifySocketError !== 'object') {
|
||||
notifySocketError = $.notify({
|
||||
message: 'There was an error attempting to establish a WebSocket connection to the Daemon. This panel will not work as expected.<br /><br />' + err,
|
||||
}, {
|
||||
type: 'danger',
|
||||
delay: 0,
|
||||
});
|
||||
}
|
||||
setStatusIcon(999);
|
||||
});
|
||||
|
||||
Socket.io.on('connect_error', function (err) {
|
||||
if(typeof notifySocketError !== 'object') {
|
||||
notifySocketError = $.notify({
|
||||
message: 'There was an error attempting to establish a WebSocket connection to the Daemon. This panel will not work as expected.<br /><br />' + err,
|
||||
}, {
|
||||
type: 'danger',
|
||||
delay: 0,
|
||||
});
|
||||
}
|
||||
setStatusIcon(999);
|
||||
});
|
||||
|
||||
// Connected to Socket Successfully
|
||||
Socket.on('connect', function () {
|
||||
if (notifySocketError !== false) {
|
||||
notifySocketError.close();
|
||||
notifySocketError = false;
|
||||
}
|
||||
});
|
||||
|
||||
Socket.on('initial status', function (data) {
|
||||
setStatusIcon(data.status);
|
||||
});
|
||||
|
||||
Socket.on('status', function (data) {
|
||||
setStatusIcon(data.status);
|
||||
});
|
||||
}
|
||||
|
||||
function setStatusIcon(status) {
|
||||
switch (status) {
|
||||
case 0:
|
||||
$('#server_status_icon').html('<i class="fa fa-circle text-danger"></i> Offline');
|
||||
break;
|
||||
case 1:
|
||||
$('#server_status_icon').html('<i class="fa fa-circle text-success"></i> Online');
|
||||
break;
|
||||
case 2:
|
||||
$('#server_status_icon').html('<i class="fa fa-circle text-warning"></i> Starting');
|
||||
break;
|
||||
case 3:
|
||||
$('#server_status_icon').html('<i class="fa fa-circle text-warning"></i> Stopping');
|
||||
break;
|
||||
default:
|
||||
$('#server_status_icon').html('<i class="fa fa-question-circle text-danger"></i> Connection Error');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
init: function () {
|
||||
initSocket();
|
||||
},
|
||||
|
||||
setStatusIcon: setStatusIcon,
|
||||
}
|
||||
|
||||
})();
|
||||
|
||||
Server.init();
|
|
@ -1,94 +0,0 @@
|
|||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// 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.
|
||||
(function updateServerStatus() {
|
||||
var Status = {
|
||||
0: 'Offline',
|
||||
1: 'Online',
|
||||
2: 'Starting',
|
||||
3: 'Stopping'
|
||||
};
|
||||
$('.dynamic-update').each(function (index, data) {
|
||||
var element = $(this);
|
||||
var serverShortUUID = $(this).data('server');
|
||||
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: Router.route('index.status', { server: serverShortUUID }),
|
||||
timeout: 5000,
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
||||
}
|
||||
}).done(function (data) {
|
||||
if (typeof data.status === 'undefined') {
|
||||
element.find('[data-action="status"]').html('<span class="label label-default">Error</span>');
|
||||
return;
|
||||
}
|
||||
switch (data.status) {
|
||||
case 0:
|
||||
element.find('[data-action="status"]').html('<span class="label label-danger">Offline</span>');
|
||||
break;
|
||||
case 1:
|
||||
element.find('[data-action="status"]').html('<span class="label label-success">Online</span>');
|
||||
break;
|
||||
case 2:
|
||||
element.find('[data-action="status"]').html('<span class="label label-info">Starting</span>');
|
||||
break;
|
||||
case 3:
|
||||
element.find('[data-action="status"]').html('<span class="label label-info">Stopping</span>');
|
||||
break;
|
||||
case 20:
|
||||
element.find('[data-action="status"]').html('<span class="label label-warning">Installing</span>');
|
||||
break;
|
||||
case 30:
|
||||
element.find('[data-action="status"]').html('<span class="label label-warning">Suspended</span>');
|
||||
break;
|
||||
}
|
||||
if (data.status > 0 && data.status < 4) {
|
||||
var cpuMax = element.find('[data-action="cpu"]').data('cpumax');
|
||||
var currentCpu = data.proc.cpu.total;
|
||||
if (cpuMax !== 0) {
|
||||
currentCpu = parseFloat(((data.proc.cpu.total / cpuMax) * 100).toFixed(2).toString());
|
||||
}
|
||||
if (data.status !== 0) {
|
||||
var cpuMax = element.find('[data-action="cpu"]').data('cpumax');
|
||||
var currentCpu = data.proc.cpu.total;
|
||||
if (cpuMax !== 0) {
|
||||
currentCpu = parseFloat(((data.proc.cpu.total / cpuMax) * 100).toFixed(2).toString());
|
||||
}
|
||||
element.find('[data-action="memory"]').html(parseInt(data.proc.memory.total / (1024 * 1024)));
|
||||
element.find('[data-action="cpu"]').html(currentCpu);
|
||||
element.find('[data-action="disk"]').html(parseInt(data.proc.disk.used));
|
||||
} else {
|
||||
element.find('[data-action="memory"]').html('--');
|
||||
element.find('[data-action="cpu"]').html('--');
|
||||
element.find('[data-action="disk"]').html('--');
|
||||
}
|
||||
}
|
||||
}).fail(function (jqXHR) {
|
||||
if (jqXHR.status === 504) {
|
||||
element.find('[data-action="status"]').html('<span class="label label-default">Gateway Timeout</span>');
|
||||
} else {
|
||||
element.find('[data-action="status"]').html('<span class="label label-default">Error</span>');
|
||||
}
|
||||
});
|
||||
}).promise().done(function () {
|
||||
setTimeout(updateServerStatus, 10000);
|
||||
});
|
||||
})();
|
|
@ -1,144 +0,0 @@
|
|||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// 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.
|
||||
|
||||
$(document).ready(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
$('[data-action="delete-schedule"]').click(function () {
|
||||
var self = $(this);
|
||||
swal({
|
||||
type: 'error',
|
||||
title: 'Delete Schedule?',
|
||||
text: 'Are you sure you want to delete this schedule? There is no undo.',
|
||||
showCancelButton: true,
|
||||
allowOutsideClick: true,
|
||||
closeOnConfirm: false,
|
||||
confirmButtonText: 'Delete Schedule',
|
||||
confirmButtonColor: '#d9534f',
|
||||
showLoaderOnConfirm: true
|
||||
}, function () {
|
||||
$.ajax({
|
||||
method: 'DELETE',
|
||||
url: Router.route('server.schedules.view', {
|
||||
server: Pterodactyl.server.uuidShort,
|
||||
schedule: self.data('schedule-id'),
|
||||
}),
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
||||
}
|
||||
}).done(function (data) {
|
||||
swal({
|
||||
type: 'success',
|
||||
title: '',
|
||||
text: 'Schedule has been deleted.'
|
||||
});
|
||||
self.parent().parent().slideUp();
|
||||
}).fail(function (jqXHR) {
|
||||
console.error(jqXHR);
|
||||
swal({
|
||||
type: 'error',
|
||||
title: 'Whoops!',
|
||||
text: 'An error occurred while attempting to delete this schedule.'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$('[data-action="trigger-schedule"]').click(function (event) {
|
||||
event.preventDefault();
|
||||
var self = $(this);
|
||||
swal({
|
||||
type: 'info',
|
||||
title: 'Trigger Schedule',
|
||||
text: 'This will run the selected schedule now.',
|
||||
showCancelButton: true,
|
||||
allowOutsideClick: true,
|
||||
closeOnConfirm: false,
|
||||
confirmButtonText: 'Continue',
|
||||
showLoaderOnConfirm: true
|
||||
}, function () {
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: Router.route('server.schedules.trigger', {
|
||||
server: Pterodactyl.server.uuidShort,
|
||||
schedule: self.data('schedule-id'),
|
||||
}),
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
||||
},
|
||||
}).done(function (data) {
|
||||
swal({
|
||||
type: 'success',
|
||||
title: '',
|
||||
text: 'Schedule has been added to the next-run queue.'
|
||||
});
|
||||
}).fail(function (jqXHR) {
|
||||
console.error(jqXHR);
|
||||
swal({
|
||||
type: 'error',
|
||||
title: 'Whoops!',
|
||||
text: 'An error occurred while attempting to trigger this schedule.'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$('[data-action="toggle-schedule"]').click(function (event) {
|
||||
var self = $(this);
|
||||
swal({
|
||||
type: 'info',
|
||||
title: 'Toggle Schedule',
|
||||
text: 'This will toggle the selected schedule.',
|
||||
showCancelButton: true,
|
||||
allowOutsideClick: true,
|
||||
closeOnConfirm: false,
|
||||
confirmButtonText: 'Continue',
|
||||
showLoaderOnConfirm: true
|
||||
}, function () {
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: Router.route('server.schedules.toggle', {
|
||||
server: Pterodactyl.server.uuidShort,
|
||||
schedule: self.data('schedule-id'),
|
||||
}),
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content'),
|
||||
}
|
||||
}).done(function (data) {
|
||||
swal({
|
||||
type: 'success',
|
||||
title: '',
|
||||
text: 'Schedule has been toggled.'
|
||||
});
|
||||
if (data.status !== 1) {
|
||||
self.parent().parent().addClass('muted muted-hover');
|
||||
} else {
|
||||
self.parent().parent().removeClass('muted muted-hover');
|
||||
}
|
||||
}).fail(function (jqXHR) {
|
||||
console.error(jqXHR);
|
||||
swal({
|
||||
type: 'error',
|
||||
title: 'Whoops!',
|
||||
text: 'An error occurred while attempting to toggle this schedule.'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,61 +0,0 @@
|
|||
// Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// 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.
|
||||
|
||||
$(document).ready(function () {
|
||||
function setupSelect2() {
|
||||
$('select[name="tasks[time_value][]"]').select2();
|
||||
$('select[name="tasks[time_interval][]"]').select2();
|
||||
$('select[name="tasks[action][]"]').select2();
|
||||
}
|
||||
|
||||
setupSelect2();
|
||||
|
||||
$('[data-action="update-field"]').on('change', function (event) {
|
||||
event.preventDefault();
|
||||
var updateField = $(this).data('field');
|
||||
var selected = $(this).map(function (i, opt) {
|
||||
return $(opt).val();
|
||||
}).toArray();
|
||||
if (selected.length === $(this).find('option').length) {
|
||||
$('input[name=' + updateField + ']').val('*');
|
||||
} else {
|
||||
$('input[name=' + updateField + ']').val(selected.join(','));
|
||||
}
|
||||
});
|
||||
|
||||
$('button[data-action="add-new-task"]').on('click', function () {
|
||||
if ($('#containsTaskList').find('.task-list-item').length >= 5) {
|
||||
swal('Task Limit Reached', 'You may only assign a maximum of 5 tasks to one schedule.');
|
||||
return;
|
||||
}
|
||||
|
||||
var clone = $('div[data-target="task-clone"]').clone();
|
||||
clone.insertBefore('#taskAppendBefore').removeAttr('data-target');
|
||||
clone.find('select:first').attr('selected');
|
||||
clone.find('input').val('');
|
||||
clone.find('span.select2-container').remove();
|
||||
clone.find('div[data-attribute="remove-task-element"]').addClass('input-group').find('div.input-group-btn').removeClass('hidden');
|
||||
clone.find('button[data-action="remove-task"]').on('click', function () {
|
||||
clone.remove();
|
||||
});
|
||||
setupSelect2();
|
||||
$(this).data('element', clone);
|
||||
});
|
||||
});
|
|
@ -77,7 +77,7 @@
|
|||
}, function () {
|
||||
$.ajax({
|
||||
method: 'DELETE',
|
||||
url: Router.route('admin.api.delete', { identifier: self.data('attr') }),
|
||||
url: '/admin/api/revoke/' + self.data('attr'),
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': '{{ csrf_token() }}'
|
||||
}
|
||||
|
|
|
@ -218,7 +218,7 @@
|
|||
}, function () {
|
||||
$.ajax({
|
||||
method: 'DELETE',
|
||||
url: Router.route('admin.nodes.view.allocation.removeSingle', { node: Pterodactyl.node.id, allocation: allocation }),
|
||||
url: '/admin/nodes/view/' + Pterodactyl.node.id + '/allocation/remove/' + allocation,
|
||||
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
||||
}).done(function (data) {
|
||||
element.parent().parent().addClass('warning').delay(100).fadeOut();
|
||||
|
@ -247,7 +247,7 @@
|
|||
clearTimeout(fadeTimers[element.data('id')]);
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: Router.route('admin.nodes.view.allocation.setAlias', { id: Pterodactyl.node.id }),
|
||||
url: '/admin/nodes/view/' + Pterodactyl.node.id + '/allocation/alias',
|
||||
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
||||
data: {
|
||||
alias: element.val(),
|
||||
|
@ -321,9 +321,7 @@
|
|||
}, function () {
|
||||
$.ajax({
|
||||
method: 'DELETE',
|
||||
url: Router.route('admin.nodes.view.allocation.removeMultiple', {
|
||||
node: Pterodactyl.node.id
|
||||
}),
|
||||
url: '/admin/nodes/view/' + Pterodactyl.node.id + '/allocations',
|
||||
headers: {'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')},
|
||||
data: JSON.stringify({
|
||||
allocations: selectedIds
|
||||
|
|
|
@ -130,7 +130,7 @@
|
|||
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: Router.route('admin.packs.new.template'),
|
||||
url: '/admin/packs/new/template',
|
||||
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
||||
}).fail(function (jqXhr) {
|
||||
console.error(jqXhr);
|
||||
|
|
|
@ -131,7 +131,7 @@
|
|||
}, function () {
|
||||
$.ajax({
|
||||
method: 'DELETE',
|
||||
url: Router.route('admin.servers.view.database.delete', { server: '{{ $server->id }}', database: self.data('id') }),
|
||||
url: '/admin/servers/view/{{ $server->id }}/database/' + self.data('id') + '/delete',
|
||||
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
||||
}).done(function () {
|
||||
self.parent().parent().slideUp();
|
||||
|
@ -152,7 +152,7 @@
|
|||
$(this).addClass('disabled').find('i').addClass('fa-spin');
|
||||
$.ajax({
|
||||
type: 'PATCH',
|
||||
url: Router.route('admin.servers.view.database', { server: '{{ $server->id }}' }),
|
||||
url: '/admin/servers/view/{{ $server->id }}/database',
|
||||
headers: { 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') },
|
||||
data: { database: $(this).data('id') },
|
||||
}).done(function (data) {
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
<script>
|
||||
$('#pUserId').select2({
|
||||
ajax: {
|
||||
url: Router.route('admin.users.json'),
|
||||
url: '/admin/users/accounts.json',
|
||||
dataType: 'json',
|
||||
delay: 250,
|
||||
data: function (params) {
|
||||
|
|
|
@ -117,7 +117,7 @@
|
|||
function saveSettings() {
|
||||
return $.ajax({
|
||||
method: 'PATCH',
|
||||
url: Router.route('admin.settings.mail'),
|
||||
url: '/admin/settings/mail',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({
|
||||
'mail:host': $('input[name="mail:host"]').val(),
|
||||
|
@ -146,7 +146,7 @@
|
|||
}, function () {
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: Router.route('admin.settings.mail.test'),
|
||||
url: '/admin/settings/mail/test',
|
||||
headers: { 'X-CSRF-Token': $('input[name="_token"]').val() }
|
||||
}).fail(function (jqXHR) {
|
||||
showErrorDialog(jqXHR, 'test');
|
||||
|
|
Loading…
Reference in a new issue