Get OS display enumeration via nodejs - node.js

I'm looking at AppJS as a possible candidate to build a cross-browser application. AppJS runs HTML5 content with a Chromium window with hooks to NodeJS.
Is there a NodeJS module that can give me an enumeration of displays currently active? I need to support dual-monitor setups and knowing the bounds of each display is required.
I've search the Node npm directory with no luck so far.
Update:
Based on sihorton's answer, I'm playing with a javascript approach. Browser security prohibits my first approach from working in normal Chrome, but I will try this on AppJS chromium when I get home. Code here and here.
The basic approach is running code like:
OpenWindow('http://jsbin.com/axiwad/3/','test',400,500);
and then the opened window runs:
window.moveTo(screen.width+2, 0);
setTimeout(function(){
$(".s2w").html(screen.width+2);
$(".s2h").html(screen.height);
}, 500);
The issue of course, is that browser do not allow a moveTo outside the active screen boundary. It remains to be seen if AppJS chromium fork allows this.

If you are running AppJS then you can do the screen detection using tricks in javascript running in the chromium window part of AppJS. I quick google search found the following link, I am sure there are others and if you experiment enough then hopefully you will get a cross platform solution:-
http://archive.cpradio.org/code/javascript/dual-monitors-and-windowopen/
An alternative approach if you want to stay node-native is to implement a common api and then implement separate code behind that for each platform. I don't personally know of any better solution at the moment, and obviously this is less preferable to the javascript solution above. However if you must go this route then there is node edge:
http://tjanczuk.github.io/edge
This lets you run .net code from nodejs so you should be able to cover windows machines with that api. For linux you could then look into connecting into dbus:
https://github.com/sidorares/node-dbus
https://npmjs.org/package/dbus-native
Hopefully you can find appropriate sample code on the internet to get display properties using dbus and .net and then just plug it together and go from there.

Related

Is it possible to run Puppeteer on server-side?

I want to use Puppeteer to automate a particular task. However, for user-friendly purposes, I thought about implementing it within a chrome extension. Browsing the web, I encountered this article https://dev.to/tchan/web-automation-using-puppeteer-inside-a-chrome-extension-318o To be honest, I could not absorb some context from the article since I don't have enough experience about that kind of stuff. According to the article, I had to activate remote debugging for chrome. So I did, yet could not access localhost, thus webSocketDebuggerUrl property, either. Some connection refusal error hit on the browser while trying to access. But the thing about I care is that in the case that it even works, if I had published this extension, one would have to activate his/her remote debugging for chrome, too and that would not be much of user-friendly. In the end, I thought that if it is possible to run Puppeteer on nodejs with your own computer, it should be possible to run it on server-side(nodejs) of a website, too. Thus, you wouldn't need an extension, so the website itself would implement the task I have intended. Sorry for this long story-wise problem, but still I don't have much knowledge of server-side languages. So is it possible to run Puppeteer on server-side? So what would you recommend to do?
Thanks.

Security Implications in Electron as a Web Browser

I asked this question a little over a week ago on the Atom forums (link below), and didn't receive a response, so I am reposting it here in the hopes that someone may be able to provide insight on my problem.
Recently, I have taken up an open source project which uses Electron as it’s front-end. This project has two requirements: it must be cross-platform, and it must have an embedded web browser (which should be able to browse the web and render content like a typical browser). Considering the rather large footprint Electron has already netted my application, it seems like a bad idea to attempt to use another embedded web framework alongside it. So, in the interest of simplifying my project and retaining the UI built on top of Electron, I am looking into using Electron itself as the web browser. Here’s where I’ve come into a problem.
In a security page for Electron’s documentation, it is explicitly stated that,
it is important to understand … Electron is not a web browser
This quote comes within the context that Electron–or rather the code running on top of it–carries the unique ability to interact with the user’s operating system, unlike typical web applications. The page goes on to say,
displaying arbitrary content from untrusted sources poses a severe security risk that Electron is not intended to handle
At this point, I was tempted to give up on the idea of using Electron as an inbuilt browser, but further down on that same page, you can find another very interesting tidbit:
To display remote content, use the <webview> tag or BrowserView , [and] make sure to disable the nodeIntegration and enable contextIsolation
Link: https://electronjs.org/docs/tutorial/security#isolation-for-untrusted-content
First, in regard to using webviews, Electron’s own documentation recommends outright avoiding them:
Electron’s webview tag is based on Chromium’s webview , which is undergoing dramatic architectural changes. This impacts the stability of webviews , including rendering, navigation, and event routing. We currently recommend to not use the webview tag and to consider alternatives, like iframe , Electron’s BrowserView , or an architecture that avoids embedded content altogether.
Link: https://electronjs.org/docs/api/webview-tag
Seeing as though I cannot avoid embedded content, I opted to look into using a BrowserView, but what I found was not very motivating either. The advice, as it stands, is to do two things:
disable nodeIntegration
enable contextIsolation
After looking at the security and best-practices page, I will also append the following steps:
deny session permission requests from remote content (webcam, microphone, location, etc.)
catch webview elements in creation and strip default privileges
disable the creation of new windows
disable the remote module
That is a fair amount of steps to undergo in securing external content. Not to mention, there were several additional warnings scattered through the best practices page such as the following:
(On verifying webview options before creation)
Again, this list merely minimizes the risk, it does not remove it. If your goal is to display a website, a browser will be a more secure option.
Link: https://electronjs.org/docs/tutorial/security#11-verify-webview-options-before-creation
(On disabling the remote module)
However, if your app can run untrusted content and even if you sandbox your renderer processes accordingly, the remote module makes it easy for malicious code to escape the sandbox and have access to system resources via the higher privileges of the main process.
Link: https://electronjs.org/docs/tutorial/security#15-disable-the-remote-module
Not to mention, upon navigation to the BrowserView page, the whole class is listed as experimental.
This all isn’t even to mention the added attack surface created by Electron, such as a vulnerability in the webview component just last year: CVE-2018-1000136
Now, taking into account all of the above, numerous developers have still opted to create web browsers that routinely consume external and uncontrolled content using Electron.
Browser’s using Electron (linked directly from Electron’s website):
https://electronjs.org/apps/wexond
https://electronjs.org/apps/dot
https://electronjs.org/apps/beaker-browser
To me, it seems irresponsible to submit users to the above security implications as a trade-off for convenience.
That being said, my question is: can you safely, to the point at which you could ensure the integrity of your users, implement web browsing capabilities for uncontrolled content using Electron?
Thank you for your time.
Link to the original post:
https://discuss.atom.io/t/security-implications-in-electron-as-a-web-browser/70653
Some ideas that don't fit into a comment box:
[the project] must have an embedded web browser
So I presume then that this project isn't just a web browser. There's other content there that may have access to Node, but you just want the embedded-web-browser portion of it to be sandboxed appropriately, right?
Regarding the comments about <webview>, yes, it is considered unstable and Electron recommends using a BrowserView instead. I don't think that the fact that it's marked as "experimental" should necessarily deter you from using it (especially considering that the Electron team is recommending it [though maybe as the best of two evils]).
Experimental doesn't imply it's unstable. It can just mean that the Electron team is experimenting with this approach, but this approach may change in the future (at which point I would expect Electron to provide a transition path forward). Though this is one possible interpretation and ultimately Electron would have to comment on this.
The advice... is to do two things:
disable nodeIntegration
enable contextIsolation
I would also make use of the sandbox option inherited from BrowserWindows. BrowserView's docs on the constructor options say:
webPreferences Object (optional) - See BrowserWindow.
which tells me that BrowserView accepts the same options as BrowserWindow.
You would set it up like so:
new BrowserView({ webPreferences: {
sandbox: true,
nodeIntegration: false,
contextIsolation: true,
preload: "./pathToPreloadScript.js"
}});
See more information about this approach here. The preload script is what would expose some Node IPC APIs to the sandboxed content you're loading. Note the Status section at the bottom, which says:
Please use the sandbox option with care, as it is still an experimental feature. We are still not aware of the security implications of exposing some Electron renderer APIs to the preload script
If the content you're loading in the BrowserView never needs to communicate back to the application, then you don't need a preload script at all and can just sandbox the BrowserView.
After looking at the security and best-practices page, I will also append the following steps:
deny session permission requests from remote content (webcam, microphone, location, etc.)
catch webview elements in creation and strip default privileges
disable the creation of new windows
disable the remote module
Sure, those sound reasonable. Note that if your embedded browser needs to be able to open new windows (via window.open or <a target="_blank" />) then you'd have to allow popups.
That is a fair amount of steps to undergo in securing external content.
Sure, but is your main concern with the security of the app, or with how much work it takes to make it secure? Browser developers need to consider similar things to ensure webpages can't get access to the OS. It's just part of the game.
Again, this list merely minimizes the risk, it does not remove it. If your goal is to display a website, a browser will be a more secure option.
This is just saying that if all you're trying to do is display a website, then just use a browser since that's what they're there for.
If you need to do other things, well then you can't use a browser, so you'll have to make your own app, making sure it's reasonably secure.
I think that if you follow what's recommended in the Security document and keep up to date with new Electron releases, then you're doing the best you can do.
As for whether that's good enough, I can't say. It depends on what you're developing and what you're trying to protect against.
However, my thoughts can't substitute the more expert opinions of those on the Electron team. This question could certainly use some guidance from them.

Node-webkit Browser Plugin

Description of the Problem
As NPAPI plugins will be deprecated in Chrome (maybe in Firefox too soon) and being part of a project (WebChimera) that is based on an NPAPI plugin. I've been thinking of different solutions to keep NPAPI support in browsers. (as porting this plugin to NaCL is currently impossible, but the plugin can be used in a frozen version of node-webkit that currently supports NPAPIs)
So I was wondering if it is possible for a browser page to open a node-webkit app on the user's PC, then using JS with/without jQuery to send data about the html element where the Node-Webkit window (with always on top set) should be to the app (maybe through a websocket) to always position it there.
I know I can get a html element's size, position in JavaScript, I also know I can track the scroll of the user and browser tab changes to do the necessary changes to the window size, position and visibility.
The Question
The thing that truly stops me from even attempting this is how would I know when a browser is not fullscreen, and how would I know the browser's position on the screen if it is not fullscreen either from the on page JS or from node-webkit directly. Another thing that should be a concern is what screen is the browser window on.
Am I the only one that has thought of such an endeavor with node-webkit, are there any open source projects attempting this?
Any thoughts or comments on this would be greatly appreciated as a solution to this would not only save NPAPI plugins in the near future but will also open a world where Node-Webkit can also be used as a viable solution to build browser plugins too. :)
This would involve a lot of painful hackery. You'd have to solve most of these issues on all platforms independently and rely on a lot of implementation details.
As a possible alternative, check out the plans for FireBreath 2.0 which will support plugins which can be loaded via NPAPI, ActiveX, and Native Messaging via a new protocol called FireWyrm. Currently there is no drawing support when using the FireWyrm interface and only Native Messaging is supported. Additionally it's not quite finished, though I'm getting close =]
Now it's possible to use libvlc to play video directly on NW.js/Electron page: https://www.npmjs.com/package/webchimera.js
What this project is: it's low level (written in C++) addon which use libvlc and allow decode video frames to JS ArrayBuffer object. In turn this ArrayBuffer object could be drawn on HTML5 canvas directly or with WebGL. This project use Node.js/V8 API directly and not use NPAPI at all, so will live even after NPAPI deprecation. Another good thing - perfomance of this (espesially if use WebGL) is comparable with original VLC player perfomance.
Simple usage example available at: https://github.com/jaruba/wcjs-player

Can I embed a browser inside a screensaver? On both Windows and Macs?

Here's the deal. I've animated + coded a variety of 'screensavers' in Actionscript3/Flash. They make extensive use of the timeline, AS3 code, the TweenLite library, and embedded fonts. That's the limit of my programming knowledge. I've tried, to no avail, to convert my .SWFs into screensaver files using a variety of software, such as InstantStorm. Somehow it never works, the code never executes properly, it's a disaster.
So, I'm wondering if it's possible to make a screensaver that simply contains an embedded browser, and have it point to my .SWF file, hosted on my web-server. Basically, imagine a full-screen website acting as a screensaver.
If this is possible, what is the EASIEST and FASTEST way for me to whip up a solution for both PCs and Macs? Language, etc. I'm hoping something that has a library I can simply draw from to embed the browser view :)
My startup is developing a product to do exactly this, it's called Screensaver Ninja and you can find it at https://Screensaver.Ninja.
You can set many different web pages with different timers. The configuration tool allows you log in and navigate to the page you want to display:
It uses WebKit, on Mac OS X it uses Safari's and on Windows it uses Chrome's and in both cases it has a separate session from any other browser installed on the computer.
Here's a small Windows-only solution:
https://github.com/cwc/web-page-screensaver/releases
You could modify this open-source one for the Mac so that it's hard-coded to your URL:
http://www.liquidx.net/blog/2010/11/13/webviewscreensaver-for-mac/
Modify hasConfigureSheet() to return NO and change the URL in kScreenSaverDefaultURL. And change the name!

Why does google.com look different on blackberry & phonegap vs. blackberry & browser

I'm tyring to get phonegap up and running on blackberry storm (9530 simulator). I had been testing my webapp from withing BB's built in browser, and it was looking ok, but then it totally bit once I tried to look at the some code from within phonegap, even though I was pointing phonegap to the same url (I hadn't yet gotten to the point of running code locally on the device).
I tried a test case on google and got similiar results. see below. I suspect that I'm missing something basic here. I would have expect both images to be nearly identical.
Browser
http://www.eleganttechnologies.com/outside/ImgDeviceBB9530WebGoogle.jpg
Phonegap
http://www.eleganttechnologies.com/outside/ImgDeviceBB9530PgGoogle.jpg
[Update]
To shed some light on what is happening, I ran the browser and the embedded browser (phonegap) against the W3 mobile web acid test: http://www.w3.org/2008/06/mobile-test/
I definitely notice differences between the two, but I don't yet know the 'why' and the 'how-to-address'.
Acid via built-in browser
(source: eleganttechnologies.com)
BTW - I ran this earlier today and got a couple more green square than just now.
Acid via browser embedded into phonegap
http://www.eleganttechnologies.com/outside/ImgDeviceBb9530PgAcid.jpg
Disclaimer: I don't know anything about phonegap, but have a pretty good theory. By default the embedded browser control on BlackBerry uses an older version of the rendering engine than the BlackBerry browser itself does.
At the BlackBerry developer conference last year, a talk was given about this, and there's an undocumented option to use the newer rendering engine. \
The option ID is 17000 (yes, a magic number, which could change, use at your own risk etc), and should be set to true. Not sure how you'd pass this option through phonegap (I'm not familiar with the toolkit) but using the BlackBerry APIs it's something like:
BrowserContent content;
...
content.getRenderingOptions().setProperty(RenderingOptions.CORE_OPTIONS_GUID, 17000, true);
I don't know the specifics of the browsers you are using, but I do know that most of the big sites will detect your OS + browser combination to decide what HTML to show you.
If Google is seeing a different user agent, you might get a generic mobile version of the HTML instead os the Blackberry specific HTML you get for the built in browser.
If you have access to a web server, try hitting it with both browser setups and see if there is any difference in the log file. That might tell you something interesting.
As we can see in your Acid tests...
One browser (the built-in one) is reporting correctly as a BlackBerry9530, and the other (phonegap) is not presenting the user-agent ["Testing with ."].
In this case, Google is providing you with the default view of their homepage, whereas when you are reporting yourself as a BlackBerry device, you will get the BlackBerry specific rendering.
By the sounds of things, using phonegap is removing the default user-agent (most probably because it's not recognising your device). As phonegap is open-source, the best bet is to get in there, and debug it and find out what happens with the user-agent when the http requests leave the device and track it back from there.
Maybe one browser has capabilities that another one does not?
Hm. By looking at the screenshot I would say that the second page is probably missing some resources. It may be missing some images, scripts and the CSS files, which would explain different l&f. Knowing how Blackberry Browser Field API works, I would guess that the implementation that uses the BrowserField was not done correctly. Just my guess. In addition to that, when the browser field is initialized the caller needs to configure it properly by enabling the appropriate browser features - scripts, styles etc. Again, the API is done in a very weird way, I have gotten myself into this trap once. When setting the options, you cannot just create one mask (like CSS | WML | SCRIPT) and make one call. Options are numeric and, I believe, non-overlapping - but you still need to call the API for setting each option independently.
Also the way asynchronous loading of the resources for BrowserField takes time to understand.
Just my $0.02.

Resources