Apache Guacamole JS not rendering in web application - javascript

I'm using the apache guacamole-common-js library to allow rdp access to VMs within my web application via Apache Guacamole. I have an instance of guacamole and the client up and running on a server and I'm attempting to connect to tunnel to my instance via web sockets. I can see from the developer tools and server side logs that the web socket connection is working and that commands are being passed b/t my web application and the server, however the UI is never displayed.
I'm following all the examples I've been able to find, to no avail. I am testing this locally with a connection to the server, so it is a cross domain scenario, however as I mentioned the traffic b/t client and server appears to be working as expected. It's simply not rendering anything visually. When I look at the DOM, I can see elements injected that represent the guacamole client display elements. My code is as follows:
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="guacamole.css">
<title>Guacamole (EXAMPLE)</title>
</head>
<body>
<!-- Display -->
<div id="display" style="background-color: #f0f0f0; height: 500px; width: 500px;"></div>
<!-- Guacamole JavaScript API -->
<script type="text/javascript" src="https://myserver.com/guacamole-common-js/all.min.js"></script>
<!-- Init -->
<script type="text/javascript"> /* <![CDATA[ */
// Get display div from document
var display = document.getElementById("display");
var wsFullUrl = "wss://myserver.com/websocket-tunnel?token=CB3A548656A5A0F5470AD0A51BE79883B864A4FF8B0308F87F53F8FBC49BA74F&GUAC_DATA_SOURCE=mysql&GUAC_ID=3&GUAC_TYPE=c&GUAC_WIDTH=500&GUAC_HEIGHT=500&GUAC_DPI=192&GUAC_TIMEZONE=America/Chicago&GUAC_AUDIO=audio/L8&GUAC_AUDIO=audio/L16&GUAC_IMAGE=image/jpeg&GUAC_IMAGE=image/png&GUAC_IMAGE=image/webp";
// Instantiate client, using an HTTP tunnel for communications.
var guac = new Guacamole.Client(
new Guacamole.WebSocketTunnel(wsFullUrl)
);
var element = guac.getDisplay().getElement();
// Add client to display div
display.appendChild(element);
// Error handler
guac.onerror = function (error) {
alert(error);
};
// Connect
guac.connect();
// Disconnect on close
window.onunload = function () {
guac.disconnect();
}
// Mouse
var mouse = new Guacamole.Mouse(guac.getDisplay().getElement());
mouse.onEach(['mousedown', 'mouseup', 'mousemove'], function sendMouseEvent(e) {
guac.sendMouseState(e.state);
});
// Keyboard
var keyboard = new Guacamole.Keyboard(document);
keyboard.onkeydown = function (keysym) {
guac.sendKeyEvent(1, keysym);
};
keyboard.onkeyup = function (keysym) {
guac.sendKeyEvent(0, keysym);
};
/* ]]> */</script>
</body>
</html>
Any insight anyone might have would be much appreciated!

Related

Exif-js doesn't seem to work with local photos

I'm having a bit of a weird problem with my javascript code...
It basically consists of a script that accesses the exif of a photo and then shows it on an HTML page, more specifically the latitude and longitude of it.
The idea is to then use both the latitude and longitude on a Google maps iframe to then show the location that photo was taken...
That's all working but, until now, I've been using a picture that's stored on the cloud to make the testing...
If I try to make it work with the same exact picture stored locally, no EXIF info will appear on the page...
(I've also tried with some of my own pictures that have exif info and it still doesn't work...)
Why does it seem like Exif-js only works with images stored on a server?
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>EXIF</title>
<style>
img{
width: 500px;
max-height: auto;
}
</style>
</head>
<body>
<!-- If I use this it works: -->
<img src="https://c1.staticflickr.com/5/4867/30883801817_bf122bc498_o.jpg" id="img1" />
<!-- If I use this it DOESN'T work: -->
<img src="image3.jpg" id="img1"/> <!-- IT'S THE SAME IMAGE AND IT DOES HAVE EXIF-->
<iframe id="mapa_google" src="" width="640" height="480"></iframe>
<h1>Latitude Exif</h1>
<p id="local_lat"></p>
<h1>Longitude Exif</h1>
<p id="local_lon"></p>
<h1>Latitude Final</h1>
<p id="local_lat_final"></p>
<h1>Longitude Final</h1>
<p id="local_lon_final"></p>
<script src="exif.js"></script>
<script>
var toDecimal = function (number) {
var d = Math.floor(number[0]);
var m = Math.floor(number[1]);
var s = ((number[1]%1)*60);
var dms= d+(m/60)+(s/3600);
return dms
};
window.onload=getExif;
function getExif() {
img1 = document.getElementById("img1");
EXIF.getData(img1, function() {
latitude = EXIF.getTag(this, "GPSLatitude");
longitude = EXIF.getTag(this, "GPSLongitude");
local_lat = document.getElementById("local_lat");
local_lon = document.getElementById("local_lon");
local_lat.innerHTML = `${latitude}`;
local_lon.innerHTML = `${longitude}`;
latitude_final = toDecimal(latitude);
local_lat_final = document.getElementById("local_lat_final");
local_lat_final.innerHTML = `${latitude_final}`;
longitude_final = toDecimal(longitude);
local_lon_final = document.getElementById("local_lon_final");
local_lon_final.innerHTML = `${longitude_final}`;
document.getElementById("mapa_google").src = "https://www.google.com/maps/embed/v1/place?key=AIzaSyDQSbRMCIv1gDsT2qRsY8HvLyZP11hte_Y&q="+latitude_final+"+"+longitude_final;
});
}
getExif();
</script>
</body>
</html>
This is a CORS problem.
Exif-js uses an ajax request to retrieve the image. Ajax calls require CORS access. Pages loaded via file:// URIs don't contain the headers that CORS depends on, and the same-origin policy for these files is implementation-dependent but the safest assumption is to treat every file as having its own unique origin -- which means that loading files without a webserver isn't a good enough way to test anything that involves XHR calls.
Similarly, the site you mentioned in comments as also having this problem is denying CORS access:
[Error] Origin null is not allowed by Access-Control-Allow-Origin.
[Error] XMLHttpRequest cannot load
https://myriad-online.com/images/forum/IMG_4692.jpg due to access
control checks.
as can be seen by watching the developer console (always a good idea when testing js code...) while running this code snippet:
function getExif() {
img1 = document.getElementById("img1");
EXIF.getData(img1, function() {
// won't be reached in this example
console.log(this);
});
}
getExif();
<script src="https://cdn.jsdelivr.net/npm/exif-js"></script>
<img src="http://myriad-online.com/images/forum/IMG_4692.jpg" id="img1" />
You won't be able to run exif-js on files that are hosted by sites which explicitly deny CORS access, but for local testing the simplest solution is going to be to spin up a local webserver and test your files via http:// instead of file:// URIs.

Disabling clicks on a certain part of the page using div

I am using the following example as a client in my web browser to access my remote desktop using Guacamole project. But it gives full access of computer to the user.
Although I have used some VNC/RDP restrictions to apply limits from server side. But still the requirement is that user must not able to interact with some portions of the application on the remote computer from front end (like close or minimize button or portion of Top left or top right page) so he can only use the application but can not minimize or close it.
So I was thinking that maybe I could disable click on these portions so it will not be transferred to the remote desktop.
<html>
<head>
<link rel="stylesheet" type="text/css" href="guacamole.css"/>
<title>Guacamole</title>
</head>
<body>
<!-- Display -->
<div id="display"></div>
<!-- Guacamole JavaScript API -->
<script type="text/javascript"
src="guacamole-common-js/all.min.js"></script>
<!-- Init -->
<script type="text/javascript"> /* <![CDATA[ */
// Get display div from document
var display = document.getElementById("display");
// Instantiate client, using an HTTP tunnel for communications.
var guac = new Guacamole.Client(
new Guacamole.HTTPTunnel("tunnel")
);
// Add client to display div
display.appendChild(guac.getDisplay().getElement());
// Error handler
guac.onerror = function(error) {
alert(error);
};
// Connect
guac.connect();
// Disconnect on close
window.onunload = function() {
guac.disconnect();
}
// Mouse
var mouse = new Guacamole.Mouse(guac.getDisplay().getElement());
mouse.onmousedown =
mouse.onmouseup =
mouse.onmousemove = function(mouseState) {
guac.sendMouseState(mouseState);
};
// Keyboard
var keyboard = new Guacamole.Keyboard(document);
keyboard.onkeydown = function (keysym) {
guac.sendKeyEvent(1, keysym);
};
keyboard.onkeyup = function (keysym) {
guac.sendKeyEvent(0, keysym);
};
/* ]]> */ </script>
</body>
What I get on the front end is the complete picture of my remote computer. Any idea how to limit the interaction from front end?

Executing Windows files/events with NW.js (Node Webkit)

I will start by saying I am far from a JavaScript guy. I work more with HTML and CSS, and "dabble" with JavaScript, as in tweak some code to make JQuery code do what I'd like it to on the front-end.
I am having a bit of an issue with a task I am trying to complete, which has led me to using NW.js (Node Webkit) for the first time.
I am trying to create a 4 button user interface that allows for the following 4 events to occur on click:
1. Load a website in a new window
2. Open windows explorer to a specific directory and allow the user to browse
3. Extend Windows Display on a Dual Monitor Setup
4. Clone Windows Display on a Dual Monitor Setup
I was originally pretty much finished and achieved my results easily with an HTML Application file - I know, outdated, but it allowed me to work within my skill set and achieve the tasks I needed fairly easily. Problem wa, it wouldn't allow for CSS3 and the website being opened used it, and it pretty much ruined the look of it as a whole. Sooo I needed something new.
I stumbled across NW.js and have started away on that. I've got my package loaded up, my "app" is now launch-able, but the old script isn't working and I am back to square one. I have no idea how to launch executables in Windows using NW.js - it's driving me bonkers!
Below is the code that worked in the HTML Application file (minus the file explorer, which I had yet to get to before realizing it wouldn't work):
<!DOCTYPE html>
<html>
<head>
<title>My HTML App</title>
<link rel="stylesheet" href="style.css">
<script type="text/javascript" language="javascript">
function RunPad() {
WshShell = new ActiveXObject("WScript.Shell");
WshShell.Run("c:/windows/system32/notepad.exe", 1, false);
}
function RunExtend() {
WshShell = new ActiveXObject("WScript.Shell");
WshShell.Run("c:/windows/System32/DisplaySwitch.exe /extend", 1, false);
}
function RunClone() {
WshShell = new ActiveXObject("WScript.Shell");
WshShell.Run("c:/windows/System32/DisplaySwitch.exe /clone", 1, false);
}
function RunWebsite() {
WshShell = new ActiveXObject("WScript.Shell");
WshShell.Run("c:/Program Files/Internet Explorer/iexplore.exe", 1, false);
}
</script>
</head>
<body>
<div class="container">
<div class="col-1-2"><img src="website.jpg" onclick="RunWebsite();"></div>
<div class="col-1-2"><img src="resources.jpg"></a></div>
<div class="col-1-2"><img src="single_screen.jpg" onclick="RunExtend();"></div>
<div class="col-1-2"><img src="dual_screen.jpg" onclick="RunClone();"></div></div>
</div>
</body>
</html>
I'm really stuck on this and am not sure which route to take to complete this with NW.js
Any help would be appreciated.
ActiveXObject is for IE/Edge only so it won't work under Chromium (used by NW).
What you can do though is create individual Vbs scripts for each of your ActiveXObject functions and call/execute them as required with node.js (supported by NW) in this way...
function RunExtProgram(ProgName){
require('child_process').exec(ProgName,function(error,stdout,stderr){if(error!==null){alert('Unable to launch process:<br><br>'+stderr+'<br><br>'+ProgName);}});
}
Usage example:
RunExtProgram('C:/test/abc.vbs');

Using Cordova webview

I wish to find out, for mobile developing using Cordova, is there a way to open a remote web app, and when a button is click in the remote web app, it execute a java script in Cordova environment?
For example, my mobile app opened up a web page hosted in the app server through web view, to ask the user to acknowledge he read and accept the license. The user need to click "Accept" or "Not Accept" on the web page.
If the user click "Accept", I hope to run a javascript that can bring up another page in the mobile app for the user to proceed to use the mobile app.
Is this possible?
Thanks!
Firstly, it's not a good idea to have a mobile app that is totally reliant on a remote server in order to function properly: what if the user's internet connection cuts out or is intermittent? (that happens plenty where I live).
However, one solution would be use an iframe to load the remote webapp content and cross-frame messaging to communicate the outcome of the UI interactions with the remote webapp back to your Cordova app. You will have to appropriately whitelist your remote webapp URL.
Something like this:
Cordova app index.html
<html>
<head>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript">
function onDeviceReady(){
window.addEventListener("message", onFrameMessage, false);
}
function onFrameMessage(event){
var eventName = event.data[0];
if(eventName === "terms_result"){
var accepted = event.data[1] == 1; // == will match 1 or "1"
if(accepted){
// Do something - e.g. change to homepage
}else{
// Do something else - e.g. display an error message
}
}
}
document.addEventListener("deviceready", onDeviceReady);
</script>
</head>
<body>
<div data-role="page" id="terms">
<iframe src="http://example.com/my/remote/webapp" style="border: 0; width: 100%; height: 100%"></iframe>
</div>
<div data-role="page" id="home">
<!-- Your home page content -->
</div>
</body>
</html>
Remote webapp html
<html>
<head>
<script type="text/javascript">
function accept(result){
window.parent.postMessage(["terms_result", result], "*");
}
</script>
</head>
<body>
<button onclick="accept(1)">Accept</button>
<button onclick="accept(0)">Not Accept</button>
</body>
</html>

Nodejs web application for mqtt using jquery

I want to design a web app capable of publishing message on mqtt broker when a switch state is changed or a form is filled and submitted etc. I am able to publish the message using mqtt library on node. I am also able to detect the normal switch state when it is changed on html page using javascript and jquery. Now I want to call the mqtt publish function from node app here. How will I do it?
Here is the normal html file switch.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="switch.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="switch.js"></script>
</head>
<body>
<h2>Toggle Switch</h2>
<label class="switch" id = "switchLabel1">
<input type="checkbox" id = "switch1">
<div class="slider round"></div>
</label>
</body>
</html>
The javascript that detects the switch state switch.js
$( document ).ready(function() {
$('#switch1').attr('checked', true);
$('#switch1').click(function(){
if($(this).prop("checked") == true){
console.log("switch1 is checked.");
}
else if($(this).prop("checked") == false){
console.log("switch1 is unchecked.");
}
});
});
The Nodejs app publishing message to mqtt index.js. MQTT library is installed using npm.
var mqtt = require('mqtt')
var client = mqtt.connect('mqtt://192.168.15.3')
client.on('connect', function () {
client.subscribe('mqtt_node_subscribe')
client.publish('mqtt_node_publish', 'Hello mqtt')
})
client.on('message', function (topic, message) {
// message is Buffer
console.log(message.toString())
})
What I want to do is call client.publish("topic", "message") when instead of console.log in switch.js
When I do that it says client not defined, so I tried merging both js and running node, it says $ not defined. I tried including jquery in node app, it says window missing. So I need a method to serve this web application using node and use jquery etc as is.
MQTT over a websocket is a difficult approach. The same work can be done using socket.io. It is a js based library giving capabilities of topics publish and subscribe messages. Give it a try.

Categories

Resources