Creating Sandbox Window from Service Worker - google-chrome-extension

I have a Chrome extension which requires a sandbox so that I can use a custom content security policy and also requires a Service Worker so I have a script running that is persistent. I would like the Service Worker to open a new (sandbox) window, and then be able to communicate with this sandbox by using postMessage.
I have tried three methods to create this window but none of them quite work for me:
I tried chrome.windows.create which is able to create the window, but I don't have accese to postMessage (or at least I don't know how to access postMessage this way).
I tried window.open which returns a WindowProxy object which I can call postMessage on. However this only works where the window context is available and this is not the case in Service Worker.
I tried clients.openWindow however I ended up with an error "Not allowed to open a window".
Is there anyway to create a (sandboxed) window which allows me to use postMessage from a Service Worker in a chrome extension?

Related

Electron 22.0.3 On Linux Session Cookies Dilemma

I have created my first Electron app which is a dashboard that collects a list of URLs from a mongodb and scrolls through each URL using a predefined time delay between URLs. I am using this to display information screens from different BMS systems (Building Management / Building Automation systems) which all reside on the same local network. The BMS systems require user logins in order to view the screens. I have created some code in my preload script which injects the necessary login credentials into the proper DOM elements and activates the submit method. (I know this is not 100% secure but to help that situation, I am running the dashboard in kiosk mode with DevTools disabled. Further more, the systems I am connecting to do not contain any super sensitive data only temperature readings, etc.) I create the main browser window once and call the loadURL method in a different function which loads the next URL in the list. The problem I am having is that after rotating between all of the displays in system-A, when I load the URLs from system-B, the app has to login to that system (Totally expected behavior), however, when my logic finishes displaying the URLs from system-B and loops back to system-A, my app has to login to system A again even though I had already logged into system A prior to displaying system-B screens and I never destroyed the original browser window. Is there a way to maintain persistent session info to prevent this reoccurring login process when switching from system to system? Ideally I would like to maintain the persistent session info until I quit the app.
I have read over the documentation for the session and cookies methods, but being new to JavaScript and Electron, I couldn't quite wrap my head around how to implement the classes. Any help with this would be greatly appreciated.

Background page runs, but popup says 'You do not have a background page.' when using getBackgroundPage()

I have a very simple background page for a Chrome extension:
chrome.runtime.onInstalled.addListener((reason) => {
console.log(reason);
});
The background page runs when my extension is loaded:
The extension also has a popup that runs getBackgroundPage(), using:
const serviceWorkerWindow = await chrome.runtime.getBackgroundPage();
This fails with:
Uncaught (in promise) Error: You do not have a background page.
How do I make getBackgroundPage() work?
The getBackgroundPage() method doesn't retrieve the background script, it retrieves the window object associated with the background script. As you know, Manifest V3 doesn't use background scripts, it uses a service worker. Service workers by definition do not have access to window objects.
What is your use case? Maybe I could suggest an alternative approach.
Answering my own question based on #wOxxOm's comment. If wOxxOm writes their own answer I'll mark that as correct.
My expectation based on Google's documentation was that getBackgroundPage():
retrieves the JavaScript 'window' object for the background page running inside the current extension/app.
In modern JS terms, this would be the globalThis for the service worker (the service workers is still referred to as background in manifest v3.
As wOxxOm said.
This API won't work. The documentation is simply outdated because the ManifestV3 team consists of just a few devs who don't have time to do everything.
Essentially the Chrome Extension documentation is not adequately maintained. There is an outstanding W3C issue on the topic of whether getBackgroundPage should work with service workers - thanks #erosman. The best way to communicate between a popup and a background service worker is via extension messaging. Ie:
chrome.runtime.sendMessage()
And:
chrome.runtime.onMessage.addListener()

How to simulate BT and WiFi connection during UI automation test with fastlane?

I am beginner of iOS testing and I really need help. Thank you in advance.
I've tried to implement a simple test with fastlane to create screenshots and evaluate if all needed elements exist (fastlane snapshot, I follow most common tutorials and up to now everything works fine). App which is tested needs a WiFi and Bluetooth connection to open some tabs. I have no idea how to manage it. When app is redirected to view where connection is checked and test wait (methods such as sleep(30) or waitForExists(app.otherElements["snapshotReady"], waitSeconds: 60) but nothing happens and app cannot be loaded to the next view (generally, when app works on device context is switched to the next view).
I could not find any programatically method anywhere to manage it.
The best way to do this to look for the FASTLANE_SNAPSHOT key in the UserDefaults that is inserted automatically by snapshot.
if UserDefaults.standard.bool(forKey: "FASTLANE_SNAPSHOT") {
// runtime check that we are in snapshot mode
}
You can use logic like this to simulate any user interfaces that you may need.
More info can be found at - https://docs.fastlane.tools/actions/snapshot/#launch-arguments

Google Chrome extension communicate with Panel

I'm trying to develop a simple Chrome extension. It just have to access to an object myVar from my web page and print it into a panel as a table. (I'm using Yeoman generator, so basically everything is there)
background.js // to add a runTime.onMessage listener
contentscript.js // to inject custom.js, add a listener to a custom event and fire the runTime.sendMessage
custom.js // to retrieve myVar and dispatch the custom event.
devtools.js // to create the extension Panel
devtools.html // contains just devtools.js
panel.html // basic html structure of my panel, no js.
So, what I was able to do is to inject a custom script into the web page and use event listeners and chrome messaging to pass MyVar.
What I'm missing is how to interact with the panel, I'm kind of lost.
Once it's initialized I don't know how to debug, access its DOM, communicate with background.js or contentscript.js.
Any ideas?
thank you!
Once it's [the panel] initialized I don't know how to debug, access its DOM, communicate with background.js or contentscript.js.
To debug it, you can detach the Dev Tools panel into a window and then invoke Dev Tools for that with Ctrl/Cmd + Shift + I.
It's a frame, so it's a self-contained document; to access its DOM you'll need a script in there.
To communicate, a devtools panel has access to chrome.runtime messaging functions to initiate communication with the background, even though it seems that the other way is impossible. It's usual to open a port with chrome.runtime.connect, with corresponding chrome.runtime.onConnect in the background script, and use it for two-way communication. Bonus, the sender object will contain the tab ID that DevTools is attached to.
Direct communication with a content script is impossible; you need to use the background as a proxy. Here's an old but thorough answer.

How to persist PNaCl process within a Chrome Extension

My team and I have created a Chrome Extension which bundles a PNaCl application to handle multimedia encoding & muxing which is adapted from the Pepper SDK (version 39) examples and the online SDK tutorial. The application's purpose to capture content from the user's desktop, tab, and webcam in order to create multimedia files.
The extension works as expected while it's visible but the PNaCl process is stopped/unloaded when the extension is hidden. I need to know what is the best strategy to persist a PNaCl process when the Chrome Extension is no longer visible.
The PNaCl app is embedded in my primary UI code (in my case this is set to index.html). The extension contains Background Pages which continues to process requests when hidden so I'm confident the manifest.json permissions and process work as expected. Additionally there are no exceptions.
So far I've attempted:
Make a background JavaScript page the interface to the PNaCl application so it's reference is stored in the background page which should persist.
Create a Chrome Window in order to persist PNaCl application and present a live-preview of the captured stream while the extension is hidden.
(Ongoing) Embed the PNaCl container a background HTML page rather primary HTML page which represents the extension UI.
So far none of them have persisted the PNaCl process.
The relevant parts of my manifest.json:
{
"manifest_version": 2,
"minimum_chrome_version": "39.0.0.0",
"offline_enabled": true,
"permissions":[
"desktopCapture",
"tabCapture",
"tabs",
"unlimitedStorage"
],
"browser_action":{
"default_popup": "index.html"
},
"background":{
"scripts": ["helpers.js", "background.js", "capture_state.js"],
"persistent": true
}
}
If I'm able to resolve before I get a response I'll respond with a solution.
We've resolved the issue despite the lack of documentation.
Here are the primary issues:
Issue #1 - Listener ID in front-end extension code.
We had our id="listener" inside of our front-end extension code (which is unloaded when the extension is hidden) and manually specifying a background.html page doesn't allow us to use background JavaScript files (a requirement of our application).
Resolution: We dynamically added the id="listener" and altered the common.js file using document.addElement to the generated background page (which is automatically created when the extension is loaded).
Issue #2 - getUserMedia method invoked in front-end extension code.
Our application requires that the streams returned from getUserMedia persist so that we can capture from the mic, webcam, and desktop in the background even if the extension is hidden.
Since we requested these in the front-end extension code (to create a live-preview) we thought we could simply pass them into the generated background page and they would persist.
What we found is that when the extension is hidden reading from the streams halts immediately without error. We found this out by digging through our code and monitoring the Chrome Task Manager to see that when the extension was hidden it's CPU usage goes to 0 but it's memory stays elevated (much like phenomena you'd expect when a thread deadlocks or is blocking).
Resolution: Moving the getUserMedia invocation to one of the background scripts and using the streams it returns resolves this.
If you create the PNaCl object in the popup window, which is supposed to be a throwaway destroyed whenever it loses focus, you won't be able to persist it.
It's not losing visibility, it's just completely unloaded.
Your "Ongoing" idea of putting the <embed> into the background page is probably correct.

Resources