Calling Firefox XPCOM from external app? - firefox

Context: we need to read Firefox cookies in our app; until Firefox 3.5, this was possible by reading cookies.txt / cookies.sqlite. In Firefox 3.5, it exclusively locks the cookie file so outside apps can't read it (see https://bugzilla.mozilla.org/show_bug.cgi?id=476167), and even if we make a local copy, FF doesn't always flush the cookies to disk until exit so they may not be there.
The suggested solution is to use nsICookieManager, which looks like what we need -- but how can I get at one of those from a process that isn't Firefox?
Everything I see about XPCOM suggests I can only use it from firefox extensions -- do we have to write an extension, and then somehow invoke Firefox to install our extension and then somehow invoke the extension itself to pass cookies back out?

Yes - you'll have to build an extension which communicates from your application to Firefox. You can install the add-on with the windows registry (assuming you are on windows).

Related

How to read profile preferences from Firefox add-on?

I'm doing this (Firefox 66.0.5, MacOS):
var prefs = Components.classes['#mozilla.org/preferences-service;1']
.getService(Components.interfaces.nsIPrefBranch);
var x = pref.getCharPref('extensions.foo.x');
I'm getting this:
JavaScript error: moz-extension://9390a488-d749-d140-91b6-fb1b2a86053f/foo.js,
line 1: TypeError: Components.classes is undefined
What is the right way to read the preferences of the profile?
I tried this:
var prefs = Components.classesByID['#mozilla.org/preferences-service;1']
.getService(Components.interfaces.nsIPrefBranch);
And got this:
JavaScript error: moz-extension://ebac8f96-717d-0c4b-b2d3-a7d6f3515843/auth.js,
line 1: TypeError: Components.classesByID is undefined
WebExtensions are very limited in their ability to make changes to user preferences. There are a few, currently 14, that you can affect through the browserSettings API. There are others which are effectively changed through other WebExtension APIs (e.g. proxy), but nothing directly. Unfortunately, there's no direct way to read or set user preferences from a WebExtension. The capability to adjust user preferences directly was only available to the older styles of add-ons (all removed as of Firefox 57).
As to your use of Components and the specific errors which you are getting, please see my answer to Unable to use Components in WebExtensions: get “ReferenceError: Cu is not defined” for more detail. The use of Components is just not possible in a WebExtension.
The only way that I can think of that it might be possible to adjust preferences in a release version of Firefox is to use Native messaging to communicate to a native application which you also install. After Firefox exits/stops/is shutdown, the native application could read and change the configuration files in the profile directory for the Firefox profile being run. It could then restart Firefox.
In the Nightly and Developer Edition versions of Firefox, it should still be possible to use a WebExtensions Experiment, which would permit you to make the preference changes you desire using the Components interface. However, that's not a viable solution if this is an extension you want to distribute publicly.

Install a personal firefox web extension permanently

Previously, I could write an addon for personal usage packed as something.xpi and I clicked on it to install it.
After a while, mozilla introduced xpinstall.signatures.required which you could still get around it.
However, it did not stop stabbing developers who are interested to have a personal addon isolated from the world. Today, only web extensions are working and my XUL based addon is thrown away. The tutorials only talk about temporary installation of a web extension while I want my one runs on firefox forever.
Beside whether I can use web extension to write into files or create a GUI in an independent page, I have a bigger challenge:
How can I install a local web extension permanently without creating a Mozilla account for personal usage?
Navigate to the folder where your extension is located. You can build it in the usual way using web-ext:
web-ext build
You can install this ZIP file permanently in Firefox by going to about:addons and dragging this file into the tab.
In order for this to work, you need to set xpinstall.signatures.required to false in about:config (works only for Nightly and maybe Developer Edition).
Apart from setting xpinstall.signatures.required to false, you need to add this to your manifest.json:
"browser_specific_settings": {
"gecko": {
"id": "some-name#example.org"
}
}
Found on https://www.reddit.com/r/firefox/comments/blqffs/how_to_permanently_add_temporary_addon/exh2u3o/, thanks to "alexherbo2".
You need a "blueish" Firefox -- Developer Edition (effectively beta) or Nightly (unstable, updated every night).
You can get them from https://mozilla.org/firefox/channel/desktop/.
Then xpinstall.signatures.required will work again.
(As for permissions--you can create a GUI in a tab or a popup, but I don't think you can do it in a separate window (unless you do a webpage-style popup window). You won't be able to write to arbitrary files anywhere on the system--which is a good thing! You can write to the Downloads folder, and read/write some sort of internal storage, but that may not expose the actual files involved. For more information see https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Working_with_files.)
What you should be looking for is having your extension signed by Mozilla as Unlisted.
See Mixing Listed and Unlisted Add-ons on addons.mozilla.org blog post for an overview.
That way, AMO does not host nor (normally) review your extension; it simply runs some basic automated checks and immediately signs your extension so that it can be privately distributed as an XPI.
For those interested in developing/running an extension from a local directory without having to package or load it manually via "Load Temporary Addon..." from about:debuggin#/runtime/this-firefox please go to this github repository.
From the README.md:
The procedure involves a few steps, but it needs to be done only once.
First you need to enable AutoConfig aka userchrome.js by copying the file config-prefs.js to [Your Firefox install directory]/defaults/pref
Note: For best security, on Windows it is best to leave your Firefox install in "c:\Program Files" so that your config-prefs.js and userChrome.js can only be modified when you are in root/admin mode.
Then you need to edit the file userChrome.js and modify the function installUnpackedExtensions() to reflect the locations of your own addons.
The modified userChrome.js then must be copied to your Firefox installation directory. For example on Windows this is usually "c:\Program Files (x86)\Mozilla Firefox" for the 32-bit version of Firefox. You can rename the file, but remember to modify the corresponding line pref("general.config.filename", "userChrome.js") in defaults/pref/config-prefs.js
Now your addons from your local directories will be loaded automaticaly whenever Firefox starts. After editing your code remember to reload it from about:debuggin. You can also get there via the menu by selecting "More Tools", then "Remote Debugging", and click on "This Firefox" on the left side (but the quickiest way is to bookmark it and then add a bookmark keyword such as "dbg" for quick access.)
Please note that this is an automated install of the extension every time Firefox starts, so it is not quite the same as a "permenent install". That is, this procedure has exactly the same effect as clicking on "Load Temporary Addon..." from the about:debuggin page, just that the process is now automated via userChrome.js. This means that if you have code that does something after the installation of the extension such as browser.runtime.onInstalled.addListener(details => { if (details.reason == "install") { ...do something after install... }); then this code will be called every time Firefox is launched.
You can try setting the preference extensions.legacy.enabled (this will only work in Nightly or Dev Edition).

Better way to prevent Firefox add-on variables values to wipe out on browser close? Getting error to use "io/text-streams" module

I want to save user settings for my firefox add-on in a variable which can be accessible any time I want. It should not get vanished on browser clos. Now how can I do it?
I have tried "simple-storage" module of firefox, it works fine until I quit my browser. When I quit my browser, "simple-storage"s wipes out. So I can't use it.
I have also tried "io/text-streams" module but when I try to use this module in "firefox add-on builder"
var io = require("io/text-streams");
io.write("write it");
I am getting this error:
XPI not built
ModuleNotFoundError: unable to satisfy: require(io/text-streams) from /tmp/tmpePRdMr/addon-sdk-1.12/packages/sadaf2605-4/lib/main.js:2: Looked for it in: /tmp/tmpePRdMr/addon-sdk-1.12/packages/sadaf2605-4/lib/io/text-streams.js /tmp/tmpePRdMr/addon-sdk-1.12/lib/io/text-streams.js
Most probably, I would need to install some packages, do the user who will be using my add-on, do they also need to install those packages on their browser?
Apparently you are testing your add-on with cfx run. The documentation explains why simple-storage appears broken and how to solve it.
Try saving your settings in localStorage object (HTML5) .Your values wont vanish after the session is closed ......

Can an standalone / external C++ executable or JavaScript create cookies for Firefox?

I need to create/update/remove cookie for FireFox browser. This cookie is a client cookie, as in it has to be created by C++ executable and it will be present on the end user machine.
How can I achieve this?
Thank you
You basically have two options:
You attempt to manipulate Firefox data (file cookies.sqlite) directly. It's a fairly simple SQLite database so there is nothing complicated about that. However, catch 1: this cannot be done while Firefox is running. Also, catch 2: the format might change in future (as happened before) and your application will stop working or, worse, break the file.
You do it from inside Firefox. For example, you would write a bootstrapped extension that would use nsICookieManager2 interface to add the cookie and then Add-on Manager API to uninstall itself immediately after that. Then your application would only have to run Firefox with the command line firefox -url file:///path/to/extension.xpi (works even if Firefox is already running). The catch here: the user would need to confirm extension installation. So you cannot do it behind his back, you need to explain what is happening and why.

Google Chrome --allow-file-access-from-files disabled for Chrome Beta 8

I have been developing an AJAX application using jQuery and Microsoft Seadragon technology.
I need to have access to the html5 canvas function toDataURL.
With Google Chrome, the same origin rule applies to this function which means that a page run locally (with the file:/// in the URL) failed to satisfy the same origin rule and an exception is thrown.
With Chrome 7, starting the application with --allow-file-access-from-files option, allows to call canvas.toDataURL() from local files.
However, it seems that starting the Chrome Beta 8 with the same option (--allow-file-access-from-files) does not allow the call canvas.toDataURL() on the local file.
Does Chrome gave up on the --allow-file-access-from-files option or it has just been disabled since it is a Beta release and not a full release?
Thanks!
Looking at the issues for this shows that the whole --allow-file-access-from-files thing was rushed.
"Firefox does it.."
"How can we do it?"
some time passes
"Here are the patches"
"Passes! On trunk wonder what happens in the next dev release"
"Ahhh it's broken" "Use the command line option" "ok"
"We shipped!"
"WTF guys? You broke all my stuff! Why didn't you tell us earlier?"
silence
On to your Problem
Indeed it seems that this is something special to the beta, I'm using Chrome 8.0.552.5 dev here and --allow-file-access-from-files works like expected, I've also tested this with Chromium 9.0.592.0 (66889) were it also works as expected.
I suspect there have been some changes on the dev branch. Unfortunately, finding something on chromium's issue tracker is nearly impossible.
Did you close all chrome instances before opening with the command line argument? You have to do that to make that parameter work.
To summarize all answers so far.
Before running chrome, make sure there are no chrome processes running.
Windows
-allow-file-access-from-files
(with one dash)
Linux
--allow-file-access-from-files
(with two dashes)
I've found a way around the issue using a JavaScript/Flash approach. If flash is compiled in the Local Only security sandbox, it has full access to local files. Using ExternalInterface, JavaScript can request a Flash Application to load a file, and Flash can pass the result back to JavaScript.
You can find my implementation here: https://code.google.com/p/flash-loader/
The trick that woked for me is that you have to give the absolute path of the file and not just file name in your HTML code. e.g file://... instead of direct name even though you are accessing the file in the same directory. It will work!

Resources