thing-it-device-browser
Advanced tools
Comparing version 2.2.9 to 2.3.0
372
browser.js
@@ -139,3 +139,4 @@ module.exports = { | ||
http = require("http"), | ||
request = require("request"), | ||
request = require('request'), | ||
rp = require('request-promise'), | ||
socket = require("socket.io"), | ||
@@ -157,2 +158,3 @@ modeEnum = { | ||
authenticatedClients = [], | ||
template, | ||
mode, | ||
@@ -165,145 +167,149 @@ authorizationToken, | ||
this.recognizeMode(); | ||
this.recognizeMode() | ||
.then(() => { | ||
app = express(); | ||
httpServer = http.createServer(app); | ||
io = socket(httpServer); | ||
proxy = httpProxy.createProxyServer({ | ||
secure: false, | ||
//auth: 'Basic ' + new Buffer("username" + ':' + "password").toString('base64'), | ||
changeOrigin: true, | ||
hostRewrite: this.configuration.externalHost, | ||
protocolRewrite: "http", | ||
cookieDomainRewrite: this.configuration.externalHost.split(":")[0], | ||
ignorePath: true, | ||
ws: true | ||
}); | ||
this.logDebug("Initialized express, http server, socket-io server, and proxy server."); | ||
app = express(); | ||
httpServer = http.createServer(app); | ||
io = socket(httpServer); | ||
proxy = httpProxy.createProxyServer({ | ||
secure: false, | ||
//auth: 'Basic ' + new Buffer("username" + ':' + "password").toString('base64'), | ||
changeOrigin: true, | ||
hostRewrite: this.configuration.externalHost, | ||
protocolRewrite: "http", | ||
cookieDomainRewrite: this.configuration.externalHost.split(":")[0], | ||
ignorePath: true, | ||
ws: true | ||
}); | ||
this.logDebug("Initialized express, http server, socket-io server, and proxy server."); | ||
// load token from file | ||
var tokenFilePath = process.cwd() + "/browser-security-tokens.json"; | ||
let tokens = fs.existsSync(tokenFilePath) | ||
? JSON.parse(fs.readFileSync(tokenFilePath, "utf8")) | ||
: {}; | ||
if (tokens.hasOwnProperty(this.id)) { | ||
lastTokenChange = new Date().getTime(); | ||
this.state.token = tokens[this.id]; | ||
} else { | ||
this.generateToken(false); | ||
} | ||
// load token from file | ||
var tokenFilePath = process.cwd() + "/browser-security-tokens.json"; | ||
let tokens = fs.existsSync(tokenFilePath) | ||
? JSON.parse(fs.readFileSync(tokenFilePath, "utf8")) | ||
: {}; | ||
if (tokens.hasOwnProperty(this.id)) { | ||
lastTokenChange = new Date().getTime(); | ||
this.state.token = tokens[this.id]; | ||
} else { | ||
this.generateToken(false); | ||
} | ||
this.logDebug("Loaded security token."); | ||
this.logDebug("Loaded security token."); | ||
io.on("connection", socket => { | ||
// authenticate on connect | ||
socket.on("authenticate", data => { | ||
if (data.token != this.state.token) { | ||
socket.disconnect(); | ||
return; | ||
} | ||
io.on("connection", socket => { | ||
// authenticate on connect | ||
socket.on("authenticate", data => { | ||
if (data.token != this.state.token) { | ||
socket.disconnect(); | ||
return; | ||
} | ||
authenticatedClients.push(socket); | ||
authenticatedClients.push(socket); | ||
// refresh client and set src of iframe | ||
socket.emit("refresh", {contentUrl: contentUrl}); | ||
// refresh client and set src of iframe | ||
socket.emit("refresh", {contentUrl: this.contentUrl}); | ||
// send jwt token to client | ||
if (authorizationToken) socket.emit("jwtToken", {jwtToken: authorizationToken}); | ||
// send jwt token to client | ||
if(this.authorizationToken) socket.emit("jwtToken", {jwtToken: this.authorizationToken}); | ||
// remove client from authenticated clients on disconnect | ||
socket.on("disconnect", () => { | ||
for (var i = 0; i < authenticatedClients.length; i++) | ||
if (authenticatedClients[i].id == socket.id) | ||
authenticatedClients.splice(i, 1); | ||
// remove client from authenticated clients on disconnect | ||
socket.on("disconnect", () => { | ||
for (var i = 0; i < authenticatedClients.length; i++) | ||
if (authenticatedClients[i].id == socket.id) | ||
authenticatedClients.splice(i, 1); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
// Insert/render external host into server website. | ||
configuredLiveHtml = handlebar | ||
.compile(fs.readFileSync(__dirname + "/server/browser.html").toString()) | ||
.bind(this)({ | ||
host: this.configuration.externalHost, | ||
id: this.id | ||
}); | ||
// Insert/render external host into server website. | ||
configuredLiveHtml = handlebar | ||
.compile(fs.readFileSync(__dirname + "/server/browser.html").toString()) | ||
.bind(this)({ | ||
host: this.configuration.externalHost, | ||
id: this.id | ||
}); | ||
this.logDebug('Configured socket-io server in the "browser.html".'); | ||
this.logDebug('Configured socket-io server in the "browser.html".'); | ||
app.use(cookieParser()); | ||
app.use("/public", express.static(__dirname + "/server/public")); | ||
app.use("/tokenpad", (request, response) => { | ||
response.sendFile(__dirname + "/server/tokenpad.html"); | ||
}); | ||
app.use(cookieParser()); | ||
app.use("/public", express.static(__dirname + "/server/public")); | ||
app.use("/tokenpad", (request, response) => { | ||
response.sendFile(__dirname + "/server/tokenpad.html"); | ||
}); | ||
var content = (request, response) => { | ||
var content = (request, response) => { | ||
let now = new Date().getTime(); | ||
let difference = now - lastTokenChange; | ||
let now = new Date().getTime(); | ||
let difference = now - lastTokenChange; | ||
if (difference > 1100) setTimeout(() => this.generateToken(), 1000); | ||
if (difference > 1100) setTimeout(() => this.generateToken(), 1000); | ||
// send rendered html with markup | ||
if (mode == modeEnum.TEMPLATE) { | ||
response.send(renderedHtml); | ||
response.end(); | ||
} else { | ||
// send rendered html with markup | ||
if (mode == modeEnum.TEMPLATE) { | ||
response.send(renderedHtml); | ||
response.end(); | ||
} else { | ||
if(this.authorizationToken && mode == modeEnum.KIOSK) { | ||
// set jwt token | ||
response.cookie("thing-it-jwt-token", this.authorizationToken) | ||
} | ||
if (authorizationToken && mode == modeEnum.KIOSK) { | ||
// set jwt token | ||
response.cookie("thing-it-jwt-token", authorizationToken) | ||
} | ||
// provide proxied website | ||
proxy.web(request, response, { | ||
target: this.state.url | ||
}); | ||
} | ||
}; | ||
// provide proxied website | ||
proxy.web(request, response, { | ||
target: this.state.url | ||
}); | ||
} | ||
}; | ||
// custom url/template content | ||
app.use("/content", this.authenticate(), (request, response) => content(request, response)); | ||
// custom url/template content | ||
app.use("/content", this.authenticate(), (request, response) => content(request, response)); | ||
// kiosk mode content | ||
app.use("/kiosk*", this.authenticate(), (request, response) => content(request, response)); | ||
// kiosk mode content | ||
app.use("/kiosk*", this.authenticate(), (request, response) => content(request, response)); | ||
// proxy console paths to tip | ||
app.use("/console/*", this.authenticate(), (request, response) => { | ||
// proxy console paths to tip | ||
app.use("/console/*", this.authenticate(), (request, response) => { | ||
var proxyUrl = this.configuration.tip; | ||
var proxyUrl = this.configuration.tip; | ||
this.logDebug(request.baseUrl); | ||
if (request.baseUrl != "/console/content") | ||
proxyUrl += request.baseUrl.replace("/console", ""); | ||
else | ||
proxyUrl = this.state.url; | ||
if(request.baseUrl != "/console/content") | ||
proxyUrl += request.baseUrl.replace("/console", ""); | ||
else | ||
proxyUrl = this.state.url; | ||
proxy.web(request, response, {target: proxyUrl}) | ||
}); | ||
proxy.web(request, response, {target: proxyUrl}) | ||
}); | ||
// Display live content on root route | ||
app.use("/", this.authenticate(), (request, response) => { | ||
// Display live content on root route | ||
app.use("/", this.authenticate(), (request, response) => { | ||
// save token in a cookie | ||
response.cookie(this.id, this.state.token); | ||
// save token in a cookie | ||
response.cookie(this.id, this.state.token); | ||
response.header("Access-Control-Allow-Origin: *"); | ||
response.send(configuredLiveHtml); | ||
response.end(); | ||
}); | ||
this.logDebug("Registered routes"); | ||
response.header("Access-Control-Allow-Origin: *"); | ||
response.send(configuredLiveHtml); | ||
response.end(); | ||
}); | ||
this.logDebug("Registered routes"); | ||
// start http server | ||
httpServer.listen( | ||
parseInt(this.configuration.host.split(":")[1]), | ||
this.configuration.host.split(":")[0], | ||
() => { | ||
this.logDebug("HTTP server started on " + this.configuration.host); | ||
} | ||
); | ||
// start http server | ||
httpServer.listen( | ||
parseInt(this.configuration.host.split(":")[1]), | ||
this.configuration.host.split(":")[0], | ||
() => { | ||
this.logDebug("HTTP server started on " + this.configuration.host); | ||
} | ||
); | ||
this.logInfo("Browser sucessfully started."); | ||
this.logDebug("Browser sucessfully started."); | ||
deferred.resolve(); | ||
}) | ||
.catch((error) => { | ||
this.logError(error); | ||
deferred.resolve(); | ||
deferred.reject(error); | ||
}); | ||
@@ -317,3 +323,3 @@ return deferred.promise; | ||
this.logDebug("Browser sucessfully stopped."); | ||
this.logInfo("Browser successfully stopped."); | ||
}; | ||
@@ -343,66 +349,71 @@ | ||
if (mode == modeEnum.TEMPLATE) { | ||
this.state.url = ""; | ||
this.template = handlebar | ||
.compile( | ||
this.state.hasOwnProperty("template") | ||
? this.state.template | ||
: this.configuration.template | ||
) | ||
.bind(this); | ||
// Insert/render markup into website. | ||
this.render(); | ||
this.logDebug("Rendered markup into website."); | ||
} else if (mode == modeEnum.KIOSK) { | ||
if (!this.state.hasOwnProperty("url")) | ||
this.state.url = this.configuration.url; | ||
this.logInfo("Running on mode: " + mode); | ||
// TODO: REMOVE THIS STATIC ****... | ||
const proxy = "https://www.thing-it.com/"; | ||
this.state.tip = this.configuration.tip; | ||
// get jwt token from tip1 to authenticate clients | ||
if (this.configuration.username && this.configuration.password) { | ||
var options = { | ||
uri: proxy + "portal/login", | ||
body: JSON.stringify({ | ||
account: this.configuration.username, | ||
password: this.configuration.password | ||
}), | ||
method: "POST", | ||
headers: { | ||
"content-type": "application/json" | ||
} | ||
}; | ||
if (!this.state.hasOwnProperty("templateMarkup") || this.state.templateMarkup == null) // fall back to configuration markup | ||
this.state.templateMarkup = this.configuration.templateMarkup; | ||
request(options, (error, response) => { | ||
if (error) { | ||
this.logError(error); | ||
} else { | ||
this.authorizationToken = JSON.parse(response.body).jwtToken; | ||
this.authorizationToken | ||
return new Promise((resolve, reject) => { | ||
if (mode == modeEnum.TEMPLATE) { | ||
this.state.url = ""; | ||
template = handlebar | ||
.compile(this.configuration.template) | ||
.bind(this); | ||
// Insert/render markup into website. | ||
this.render(); | ||
this.logDebug("Rendered markup into website."); | ||
resolve(mode); | ||
} else if (mode == modeEnum.KIOSK) { | ||
if (!this.state.hasOwnProperty("url")) | ||
this.state.url = this.configuration.url; | ||
this.requestJWT() | ||
.then((response) => { | ||
authorizationToken = JSON.parse(response).jwtToken; | ||
authorizationToken | ||
? this.logDebug("Authenticated in TIP.") | ||
: this.logInfo("Authentication in TIP failed!"); | ||
} | ||
this.contentUrl = this.state.url.replace(this.configuration.tip, ""); | ||
}); | ||
contentUrl = this.state.url.replace(this.configuration.tip, ""); | ||
resolve(mode); | ||
}) | ||
.catch(error => reject(error)); | ||
} else { | ||
if (!this.state.hasOwnProperty("url") && this.state.mode == null) | ||
this.state.url = this.configuration.url; | ||
else if (!this.state.hasOwnProperty("url") || this.state.url == "") | ||
this.state.url = "https://example.org"; | ||
contentUrl = "/content"; | ||
resolve(mode); | ||
} | ||
} else { | ||
if (!this.state.hasOwnProperty("url") && this.state.mode == null) | ||
this.state.url = this.configuration.url; | ||
else if (!this.state.hasOwnProperty("url") || this.state.url == "") | ||
this.state.url = "https://example.org"; | ||
}); | ||
}; | ||
// refresh clients | ||
this.contentUrl = "/content"; | ||
this.refresh(); | ||
} | ||
Browser.prototype.requestJWT = function () { | ||
this.state.tip = this.configuration.tip; | ||
this.state.template = this.configuration.template; | ||
// get jwt token from tip1 to authenticate clients | ||
// TODO: REMOVE THIS STATIC ****... | ||
const proxy = "https://www.thing-it.com/"; | ||
if (!this.state.hasOwnProperty("templateMarkup") || this.state.templateMarkup == null) // fall back to configuration markup | ||
this.state.templateMarkup = this.configuration.templateMarkup; | ||
var options = { | ||
method: 'POST', | ||
uri: proxy + "portal/login", | ||
body: JSON.stringify({ | ||
account: this.configuration.username, | ||
password: this.configuration.password | ||
}), | ||
headers: { | ||
"content-type": "application/json" | ||
} | ||
}; | ||
this.logDebug("Running on mode: " + mode); | ||
return rp(options); | ||
}; | ||
@@ -428,3 +439,3 @@ | ||
// Render website with new markup | ||
renderedHtml = this.template( | ||
renderedHtml = template( | ||
JSON.parse( | ||
@@ -442,3 +453,3 @@ this.state.hasOwnProperty("templateMarkup") | ||
var data = {}; | ||
if(contentUrl) data.contentUrl = contentUrl; | ||
if (contentUrl) data.contentUrl = contentUrl; | ||
@@ -466,11 +477,26 @@ // Refresh iframe on live website | ||
Browser.prototype.updateState = function (params) { | ||
let token = this.state.token; | ||
params.token = this.state.token; | ||
if(this.state == params) { | ||
this.logDebug("Update state: Nothing to change"); | ||
return; | ||
} | ||
this.state = params; | ||
this.state.token = token; | ||
this.recognizeMode(); | ||
this.recognizeMode() | ||
.then(() => { | ||
this.publishStateChange(); | ||
this.refresh(); | ||
this.publishStateChange() | ||
}) | ||
.catch(() => { | ||
this.refresh(); | ||
this.publishStateChange() | ||
}); | ||
}; | ||
@@ -477,0 +503,0 @@ |
@@ -18,3 +18,3 @@ module.exports = { | ||
"templateMarkup": "{\"company\":\"Thing-IT\"}", | ||
"url": "https://www.thing-it.com/console/kiosk/calendar?mesh=5bed35dc7fc65a28e66d7841&calendar=5beda33f4e30c4c33d4a66a4", | ||
"url": "https://progme.de", | ||
"host": "localhost:8001", | ||
@@ -21,0 +21,0 @@ "externalHost": "localhost:8001", |
{ | ||
"name": "thing-it-device-browser", | ||
"version": "2.2.9", | ||
"version": "2.3.0", | ||
"description": "[thing-it-node] Device Plugin to show a website", | ||
@@ -22,2 +22,3 @@ "authors": "Marvin Erkes", | ||
"request": "^2.88.0", | ||
"request-promise": "^4.2.2", | ||
"socket.io": "^2.1.1" | ||
@@ -24,0 +25,0 @@ }, |
@@ -22,2 +22,32 @@ var assert = require("assert"); | ||
}); | ||
describe('Start testing', function () { | ||
it('Updating state', function () { | ||
setTimeout(() => { | ||
testDriver.devices[0].updateState( | ||
{ | ||
tip: 'https://www.thing-it.com/console', | ||
templateMarkup: '{"company":"Eiermann"}', | ||
url: '', | ||
token: 150553, | ||
mode: "template" | ||
} | ||
); | ||
}, 20000); | ||
setTimeout(() => { | ||
testDriver.devices[0].updateState( | ||
{ | ||
tip: 'https://www.thing-it.com/console', | ||
templateMarkup: '{"company":"Eiermann"}', | ||
url: 'https://www.thing-it.com/console/kiosk/calendar?mesh=5bed35dc7fc65a28e66d7841&calendar=5beda33f4e30c4c33d4a66a4', | ||
token: 150553, | ||
mode: "kiosk" | ||
} | ||
); | ||
}, 30000); | ||
}) | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
772448
1814
8
+ Addedrequest-promise@^4.2.2
+ Addedbluebird@3.7.2(transitive)
+ Addedlodash@4.17.21(transitive)
+ Addedrequest-promise@4.2.6(transitive)
+ Addedrequest-promise-core@1.1.4(transitive)
+ Addedstealthy-require@1.1.1(transitive)