caterpillar/console.html

495 lines
22 KiB
HTML
Raw Normal View History

2024-06-20 07:48:52 +00:00
<!doctype html>
<html>
<head>
2024-11-06 09:42:08 +00:00
<title>Caterpillar Proxy Console</title>
2024-06-20 07:48:52 +00:00
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
2024-06-21 05:35:27 +00:00
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
2024-06-26 07:21:05 +00:00
<meta name="referrer" content="unsafe-url">
2024-11-06 09:42:08 +00:00
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery.terminal/2.44.1/css/jquery.terminal.min.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
2024-06-25 02:31:53 +00:00
<style type="text/css">/*<!--<![CDATA[*/
2024-11-06 09:42:08 +00:00
html, body, main {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#content {
float: right;
2024-11-06 09:46:17 +00:00
width: 80%;
2024-11-06 09:42:08 +00:00
height: 100%;
scroll: hidden;
}
#cover {
float: left;
2024-11-06 09:46:17 +00:00
width: 20%;
2024-11-06 09:42:08 +00:00
height: 100%;
scroll: hidden;
2024-06-25 04:34:53 +00:00
background: #2e8d36 url(https://pub-1a7a176eea68479cb5423e44273657ad.r2.dev/bg.jpg) no-repeat;
background-size: cover;
background-position: center;
2024-06-25 02:31:53 +00:00
}
2024-11-06 09:42:08 +00:00
#cover article {
margin: 30px;
2024-06-25 02:31:53 +00:00
}
2024-11-06 09:42:08 +00:00
#console {
height: 100%;
2024-06-25 02:31:53 +00:00
}
/*]]>-->*/</style>
2024-06-20 07:48:52 +00:00
</head>
<body>
2024-06-25 02:31:53 +00:00
<main>
2024-11-06 09:42:08 +00:00
<section id="content">
<div id="console"></div>
<div id="map"></div>
2024-11-07 17:17:15 +00:00
<div id="embed"></div>
2024-11-06 09:42:08 +00:00
</section>
<section id="cover">
<article>
2024-11-06 09:43:50 +00:00
<h1>Caterpillar Proxy Console</h1>
2024-11-06 09:42:08 +00:00
<p>Source code available</p>
<p><a href="https://github.com/gnh1201/caterpillar">gnh1201/caterpillar (GitHub)</a></p>
2024-11-07 05:42:48 +00:00
<p><a href="https://github.com/gnh1201/caterpillar-plugins">gnh1201/caterpillar-plugins (GitHub)</a></p>
2024-11-06 09:42:08 +00:00
</article>
</section>
2024-06-25 02:31:53 +00:00
</main>
2024-06-20 07:48:52 +00:00
2024-11-06 09:42:08 +00:00
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.terminal/2.44.1/js/jquery.terminal.min.js"></script>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
2024-06-20 07:48:52 +00:00
<script type="text/javascript">//<!--<![CDATA[
var env = {
"target": "http://localhost/",
2024-06-21 07:19:10 +00:00
"method": "",
"filename": null
2024-06-20 07:48:52 +00:00
};
2024-06-25 10:39:32 +00:00
var set_default_env = function(_env) {
for (k in _env) {
if (!(k in env)) {
env[k] = _env[k];
}
}
};
2024-06-21 02:32:08 +00:00
var pretty_jsonify = function(data) {
return JSON.stringify(data, null, 4);
};
2024-06-21 07:19:10 +00:00
var download_text = function(filename, text) {
var element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
2024-11-07 16:33:05 +00:00
};
var show_embed = function(term, url) {
term.echo('', {
finalize: function($div) {
2024-11-07 17:17:15 +00:00
var $embed = $("#embed");
$embed.html($("<iframe/>").attr({
2024-11-07 16:33:05 +00:00
"title": "embed web page",
"src": url,
"allow": "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share",
"referrerpolicy": "unsafe-url",
"allowfullscreen": true
}).css({
"width": "100%",
"height": "240px",
"border": "none"
}));
2024-11-07 17:17:15 +00:00
$div.children().last().append($embed);
2024-11-07 16:33:05 +00:00
term.echo();
}
});
};
2024-06-20 07:48:52 +00:00
var jsonrpc2_request = function(term, method, params) {
var requestData = {
jsonrpc: "2.0",
method: method,
params: params,
id: null
};
$.ajax({
url: env.target,
type: 'POST',
contentType: 'application/json',
2024-06-21 12:58:50 +00:00
dataType: 'text',
2024-06-20 07:48:52 +00:00
data: JSON.stringify(requestData),
beforeSend: function(xhr) {
xhr.setRequestHeader("X-User-Agent", "php-httpproxy/0.1.5 (Client; WebConsole; abuse@catswords.net)");
},
success: function(response) {
2024-06-21 12:58:50 +00:00
var responseData = {
"error": {
2024-06-21 13:21:21 +00:00
"message": "Unknown error"
2024-06-21 12:58:50 +00:00
}
};
var process_corrupted_json = function(s) {
2024-06-21 13:02:53 +00:00
// for dirty response (e.g., magic header, advertise logo)
2024-06-21 12:58:50 +00:00
try {
var start = s.indexOf('{');
var end = s.lastIndexOf('}');
if (start > -1 && end > -1 && end > start) {
2024-06-24 12:51:12 +00:00
responseData = JSON.parse(s.substring(start, end + 1));
2024-06-21 13:24:32 +00:00
} else {
throw new Error("It does not seem like a JSON format.");
2024-06-21 12:58:50 +00:00
}
} catch (e) {
2024-06-21 13:21:21 +00:00
responseData.error.message = e.message
+ "\r\nRaw response data:"
+ "\r\n" + response;
2024-06-21 12:58:50 +00:00
}
};
try {
2024-06-21 13:21:21 +00:00
if (response.trim() == "") {
responseData.error.message = "Received an empty response data";
} else {
2024-06-21 12:58:50 +00:00
responseData = JSON.parse(response);
}
} catch (e) {
responseData.error.message = e.message;
process_corrupted_json(response);
}
2024-06-21 07:19:10 +00:00
var text = "";
2024-06-21 12:58:50 +00:00
if ("error" in responseData) {
text = responseData.error.message;
2024-06-20 08:01:32 +00:00
} else {
2024-06-21 12:58:50 +00:00
if (typeof responseData.result.data === "object") {
text = pretty_jsonify(responseData.result.data);
2024-06-21 03:41:18 +00:00
} else {
2024-06-21 12:58:50 +00:00
text = responseData.result.data;
2024-06-21 03:41:18 +00:00
}
2024-06-20 08:01:32 +00:00
}
2024-06-21 07:19:10 +00:00
// save as a file
if (env.filename != null) {
download_text(env.filename, text);
}
2024-06-25 08:22:03 +00:00
// method(relay_get_geolocation)
if (env.method == "relay_get_geolocation") {
2024-11-07 20:45:12 +00:00
term.echo(text);
2024-06-25 08:22:03 +00:00
term.echo('', {
finalize: function($div) {
2024-11-07 20:45:12 +00:00
var geodata = responseData.result.data;
2024-11-07 17:17:15 +00:00
var $map = $("#map").css({
2024-11-07 16:33:05 +00:00
"height": "240px"
2024-11-07 17:17:15 +00:00
});
$div.children().last().append($map);
2024-06-25 08:22:03 +00:00
map.setView([geodata.lat, geodata.lon], 13);
var circle = L.circle([geodata.lat, geodata.lon], {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.5,
radius: 500
}).addTo(map);
term.echo();
}
});
}
2024-11-07 20:45:12 +00:00
// method(relay_web_search)
if (env.method == "relay_web_search") {
var searchdata = responseData.result.data;
if ("error" in searchdata) {
term.echo(searchdata.error.message);
term.echo('');
return;
}
var results = Object.values(searchdata);
if (results.length > 0) {
results.forEach(function(x) {
if (typeof x !== "object") return;
if ("special_response" in x) {
term.echo("< " + x.special_response.response);
term.echo("< " + x.special_response.source);
term.echo('');
} else {
var base_domain = (function(s) {
return s.split("/")[2];
})(x.base_url);
term.echo("< [[!;;;;" + x.url + ";{}]" + x.title.trim() + " (" + base_domain + ")]: " + x.description.trim());
}
});
} else {
term.echo("No any results");
}
term.echo('');
}
2024-06-20 07:48:52 +00:00
},
error: function(xhr, status, error) {
term.echo(error);
}
});
};
jQuery(function($, undefined) {
$('#console').terminal({
2024-11-07 21:13:55 +00:00
set: function(...args) {
var k = (args.length > 0 ? args[0] : '');
var v = (args.length > 1 ? args.slice(1) : []).join(' ');
2024-06-21 02:24:18 +00:00
if (k == "env") {
this.echo("env is the reserved word");
return;
}
2024-11-07 21:13:55 +00:00
// method(relay_web_search)
if (env.method == "relay_web_search" && k == "page") {
env[k] = parseInt(v);
return;
}
2024-06-21 02:24:18 +00:00
2024-06-21 07:19:10 +00:00
env[k] = v || null;
2024-06-20 10:05:28 +00:00
if (k == "method") {
this.set_prompt('method([[b;red;black]' + env.method + '])> ');
2024-06-21 03:41:18 +00:00
2024-06-25 10:39:32 +00:00
// method(relay_sendmail)
if (env.method == "relay_sendmail") {
set_default_env({
"mail_to": "noreply@example.org",
"mail_from": "noreply@example.org",
"mail_subject": "Important Message from System Administrator"
});
}
// method(relay_mysql_query)
2024-06-21 03:41:18 +00:00
if (env.method == "relay_mysql_query") {
2024-06-25 10:39:32 +00:00
set_default_env({
2024-06-21 03:41:18 +00:00
"mysql_hostname": "localhost",
"mysql_username": "root",
2024-06-25 06:43:53 +00:00
"mysql_password": null,
"mysql_database": null,
2024-06-21 03:41:18 +00:00
"mysql_port": "3306",
"mysql_charset": "utf8"
2024-06-25 10:39:32 +00:00
});
2024-06-21 03:41:18 +00:00
}
2024-11-07 20:45:12 +00:00
// method(relay_web_search)
if (env.method == "relay_web_search") {
set_default_env({
2024-11-07 21:13:55 +00:00
"keyword": "",
2024-11-07 20:45:12 +00:00
"page": 1
});
}
2024-06-20 10:05:28 +00:00
}
2024-06-20 07:48:52 +00:00
},
show: function(k) {
2024-06-21 02:24:18 +00:00
var v = env[k];
if (typeof env[k] === "object") {
2024-06-21 02:32:08 +00:00
this.echo(pretty_jsonify(v));
2024-06-21 02:24:18 +00:00
} else if (k == "env") {
2024-06-21 02:32:08 +00:00
this.echo(pretty_jsonify(env));
2024-06-21 02:24:18 +00:00
} else {
this.echo(v);
2024-06-20 07:48:52 +00:00
}
},
do: function(...args) {
if (env.method == "") {
this.echo("Please set a method");
return;
}
2024-06-21 03:41:18 +00:00
// method(relay_invoke_method)
2024-06-20 07:48:52 +00:00
if (env.method == "relay_invoke_method") {
if (args.length < 1) {
this.echo("Please set a callback");
return;
}
jsonrpc2_request(this, env.method, {
"callback": args[0],
"args": args.slice(1)
});
return;
}
2024-06-21 03:41:18 +00:00
// method(relay_dns_get_record)
if (env.method == "relay_dns_get_record") {
if (args.length < 1) {
this.echo("Please set a hostname");
return;
}
jsonrpc2_request(this, env.method, {
"hostname": args[0]
});
return;
}
2024-06-25 07:33:33 +00:00
// method(relay_fetch_url)
if (env.method == "relay_fetch_url") {
if (args.length < 1) {
this.echo("Please set a URL");
return;
}
2024-06-25 07:33:33 +00:00
jsonrpc2_request(this, env.method, {
"url": args[0]
});
return;
2024-06-25 07:33:33 +00:00
}
2024-06-21 03:41:18 +00:00
2024-06-25 10:39:32 +00:00
// method(relay_sendmail)
if (env.method == "relay_sendmail") {
this.echo("From: " + env.mail_from + "\r\nTo: " + env.mail_to + "\r\nSubject: " + env.mail_subject);
this.read("Enter your message:\r\n", function(message) {
jsonrpc2_request(this, env.method, {
"to": env.mail_to,
"from": env.mail_from,
"subject": env.mail_subject,
"message": message
});
});
return;
}
2024-06-21 03:41:18 +00:00
// method(relay_mysql_query)
if (env.method == "relay_mysql_query") {
var _this = this;
2024-06-25 06:43:53 +00:00
var do_query = function(query) {
2024-06-21 03:41:18 +00:00
jsonrpc2_request(_this, env.method, {
"hostname": env.mysql_hostname,
"username": env.mysql_username,
"password": env.mysql_password,
"database": env.mysql_database,
"port": env.mysql_port,
"charset": env.mysql_charset,
"query": query
});
2024-06-25 06:43:53 +00:00
}
if (args.length < 1) {
this.read("Enter MySQL query:\r\n", do_query);
} else {
do_query(args.join(' '));
}
2024-06-21 03:41:18 +00:00
return;
}
2024-10-24 22:08:39 +00:00
// method(analyze_sequence)
if (env.method == "analyze_sequence") {
var _this = this;
this.read("Enter the sequence:\r\n", function(message) {
2024-10-24 23:59:49 +00:00
jsonrpc2_request(_this, env.method, {
2024-10-24 22:08:39 +00:00
"sequence": message
});
});
return;
}
// method(gc_content_calculation)
if (env.method == "gc_content_calculation") {
var _this = this;
this.read("Enter the sequence:\r\n", function(message) {
2024-10-24 23:59:49 +00:00
jsonrpc2_request(_this, env.method, {
2024-10-24 22:08:39 +00:00
"sequence": message
});
});
return;
}
2024-06-21 03:41:18 +00:00
2024-10-25 00:36:33 +00:00
// method(container_start)
if ([
"container_start",
"container_stop",
"container_pause",
"container_unpause",
"container_restart",
"container_kill",
"container_remove"
].indexOf(env.method) > -1) {
if (args.length < 1) {
this.echo("Please set a container name");
return;
}
jsonrpc2_request(this, env.method, {
"name": args[0]
});
return;
}
2024-11-07 20:45:12 +00:00
// method(relay_web_search)
if (env.method == "relay_web_search") {
jsonrpc2_request(this, env.method, {
2024-11-07 21:13:55 +00:00
"keyword": env.keyword,
"page": env.page,
"type": "text"
2024-11-07 20:45:12 +00:00
});
return;
}
2024-10-25 00:36:33 +00:00
2024-06-21 03:41:18 +00:00
// method(*)
2024-06-20 07:48:52 +00:00
jsonrpc2_request(this, env.method, {});
2024-11-07 16:33:05 +00:00
},
show_embed: function(url) {
show_embed(this, url);
},
youtube: function(...args) {
if (args.length < 1) {
this.echo("Please let me know what do you want to do.");
}
var action = args[0];
switch (action) {
case "play":
if (args.length < 2) {
this.echo("Please let me know the video ID");
}
var video_id = args[1];
show_embed(this, "https://www.youtube.com/embed/" + video_id);
break;
}
2024-11-07 18:22:50 +00:00
},
search: function(...args) {
2024-11-07 20:45:12 +00:00
this.exec("set method relay_web_search");
2024-11-07 21:13:55 +00:00
this.exec("set page 1");
this.exec("set keyword " + args.join(' '));
this.exec("do");
},
next: function() {
if (env.method == "relay_web_search") {
var num = parseInt(env.page) + 1;
this.exec("set page " + num);
this.exec("do");
}
},
prev: function() {
if (env.method == "relay_web_search") {
2024-11-07 21:17:26 +00:00
var num = (env.page > 1 ? env.page - 1 : 1);
2024-11-07 21:13:55 +00:00
this.exec("set page " + num);
this.exec("do");
}
},
2024-06-20 07:48:52 +00:00
}, {
2024-11-06 09:42:08 +00:00
height: "100%",
width: "100%",
2024-06-20 07:48:52 +00:00
prompt: '> ',
checkArity: false
});
});
2024-06-25 08:22:03 +00:00
var map = L.map('map');
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
2024-06-20 07:48:52 +00:00
//]]>--></script>
</body>
</html>