List all web accessible resources in a Chrome Extension - javascript

I would like to list all the images I have in a specified folder inside of my chrome extension. However, I think I am fighting web technologies on this one. Is there any env in the chrome extension that executes javascript in a "server" context, as in, could read the files in it's neighboring folders?
Here's what my web accessible resources param looks like:
"web_accessible_resources": ["*.jpg","*.JPG", "*.png", "*.PNG"]
I have background script and content script both enabled.
I've tried running an ajax query against the dir to see if it will index but also no luck.

There seems to be no direct way.
As a workaround you can set up a native app. Get the resources and directories from the manifest file and if there are any wildcards, as in your example, search the directories for them using traditional system calls.
Here's a link to how you can set up the native app and communicate with it using your extension: https://developer.chrome.com/extensions/nativeMessaging

Related

Chrome manifest v3 - How can one safely load external JavaScript files from disk?

Manifest v3 hardened down on what is doable with code execution and remotely hosted code: https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration/#code-execution
Following scenario: I want to create an extension that allows the user to add additional functionality into the extension by explicitly specifying javascript files on disk and giving permission to those files (for example through HTML5 FileSystem API, file picker, file:// urls, or maybe just a config file). They are not distributed with the main extension.
These files may also contain some UI code written in a UI library like React or Vue, which should get rendered into the main application window somehow. The main window would also pass information about the extension context into those components.
I understand that there is the sandbox that can be used to execute code - https://developer.chrome.com/docs/extensions/mv3/manifest/sandbox/
I know how to do these things in normal applications but is what I want to do somehow feasible with v3 and the new restrictions on code execution and external code loading or am I hitting a brick wall here?

Can a Chrome Extension Dynamically Add JS Files to Local Extension Directory? User Upload or Saved From the Web?

I'm wondering if it's possible to for certain JS files to be added to the web extension directory later?
Like say I have an app where users can select certain settings from within the app and those files (js and html files, images or blobs) are somehow added into the extension from the web. Like some sort of ondemand updater without using any native apps but it seems that upgrades are done by the appstores automatically.
I'm reading the files using ajax and adding them to indexeddb but because it could be more than one file that's getting messy.
Say a user wants a certain feature on the extension and there's an html page, js files and images then this gets downloaded to a certain folder inside the installed extension.
function download() { //only saves to downloads directory
var imgurl = "https://www.google.com.hk/images/srpr/logo11w.png";
console.log('download');
browser.downloads.download({url:imgurl},function(downloadId){
console.log("download begin, the downId is:" + downloadId);
});
}
I also tried the chrome download function above but that only works for the downloads folder not the extension folder.
Is there any way to make a custom updater?! I know we can't save to disk but any leniency or workarounds for the extension folder?! Even something silly like making a shell call to some dos (and linux/mac) thing that saves the file to the extension folder. I can fetch the files, just not save them.
Ok so I'll put it as an answer. This is the solution I'm leaning on which works for my scenario and I've listed some alternatives below:
Having the other files as separate extensions and giving the user an install link instead where they can install that extension, then those child extensions talk to the mother extension and they know the address to the resources in their child extension folder, so the mother gets the just the file locations from the children to load those assets from that folder. The child extensions are like bundles of those html and js with a background script which sends the addresses of these items to the mother.
https://developer.chrome.com/extensions/messaging#external
The drawback is that I'll have to see how that affects the urls like if I inject the html page from the child extension folder into the main interface using ajax then I can't use relative url's to any images in that 'cos the urls are relative to the mother extension folder.. I'll have to rewrite the child extension urls with the absolute paths into the html page to load images and js from the child extension html code which has relative urls.
Pros:
Cleaner and more persistent than indexeddb.
Files can be loaded normally from disk.
Cons:
User has to install separate extensions.
URL structure might be a bit confusing, need to rewrite urls if loading html from child. However this is only for image src's and where the javascript is loaded from so it's not such a big deal.
Other Possible Solutions:
Indexeddb which I'm already doing seems to be the preferred way of doing this but I really do not want to store every html asset in indexeddb. The upside is that while extensions need to be installed, this method can be done silently fetching and adding files without user interaction and indexeddb seems to be somewhat persistent. Might still end up using this because it is silent but having to load each asset from a database sounds like a nightmare.
The File Handle Api might have worked if I was working on Firefox only https://wiki.mozilla.org/WebAPI/FileHandleAPI
I haven't tried the shell copy, maybe if I fetch with ajax and then save to disk using some dos function and then doing different save functions for different OS systems.
Filesystem Api only saves to downloads and doesn't work for extensions anyways, so that's useless.
UPDATE
In windows there isn't any sudo, but this worked without admin priveleges for a subfolder (not on the C:\ root though). It would work for a linux only app very nicely. If I just wanted to save a file to a windows machine this might work.
Shell copy method would be to grab the contents of file with ajax from the local or remote location, output to DOS as a stream to save to file on windows. And do this for every operating system with a shell exec command or detect the OS and do that command. This way I can even put the files in the exact folder location.
Like say I make this sort of command from the contents:
//To append you can use >> instead of >
//folder seems necessary, can't save to root without admin
echo the content I want to save > C:\folder\textfile.txt
I thought of calling it using shell exec that only works in nodejs, so digging through the other answers on
How to execute shell command in Javascript
//full code to save file using javascript on windows
var shell = WScript.CreateObject("WScript.Shell");
shell.Run("echo content to save > C:\folder\textfile.txt");
The shell command doesn't seem to work. i can't find what this is for. There doesn't seem to be a shell command in regular javascript for windows. It seems to require IE ActiveX. Doesn't work with Firefox or Chrome.
Extensions can't modify their sources because the browser verifies them and resets/disables the extension if they change. Also, in Firefox the extensions aren't even unpacked.
The solution is actually quite trivial: save the code in any storage (localStorage, chrome.storage.local, IndexedDB) as a string and then add it in your extension page as a standard DOM script element. You'll have to relax the standard CSP a bit for that.

Could a google chrome extension be dormant yet invokable?

I am planning to develop a google chrome extension which will help with a home brew functional testing framework. Here's the puzzle:
There is no predefined url pattern where test pages could reside.
I don't want the extension to get invoked by a match-all url pattern and then decide the page is of no interest.
What I want instead is for the extension to be completely dormant and to be able to invoke it from within the test pages.
Is this possible? If so,
What should I have in my manifest?
How do I implement the wake-up call in my test page javascript?
Could the call be made whilst I am developing the extension, before it gets an id?
Edit:
This answer shows how a page could call an extension, but it needs an extension ID. Is there a way to get a temporary extension ID before the extension is published?
This is the first option I was thinking of but you do have to specify a second-level domain in the URL pattern.
Add this to your manifest.json
"externally_connectable": {
"matches": ["://.example.com/*"]
}
As such: *://*.example.com/*
not *://*.com
More information about chrome extension message passing here:
https://developer.chrome.com/extensions/messaging#external-webpage
You will need to specify an id for the communication. You can get your extensions id by visiting chrome://extensions
Not knowing your stack or build process I would set up a separate dev and prod config file with my dev and prod id's in the respective files. This will help avoid pointing to your development extension when you release your app to production.
An alternate option would be to inject on each page and invoke your script depending on the pages content.

Get filenames for all files in a chrome extension directory?

I'm writing a chrome extension which will add custom images to a webpage. I want the users to put all their images in the "backgrounds" folder, and I want my extension to be able to retrieve the file names of every file in the "backgrounds" directory in the extensions folder. It seems like there is no way to do this in chrome extensions. When I try to use the chrome fileSystem API, I get this error:
There were warnings when trying to install this extension:
'fileSystem' is only allowed for packaged apps, but this is a extension.
How can I do this?
You can get read-only access to your extension's folder with chrome.runtime.getPackageDirectoryEntry, with which you can work using the HTML5 FileSystem API.
However, this will not allow you to do what you want to do.
While you're developing an extension, it will work fine, as Chrome does not mind changes to the extension's folder - they are expected.
However, when the extension is deployed to users, Chrome will maintain a cryptographic hash of the extension folder's contents. In case there are any external modification to the files, the extension is considered compromised and is forcibly disabled.
So you should consider other approaches instead, such as:
using the above HTML5 FileSystem API to have a virtual persistent filesystem to which you can let the user "upload" files through your UI;
storing data as blob:/data: URIs in chrome.storage or IndexedDB;
asking the user to put the files in a cloud drive your extension can access using its usual API.

Does google chrome app development allow you to add html and javascript to the locally stored files, depending on user

I want to create a web app platform that runs locally on the users computer.
I am considering using google chrome's app process to make this work.
I am having trouble understanding, wether google will let me do this. so the user would have to download the main chrome app , which contains the base html and javascript code, and within the app be able to download and store locally with in the app new html and js code.
So in other words I want to create an app that allows users to download and install apps from my own app store, and have them run within the chrome app.
Does google chrome app development allow this?
if not what are my alternatives for creating an app that needs to run on a browser storing all files locally?
You can download HTML and CSS as much as you want and then use JavaScript to modify the DOM accordingly. It's not set up as any kind of system that lets you substitute pages, and there's no navigation within the app (using A elements), but you are free to modify the DOM.
There's no way to add any JavaScript to what's initially in the app, as eval and the other code-executing functions are disabled. You can certainly add SCRIPT elements to the DOM, but the files they reference have to have been part of the app at the time it was installed.
Having said all that, you can implement the app as an interpreter for some language and then download programs written in that language. It's just that none of the code can be direct Chrome App code, nor can any code you download (regardless of language) make direct Chrome API calls.
Have you looked at the HTML5 Filesystem API? You can fetch a file and reference it later. You also need the add the "unlimitedStorage" permission to manifest.json.
http://www.html5rocks.com/en/tutorials/file/filesystem/

Categories