Websocket connection failing from Firefox extension - firefox

I have a Firefox extension which connects to a websocket server and sends a message. I packaged it with web-ext build, renamed the .zip to a .xpi. Last month I installed it in Firefox after setting xpinstall.signatures.required to false in about:config. I added the SSL key to the Firefox certificate manager. It worked for a month. Yesterday there was probably a Firefox update and now the extension is blocked becaue it is not signed. After some research, I found that the regular Firefox has not allowed unsigned extensions for a long time. It makes me wonder what version I had until yesterday; I am working on a Ubuntu 20.04 system I set up 2 months ago.
When the extension is loaded manually with about:debugging, the extension works as it did before (websocket creation is successful and a message is sent).
I read online that Firefox Developer edition allows unsigned extensions. But after following the exact same steps, I cannot get the extension to work with a .xpi or by temporarily loading the extension. It is the same error in both circumstances:
Firefox can’t establish a connection to the server at wss://localhost:9501/.
The extension has a manifest and a background script
manifest.json:
{
"description": "weblogging app",
"manifest_version": 2,
"name": "weblogger",
"version": "1.0",
"browser_specific_settings": {
"gecko": {
"id": "browser_logger#example.org",
"strict_min_version": "50.0"
}
},
"background": {
"scripts": ["background.js"]
},
"permissions": []
}
background.js:
var websocketArguments = 'wss://localhost:9501';
var connected = new Boolean(false);
var webSocket;
createWebsocket();
function onError(error)
{
console.log(`Error: ${error}`);
}
function createWebsocket()
{
webSocket = new WebSocket(websocketArguments);
webSocket.onerror = onWebSocketError;
webSocket.onopen = onWebSocketOpen;
}
function onWebSocketError(event)
{
console.log("WebSocket error observed:", event);
};
function onWebSocketOpen(event)
{
console.log("WebSocket open: ", webSocket.readyState);
webSocket.send("hello there");
connected = true;
};

Whatever the reason I could not get the extension to work when unsigned, it was just easier to get it signed.
https://addons.mozilla.org/en-CA/developers/

Related

Firefox add-on background script stopped in new Firefox version

My Firefox add-on background script stopped working in the latest version of Firefox. I've been using this add-on without changes for over a year now and it has been working perfectly so something in the recent Firefox updates broke the add-on. I'm on version 106.0.1 now. When I go to debug add-ons I can see the background script is stopped.
In the manifest.json (version 2)
"background": {
"scripts": [
"background.js"
],
"persistent": false
},
In the background.js
chrome.runtime.onInstalled.addListener(() => {
console.log('Installed');
setUpdateAlarm();
});
chrome.runtime.onStartup.addListener(() => {
console.log('Startup');
setUpdateAlarm();
});
chrome.alarms.onAlarm.addListener((alarm) => {
console.log('Alarm: ' + alarm.name);
switch (alarm.name) {
case 'Refresh':
updateCache();
break;
}
});
function setUpdateAlarm() {
updateCache();
chrome.alarms.create('Refresh', { periodInMinutes: 3 });
}
Keep in mind that neither of these files have changed but Firefox has been updated.

How to update self-hosted firefox webExtension

How do I configure my self-distrubuted firefox webExtension to auto-update, I have tried following MDN update doc but still unable to update.
My web Extension is hosted on a sub-domain name like
"https://files.example.com/myfile/extension.xpi"
My updates.json file resides at the same location with my .xpi file
This is a prototype of my updates.json
{
"addons": {
"updates": [ { "version": "1.2",
"update_link": "https://files.abc.com/myfiles/extension-1.2-an+fx.xpi" },
{ "version": "1.3",
"update_link": "https://files.abc.com/myfiles/extension-1.3-an+fx.xpi" }
]
}
}
This is the gibberish I get from browser console
1535658478365 addons.update-checker WARN onUpdateCheckComplete failed
to parse update manifest: [Exception... "Update manifest is missing a
required addons property." nsresult: "0x80004005 (NS_ERROR_FAILURE)"
location: "JS frame ::
resource://gre/modules/addons/AddonUpdateChecker.jsm ::
getRequiredProperty :: line 120" data: no] Stack trace:
getRequiredProperty()#resource://gre/modules/addons/AddonUpdateChecker.jsm:120
parseJSONManifest()#resource://gre/modules/addons/AddonUpdateChecker.jsm:130 onLoad()#resource://gre/modules/addons/AddonUpdateChecker.jsm:309 UpdateParser/<()#resource://gre/modules/addons/AddonUpdateChecker.jsm:241
It looks like your 'updates.json' is missing the add-on name and XPI hash. I would also test without the "+" in the file name, I think that caused me issues (Due to hosting server).
To view your add-ons UUID (ex "ADDONNAME#test.com") log into the developer hub, click edit information, then look under technical information. To generate an update_hash of your XPI file I would recommend VSCryptoHash, but any other program that generates a cryptographic hash will work.
{
"addons": {
"ADDONNAME#test.com": {
"updates": [
{ "version": "1.0.0",
"update_link": "https://files.abc.com/myfiles/extension-1.2-fx.xpi" ,
"update_hash": "sha256:blahblah" }
]
}
}
}
The console error says your manifest is missing something too. Here is an example based on mine that works.
"applications": {
"gecko": {
"id": "ADDONNAME#test.com",
"strict_min_version": "50.0",
"update_url": "https://webpage/Updatefile.json"
}
},

Protractor file download test fails when headless chrome

I am having an issue with a protractor test. It was working, but now (even thought nothing has changed) it is not.
The test is just opening the app (web application) and clicking on a button to download an image. The download should start straight away.
The problem is that the next instruction after the download event throws an exception, Failed: chrome not reachable. I am using the latest chrome and chrome driver versions.
The capabilites section for protractor is like this:
capabilities: {
browserName: 'chrome',
loggingPrefs: { browser: 'ALL' },
chromeOptions: {
args: ['--headless', '--window-size=1240,780'],
},
}
I am reading about using DevTools to enable downloads in headless mode (Page.setDownloadBehavior), but so far no luck.
Does anybody have this issue too? Any clue how to fix it?
Thanks.
There could be another easy way to do it, but this is what I have done in my test suite.
I used got library, however, you can use any library to send an HTTP post request.
Discussion about setting download directory in headless chrome: https://bugs.chromium.org/p/chromium/issues/detail?id=696481
let got = require('got');
let session = await browser.getSession();
let sessionId = session['id_'];
let params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': downloadDir }}
await got.post('http://localhost:4444/wd/hub/session/'+ sessionId + '/chromium/send_command', {body: JSON.stringify(params)})
If you have not disabled ControlFlow in your protractor config, change ASync/Await to .then.
An easier solution is to add these lines to your protractor.conf.js:
exports.config = {
...
onPrepare() {
...
browser.driver.sendChromiumCommand('Page.setDownloadBehavior', {
behavior: 'allow',
downloadPath: downloadsPath
});
}
};
From: https://bugs.chromium.org/p/chromium/issues/detail?id=696481#c196
Appendix
If you are to lazy to find a Download Path just paste this at the top of your protractor.conf.js:
var path = require('path');
var downloadsPath = path.resolve(__dirname, './downloads');
It will download the file to the e2e/downloads folder. Just use the same code in your tests to find out if the file downloaded.
This works for me:
chromeOptions: {
'args': [
'--headless',
'--disable-gpu',
'--test-type=browser',
'--disable-extensions',
'--no-sandbox',
'--disable-infobars',
'--window-size=1920,1080',
//'--start-maximized'
"--disable-gpu",
],
prefs: {
'download.default_directory': 'C:\\downloads',
'download.prompt_for_download':false,
'download.directory_upgrade':true,
"safebrowsing.enabled":false,
"safebrowsing.disable_download_protection":true
},
},

Ionic 3 Cordova ajax calls fail on Windows 10 (UWP)

I have attempted to ask this previously, buy got no real answers, and have now been struggling for over a month.
I just cannot get my ajax calls to work on an Ionic 3 Cordova application built for a Windows 10 UWP. They can access localhost, but not any outside connections.
The application works fine on both Android and iOS.
I am trying to test this locally on my dev machine. I use a certificate (bought) to sign the application, install this certificate, build the application for Windows, and am able to open up the built CordovaApp.Windows10_1.0.1.1_x86.appxupload, and then double click the embedded CordovaApp.Windows10_1.0.1.1_x86.appx file to install, which completes successfully. The install indicates the app need internet access.
In the config.xml, I have the following tags, as suggested elsewhere...
<allow-navigation href="*" />
<access origin="*" />
However, when I run, the http.get call just returns 0 with no other information. I can run in Visual Studio, and look at the returned error object, and get no further info, apart from this 0 return.
I have run fiddler, enabled the https decryption as explained here, but all I see in the response header is
HTTP/1.0 200 Connection Established
FiddlerGateway: Direct
StartTime: 13:44:21.686
Connection: close
The result in the main view actually shows 200, so I don't think this is showing me anything real.
I am at a complete loss. I have no where else to search. What could I be missing?
Should I be able to use external ajax on a Windows 10 machine, when I have sideloaded the application as here? I haven't tried from the store yet, as I don't want to upload until I know it works.
Any suggestions desperately welcomed. Surely someone has had an Ionic 3 application accessing external ajax working?
Thanks in advance for any help
[UPDATE 1]
If I run the application on the same machine, just using Ionic serve (so it just runs in the browser rather than hosted in the UWP), the ajax calls also work fine.
[UPDATE 2]
I have now created a Cordova application using the Visual Studio template, so taking all other frameworks out of the equation.
I used vanilla JavaScript to do my rest call...
document.addEventListener('deviceready', callUrl, false);
function callUrl() {
console.log('callUrl');
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://myserveraddress.com/myapp/testroute');
xhr.send(null);
xhr.onreadystatechange = function () {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200; // status 200 is a successful return.
if (xhr.readyState === DONE) {
if (xhr.status === OK)
console.log(xhr.responseText);
} else {
console.log('Error: ' + xhr.status);
}
}
};
I run this in the debugger, and even here I get an error (status code of 0).
Another thing I noticed when I open up the build package and look at the cordova_plugins.js file..
My Ionic app has the following...
cordova.define('cordova/plugin_list', function(require, exports, module) {
module.exports = [
{
"id": "cordova-plugin-console.logger",
"file": "plugins/cordova-plugin-console/www/logger.js",
"pluginId": "cordova-plugin-console",
"clobbers": [
"cordova.logger"
]
},
{
"id": "cordova-plugin-console.console",
"file": "plugins/cordova-plugin-console/www/console-via-logger.js",
"pluginId": "cordova-plugin-console",
"clobbers": [
"console"
]
},
{
"id": "cordova-plugin-device.device",
"file": "plugins/cordova-plugin-device/www/device.js",
"pluginId": "cordova-plugin-device",
"clobbers": [
"device"
]
},
{
"id": "cordova-plugin-device.DeviceProxy",
"file": "plugins/cordova-plugin-device/src/windows/DeviceProxy.js",
"pluginId": "cordova-plugin-device",
"merges": [
""
]
},
{
"id": "cordova-plugin-splashscreen.SplashScreen",
"file": "plugins/cordova-plugin-splashscreen/www/splashscreen.js",
"pluginId": "cordova-plugin-splashscreen",
"clobbers": [
"navigator.splashscreen"
]
},
{
"id": "cordova-plugin-splashscreen.SplashScreenProxy",
"file": "plugins/cordova-plugin-splashscreen/www/windows/SplashScreenProxy.js",
"pluginId": "cordova-plugin-splashscreen",
"runs": true
},
{
"id": "cordova-plugin-statusbar.statusbar",
"file": "plugins/cordova-plugin-statusbar/www/statusbar.js",
"pluginId": "cordova-plugin-statusbar",
"clobbers": [
"window.StatusBar"
]
},
{
"id": "cordova-plugin-statusbar.StatusBarProxy",
"file": "plugins/cordova-plugin-statusbar/src/windows/StatusBarProxy.js",
"pluginId": "cordova-plugin-statusbar",
"runs": true
},
{
"id": "ionic-plugin-keyboard.KeyboardProxy",
"file": "plugins/ionic-plugin-keyboard/src/windows/KeyboardProxy.js",
"pluginId": "ionic-plugin-keyboard",
"clobbers": [
"cordova.plugins.Keyboard"
],
"runs": true
}
];
module.exports.metadata =
// TOP OF METADATA
{
"cordova-plugin-console": "1.0.5",
"cordova-plugin-device": "1.1.4",
"cordova-plugin-splashscreen": "4.0.3",
"cordova-plugin-statusbar": "2.2.2",
"cordova-plugin-whitelist": "1.3.1",
"ionic-plugin-keyboard": "2.2.1"
};
// BOTTOM OF METADATA
});
Now, I notice every plugin in the module.exports.metadata also has an entry in the module.exports EXCEPT for cordova-plugin-whitelist!
If I open the same file for the Corvoda application created in VS, I see the following...
cordova.define('cordova/plugin_list', function(require, exports, module) {
module.exports = [];
module.exports.metadata =
// TOP OF METADATA
{
"cordova-plugin-whitelist": "1.2.2"
};
// BOTTOM OF METADATA
});
So this has nothing else for the whitelist plugin as well
Could there be something missing here?? Could this white-list plugin not be installed correctly?
I had a similar situation where my ajax calls worked fine in TEST, but when I moved to PROD, they would fail.
The answer was finally tracked down as a missing intermediary certificate on the server I was trying to access. TEST had the cert, PROD did not.
I hope this helps.

Can't get native messaging to work in Chrome Extension

Hope you can help me. I need to call an executable jar from an Chrome-Extension. By research I found https://developer.chrome.com/extensions/messaging#native-messaging is the way to go.
So I first edited the manifest of my extension and added:
"permissions": [
"nativeMessaging"
],
I can see in the Extensions overview, that the permission is granted.
As I am operating on Windows I added a Registry-Key:
HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\myextension
with:
C:\path\to\myextension.json
the "myextension.json" contains:
{
"name": "myextension",
"description": "my extension",
"path": "myextension.bat",
"type": "stdio",
"allowed_origins": [
"chrome-extension://[key]/"
]
}
the myextension.bat contains:
#echo off
cd %windir%\system32
start calc.exe
(for testing just wanted to start the calculator)
in the js of my extension I try to call it by this:
var port = null;
var hostName = "myextension";
[...]
$(this).children(".abc").click(function() {
//alert("test");
port = chrome.runtime.connectNative(hostName);
alert(port);
message = {"text": "nachricht"};
port.postMessage(message);
});
But nothing happens. The first alert "test" would be executed. But other than that nothing happens.
I really don't know how to debug it, because I don't get any feedback by executing it. Hope you can help me.
/edit
Just saw that I get:
"Uncaught TypeError: undefined is not a function (anonymous function)"
at:
port = chrome.extension.connectNative(hostName);
or
port = chrome.runtime.connectNative(hostName);
/edit 2
Ok, now I got it to work when I use a button in the browser with: chrome.browserAction.onClicked.addListener(function() {
chrome.extension.connectNative('fbehost');
});
But when I want to call it from a button in the website it doesn't work:
$(this).children(".abc").click(function() {
alert("Test");
port = chrome.extension.connectNative("fbehost");
});
The alert works, but nothing else happens.

Resources