Offline HTML5 website with JavaScript search - javascript

I am building a simple website that needs to be able to run completely offline if needs be. With the intention of being a 50+ page searchable reference manual.
I need the whole site to be cached upon opening one page. I'm doing this with the appcache manifest and getting the site to cache and be viewed on an offline mobile seems to work ok.
The site has a basic JavaScript search facility (that was a freeware download) and while online this search works perfectly. As soon as the internet connection is stopped and the cached version is used the search no longer works, displaying one of two symptoms 1. Button is clicked and nothing happens or 2. A 'webpage cannot be found' kind of error is displayed.

Quote from https://developer.mozilla.org/en-US/docs/HTML/Using_the_application_cache#Gotchas
Never access cached files by using traditional GET parameters (like
other-cached-page.html?parameterName=value). This will make the
browser bypass the cache and attempt to get it from network. To link
to cached resources that have parameters parsed in JavaScript use
parameters in the hash part of the link, such as
other-cached-page.html#whatever?parameterName=value.
But that is exactly what your js-search does. It tries to load the subpages like this "http://www.filemanage.co.uk/offline/index.html?1350563635665" using XHR.
As a fix try this
// change in function sendRequest line 228 from
this.httpRequest.open("GET", uri+"?"+q, true);
// to
this.httpRequest.open("GET", uri, true);

Related

How to detect inline Firefox extension installation, and intercept it - Firefox extension development

I am building Firefox addon am trying to detect inline installation of the Firefox extensions. To be clear, installations on the places that are not on the Mozilla domain. So, when I am on some website, and when I trigger the extension installation (the .xpi file), I want to redirect the user to some website.
Before that dialog box appears, and if that is not possible, very soon after that, the one for 'installation confirmation', I want to redirect the user.
I am not very familiar with the download API, and I really don't know where to start. I have tried adding the listener for the downloads, but no result from it.
background.js (and included downloads in manifest.json)
function handleCreated(item) {
console.log(item);
}
browser.downloads.onCreated.addListener(handleCreated);
My expectations are to make my addon to recognize that the user is downloading a .xpi file, and perform redirection on some page when that happens.
Edit:
Of the redirection is not possible, then replacing websites .xpi with another one would do the job also.
Adding to the list of what I have tried.
I have tried to convert the page into the text format using .text() fro jQuery, and then search for the URL that has .xpi at the end. However, this did not work for some cases. Sometimes, some websites are pulling the .xpi from their own server, using their own API. So it is not a golden solution to my problem.

Force Cache Refresh for Web Resources

I have several web resources that are displayed on forms in Microsoft Dynamics. The web resources are html files that include JavaScript/CSS files. When I update the JavaScript files, I am seeing that the latest changes are not getting pulled to end user computers on their next use of the form. I believe this is because the previous version of the web resource has been cached on their machine.
According to this SO question, the solution would be to add a version to the script tag. However, according to the comments on the question, this solution does not work on Chrome and is considered a hack. I have also read here that Dynamics should automatically handle caching when web resources are updated, but does not do so reliably (which is my experience).
How can I force end user computers to get the latest version of my code on their next use of the form when I push out updates?
If you are only changing the files for development (ie. Once they are finished they won't change), then most browsers will allow you to disable the cache. In Chrome, this can be done as long as developer tools are open and you click the "disable cache" button in the network tab.
If they are going to change for the client with each request, then you can generate a random ID to be sent with the file (eg example.com/script.js?182hdh2). To allow this, just put some js in your html file (not in an external script) to import all the other files.

How to check the authenticity of a Chrome extension?

The Context:
You have a web server which has to provide an exclusive content only if your client has your specific Chrome extension installed.
You have two possibilities to provide the Chrome extension package:
From the Chrome Web Store
From your own server
The problem:
There is a plethora of solutions allowing to know that a Chrome extension is installed:
Inserting an element when a web page is loaded by using Content Scripts.
Sending specific headers to the server by using Web Requests.
Etc.
But there seems to be no solution to check if the Chrome extension which is interacting with your web page is genuine.
Indeed, as the source code of the Chrome extension can be viewed and copied by anyone who want to, there seems to be no way to know if the current Chrome extension interacting with your web page is the one you have published or a cloned version (and maybe somewhat altered) by another person.
It seems that you are only able to know that some Chrome extension is interacting with your web page in an "expected way" but you cannot verify its authenticity.
The solution?
One solution may consist in using information contained in the Chrome extension package and which cannot be altered or copied by anyone else:
Sending the Chrome extension's ID to the server? But how?
The ID has to be sent by you and your JavaScript code and there seems to be no way to do it with an "internal" Chrome function.
So if someone else just send the same ID to your server (some kind of Chrome extension's ID spoofing) then your server will consider his Chrome extension as a genuine one!
Using the private key which served when you packaged the application? But how?
There seems to be no way to access or use in any way this key programmatically!
One other solution my consist in using NPAPI Plugins and embed authentication methods like GPG, etc. But this solution is not desirable mostly because of the big "Warning" section of its API's doc.
Is there any other solution?
Notes
This question attempts to raise a real security problem in the Chrome extension's API: How to check the authenticity of your Chrome extension when it comes to interact with your services.
If there are any missing possibilities, or any misunderstandings please feel free to ask me in comments.
I'm sorry to say but this problem as posed by you is in essence unsolvable because of one simple problem: You can't trust the client. And since the client can see the code then you can't solve the problem.
Any information coming from the client side can be replicated by other means. It is essentially the same problem as trying to prove that when a user logs into their account it is actually the user not somebody else who found out or was given their username and password.
The internet security models are built around 2 parties trying to communicate without a third party being able to imitate one, modify or listen the conversation. Without hiding the source code of the extension the client becomes indistinguishable from the third party (A file among copies - no way to determine which is which).
If the source code is hidden it becomes a whole other story. Now the user or malicious party doesn't have access to the secrets the real client knows and all the regular security models apply. However it is doubtful that Chrome will allow hidden source code in extensions, because it would produce other security issues.
Some source code can be hidden using NPAPI Plugins as you stated, but it comes with a price as you already know.
Coming back to the current state of things:
Now it becomes a question of what is meant by interaction.
If interaction means that while the user is on the page you want to know if it is your extension or some other then the closest you can get is to list your page in the extensions manifest under app section as documented here
This will allow you to ask on the page if the app is installed by using
chrome.app.isInstalled
This will return boolean showing wether your app is installed or not. The command is documented here
However this does not really solve the problem, since the extension may be installed, but not enabled and there is another extension mocking the communication with your site.
Furthermore the validation is on the client side so any function that uses that validation can be overwritten to ignore the result of this variable.
If however the interaction means making XMLHttpRequests then you are out of luck. Can't be done using current methods because of the visibility of source code as discussed above.
However if it is limiting your sites usability to authorized entities I suggest using regular means of authentication: having the user log in will allow you to create a session. This session will be propagated to all requests made by the extension so you are down to regular client log in trust issues like account sharing etc. These can of course be managed by making the user log in say via their Google account, which most are reluctant to share and further mitigated by blocking accounts that seem to be misused.
I would suggest to do something similar to what Git utilises(have a look at http://git-scm.com/book/en/Git-Internals-Git-Objects to understand how git implements it), i.e.
Creating SHA1 values of the content of every file in your
chrome-extension and then re-create another SHA1 value of the
concatenated SHA1 values obtained earlier.
In this way, you can share the SHA1 value with your server and authenticate your extension, as the SHA1 value will change just in case any person, changes any of your file.
Explaining it in more detail with some pseudo code:
function get_authentication_key(){
var files = get_all_files_in_extension,
concatenated_sha_values = '',
authentication_key;
for(file in files){
concatenated_sha_values += Digest::SHA1.hexdigest(get_file_content(file));
}
$.ajax({
url: 'http://example.com/getauthkey',
type: 'post'
async: false,
success:function(data){
authentication_key = data;
}
})
//You may return either SHA value of concatenated values or return the concatenated SHA values
return authentication_key;
}
// Server side code
get('/getauthkey') do
// One can apply several type of encryption algos on the string passed, to make it unbreakable
authentication_key = Digest::<encryption>.hexdigest($_GET['string']);
return authentication_key;
end
This method allows you to check if any kind of file has been changed maybe an image file or a video file or any other file. Would be glad to know if this thing can be broken as well.

Open local html file in current window with Javascript Bookmarklet

I'm trying to build a sample bookmarklet to grab current webpage source code and pass it to a validator. Validator is not a an online website, but a folder with bunch of javascript and html files. I'm trying to open file:///C:/Users/Electrifyings/Desktop/Validator/Main.html file with the help of javascript bookmarklet code and put the source code in the textarea in the newly opened window, but it is not working for some reasons that I'm not aware of.
Here is the sample code with algorithm:
javascript:(function(){var t = document.body.innerHTML;window.open('file:///C:/Users/RandomHero/Desktop/test.html',_self);document.getElementById("validator_textarea")=t;})()
Here are the steps:
Grab current web page source code in a variable.
Open locally stored HTML web page in current or new window or new tab (either way is fine with me, but no luck)
Put the source code from the variable into the validator textarea of the newly opened HTML file.
I have tried above code with a lot of variations, but got stuck on the part where it opens the new window. Either it's not opening the new window at all or it is opening blank window without loading the file.
Would love to get some help with this issue, thanks a lot.
Oh and btw,
Windows 7 x64, Tried IE, Firefox and Chrome. All latest and stable builds. I guess it's not a browser side issues, but something related to javascript code not opening the URI with file:/// protocol. Let me know if any more details are needed. :)
You wouldn't want a webpage you visit to be able to open up file://c:/Program Files/Quicken/YourSensitiveTaxInfo right? Because then if you make a mistake and go to a "bad" website (either a sleazy one or a good one that's been compromised by hackers), evil people on the intarweb would suddenly have access to your private info. That would suck.
Browser makers know this, and for that reason they put VERY strict limits to prevent Javascript code from accessing files on a user's local computer. This is what is getting in the way of your plan.
Solutions?
build the whole validator in to the bookmarklet (not likely to work unless it's really small)
put your validator code up on the web somewhere
write a plug-in (because the user has to choose to install a plug-in, they get much more freedom than webpages ... even though for Firefox, Chrome, etc. plug-ins are basically just Javascript)
* * Edit * *
Extra bonus solution, if you don't limit yourself to a purely-client-side implementation:
Have your bookmarklet add a normal (HTML) form to the page.
Also add an iframe to the page (it's ok if you hide it with CSS styling)
Set the form's target attribute to point to the iframe. This will make it so that, when the user submits the form and the server replies back to that submission, the server's reply will go to the (hidden) iframe, instead of replacing the page as it normally would.
Add a file input to your form - you won't be able to access the file within that input using Javascript, but that's ok because your server will be doing the accessing, not your bookmarklet.
Write a server-side script which takes the form submissions, reads the file that came with it, and then parrots that file back as the response. In other words, you'll have a URL that you can POST to, and when it sees a file in the POST's contents, it will respond back with the contents of that file.
Now that you've got all that the user can pick their validator file using the file input, upload it to your server, your server will respond back with the file it just got, and that file will appear as the contents of the iframe.
And now that you finally have the file that you worked so hard to get (inside your iframe) you can do $('#thatIframe').html() and viola, you have access to your file. You can save the current page's source and then replace the whole page with that uploaded file (and then pass the saved page source back to the new validator page), or you can do whatever else you want with the contents of the uploaded validator file.
Of course, if the file doesn't vary from computer to computer, you can make all of that much simpler by just having a server that sends the validator file back; this could be a pure Apache server with no logic whatsoever, as all it would have to do is serve a static file.
Either way though, if you go with this approach and your new file upload script is not on the same server as your starting webpage, you will have a new security problem: cross-domain script limitations. However, these limitations are much less strict than local file access ones, so there are ways to work around them (JSONP, cross-site policy files, etc.). There are already tons of great Stack Overflow posts explaining these techniques, so I won't bother repeating them here.
Hope that helps.

Client side scripting to make changes in a file

Is there any client-side script that would be able to make changes to a file on the hosts computer? (Intention stated below)
I am creating a packaged app for chrome which can show some online data, and make it available even when offline.
There is a certain thing, for e.g. 'a webpage' i want to show/store (but i cannot get/read its contents due to it being on different origin). To show when online, i can use iframe, but am unable to preserve it for offline.
So i thought i could make an appcache (manifest within the application package) which will cache the file, and on press of an update button a script would run which would make some change to the manifest which would force the cached resource to be reloaded.
I searched a lot, but no results.
Any suggestions as to how it can be done. Or any other way to get it to work?
I don't think so. This could be a huge security problem if it existed.
If you had to, you could send an ajax request to the server to create a file it creates with the current prices, and add it to the appcache file.
Here is a link to another SO quesitob that has a list of APIs you could use to get your stock price.
Webservice to get stock quotes?

Categories

Resources