I have created an online multiplayer card game using Adobe flash Professional. In this game multiple clients/account is not allowed, hence I need to detect whether the users are joining game from different devices or not. I can't simply do a server sided check for the IP-address because I still want e.g. people in the same office to be able to play together.
I have found some solution like reading the MAC address (Here) but the problem is that NetworkInfo.networkInfo.findInterfaces() works only on Adobe air, which is not my case.
Another solution could be using browser cookies, but the problem of this solution is that, the users can use e.g. Chrome and Firefox on the same computer.
As this a web game, using js could be also a solution, so I tag this question as js as well.
UPDATE
Using SharedObject does not work in this case, since google chrome uses its own storage.
Any suggestion will be appreciated.
Instead browser cookies you can use "flash cookies" - SharedObject. It is really simple and have mechanic similar to browser cookies, but stored in flash local storage.
UPDATE
Example:
var mySo:SharedObject = SharedObject.getLocal("host"); // get saved SO with name "host" if exists or create new if doesn't exist
mySo.data = {someProperty: "someData"}; // writing some data
var flushResult:Object = mySo.flush(); // saving data in local storage
...
var savedSO:SharedObject = SharedObject.getLocal("host");
trace(savedSO.data.someProperty); // output: someData
Related
So I'm working on a Chrome extension for someone else. I don't want to give away specific details about the project, so for I'll use an equivalent example: let's assume it's an extension to run on an image/forum board. Imagine I have variables such as userPoints, isBanned etc. The later being fairly self-explanatory, while the former corresponding to points the user acquires as they perform certain actions, hence unlocking additional features etc
Let's imagine I have code like:
if(accountType !== "banned"){
if(userPoints > 10000) accountType = "gold";
else if(userPoints > 5000) accountType = "silver";
else if(userPoints > 2500) accountType = "bronze";
else if(userPoints <= 0) accountType = "banned";
else accountType = "standard";
}else{
alert("Sorry, you're banned");
stopExtension();
}
Obviously though, it becomes trivial for someone with the knowledge to just browse to the extensions background page and paste chrome.storage.local.set({'userPoints': 99999999}) in the console, hence giving them full access to all the site. And, with the Internet, someone can of course share this 'hack' on Twitter/YouTube/forums or whatever, then suddenly, since all they'd need to do is copy and paste a simple one-liner, you can have 1000s of people, even with no programming experience, all using a compromised version of your extension.
And I realise I could use a database on an external site, but realistically, it would be possible that I would be wanting to get/update these variables such as userPoints 200+ times per hour, if the user was browsing the extentions target site the entire time. So the main issues I have with using an external db are:
efficiency: realistically, I don't want every user to be querying the
db 200+ times per hour
ease-of-getting-started: I want the user to just download the
extension and go. I certainly don't want them to have to sign up. I
realise I could create a non-expiring cookie with for the user's ID
which would be used to access their data in the db, but I don't want
to do that, since users can e.g. clear all cookies etc
by default, I want all features to be disabled (i.e. effectively
being considered like a 'banned' user) - if, for some reason, the
connection with the db on my site fails, then the user wouldn't be
able to use the extension, which I wouldn't want (and just speaking
from experience of my parents being with Internet providers whose
connection could drop 10 times per hour, for some people, failed
connections could be a real issue) - in contrast, accessing data from
the local storage will have like a 99.999% success rate I'd assume,
so, for non-critical extensions like what I'm creating, that's more
than good enough
Still, at least from what I've found searching, I've not found any Chrome storage method that doesn't also allow the user to edit the values too. I would have thought there would be a storage method (or at least option with chrome.storage.local.set(...) to specify that the value could only be accessed from within the extension's context pages, but I've not found that option, at least.
Currently I'm thinking of encrypting the value to increment by, then obfuscating the code using a tool like obfuscator.io. With that, I can make a simple, like 30 character js file such as this
userPoints = userPoints + 1000;
become about 80,000...still, among all the junk, if you have the patience to scroll through the nonsense, it's still possible to find what you're looking for:
...[loads of code](_0x241f5c);}}}});_0x5eacdc(),***u=u+parseInt(decrypt('\u2300\u6340'))***;function _0x34ff36(_0x17398d)[loads more code]...
[note that, since it's an extension and the js files will be stored on the user's pc, things like file size/loading times of getting the js files from a server are irrelevant]
Hence meaning a user wouldn't be able to do something like chrome.storage.local.set({'userPoints': 99999999}), they'd instead have to set it to the encrypted version of a number - say, something like chrome.storage.local.set({'userPoints': "✀ເ찀삌ሀ"}) - this is better, but obviously, by no means secure.
So anyway, back to the original question: is there a way to store persistent values for a Chrome extension without the user being able to edit them?
Thanks
am developing an offline application using html 5 and java script libraries.
my system is for offline data collection. data is stored in the local machine in text format before being synced to the server later on.
before i had developed the same application but using silver light which was easy to back up data for security reasons using
any idea on how i can backup the text files and zip them to my hard disk will be highly appreciated.
i have not found a solid answer through my research so far
thanks in advance.
One "solution" I can think of is, before the user closes the app using the close button, you could detect the window.onbeforeunload event and send the data to your server to save. But this is not reliable because there might be cases when the browser may crash or the user might forcefully close the browser application. Or worst of all if you are constantly using localStorage and by chance the user clears the browsing data (which includes localStorage) it will be gone.
But assuming you have the data at hand, you can send it to the server using POST and make a script to save it in the disk. Obviously, you might want to impose limitation on file size and enforce other security restrictions.
WARNING: PHP
Lets say you have a folder created for each unique user and all files in each user's folder are guaranteed to be named uniquely. In PHP you can use functions like file_put_contents() to save a text file, you can also easily ZIP it using the ZipArchive class.
It's not recommended to store this kind of data directly to the drive. I would highly recommend you to put the localStorage data in some kind of database and do a database backup instead of backing up individual user's data.
As other users have pointed it out you could also look at the HTML5 File API. Examples here.
I found a solution on how to backup local storage files and zip them to my local drive without any server code. Below is a code snippet that works fine for me at least for now. Any modifications and enhancements will be highly appreciated.
if (localStorageKeys.length > 0) {
for (var i = 0; i < localStorageKeys.length; i++) {
var key = localStorageKeys[i];
if (key.search(_instrumentId) != -1) {
keysToBackup.push(key);
var data = localStorage.getItem(localStorageKeys[i]);
zip.file(localStorageKeys[i].slice(0, -19) + ".txt", data);
}
else {
keysNotToBackup.push(key);
}
var datafile = document.getElementById('backupData');
datafile.download = formName + "_Data.zip";
datafile.href = window.URL.createObjectURL(zip.generate({ type: "blob" }));
}
}
I found a solution for backup and restoring the local storage of websites.
You can use this repository:
https://github.com/todvora/localstorage-backup
This is the live app:
https://www.tomas-dvorak.cz/localstorage-backup/
Usage:
In the live app, Drag the buttons and drop them into your bookmarks. They are so-called bookmarklets.
Open the site you want to backup/restore and click on this bookmarked button.
I need users to be able to post data from a single page browser application (SPA) to me, but I can't put server-side code on the host.
Is there a web service that I can use for this? I looked at Amazon SQS (simple queue service) but I can't call their REST APIs from within the browser due to cross origin policy.
I favour ease of development over robustness right now, so even just receiving an email would be fine. I'm not sure that the site is even going to catch on. If it does, then I'll develop a server-side component and move hosts.
Not only there are Web Services, but nowadays there are robust systems that provide a way to server-side some logic on your applications. They are called BaaS or Backend as a Service providers, usually to provide some backbone to your front end applications.
Although they have multiple uses, I'm going to list the most common in my opinion:
For mobile applications - Instead of having to learn an API for each device you code to, you can use an standard platform to store logic and data for your application.
For prototyping - If you want to create a slick application, but you don't want to code all the backend logic for the data -less dealing with all the operations and system administration that represents-, through a BaaS provider you only need good Front End skills to code the simplest CRUD applications you can imagine. Some BaaS even allow you to bind some Reduce algorithms to calls your perform to their API.
For web applications - When PaaS (Platform as a Service) came to town to ease the job for Backend End developers in order to avoid the hassle of System Administration and Operations, it was just logic that the same was going to happen to the Backend. There are many clones that showcase the real power of this strategy.
All of this is amazing, but I have yet to mention any of them. I'm going to list the ones that I know the most and have actually used in projects. There are probably many, but as far as I know, this one have satisfied most of my news, whether it's any of the previously ones mentioned.
Parse.com
Parse's most outstanding features target mobile devices; however, nowadays Parse contains an incredible amount of API's that allows you to use it as full feature backend service for Javascript, Android and even Windows 8 applications (Windows 8 SDK was introduced a few months ago this year).
How does a Parse code looks in Javascript?
Parse works through classes and objects (ain't that beautiful?), so you first create a specific class (can be done through Javascript, REST or even the Data Browser manager) and then you add objects to specific classes.
First, add up Parse as a script tag in javascript:
<script type="text/javascript" src="http://www.parsecdn.com/js/parse-1.1.15.min.js"></script>
Then, through a given Application ID and a Javascript Key, initialize Parse.
Parse.initialize("APPLICATION_ID", "JAVASCRIPT_KEY");
From there, it's all object manipulation
var Person = Parse.Object.extend("Person"); //Person is a class *cof* uppercase *cof*
var personObject = new Person();
personObject.save({name: "John"}, {
success: function(object) {
console.log("The object with the data "+ JSON.stringify(object) + " was saved successfully.");
},
error: function(model, error) {
console.log("There was an error! The following model and error object were provided by the Server");
console.log(model);
console.log(error);
}
});
What about authentication and security?
Parse has a User based authentication system, which pretty much allows you to store a base of users that can manipulate the data. If map the data with User information, you can ensure that only a given user can manipulate specific data. Plus, in the settings of your Parse application, you can specify that no clients are allowed to create classes, to ensure innecesary calls are performed.
Did you REALLY used in a web application?
Yes, it was my tool of choice for a medium fidelity prototype.
Firebase.com
Firebase's main feature is the ability to provide Real Time to your application without all the hassle. You don't need a MeteorJS server in order to bring Push Notifications to your software. If you know Javascript, you are half way through to bring Real Time magic to your users.
How does a Firebase looks in Javascript?
Firebase works in a REST fashion, and I think they do an amazing job structuring the Glory of REST. As a good example, look at the following Resource structure in Firebase:
https://SampleChat.firebaseIO-demo.com/users/fred/name/first
You don't need to be a rocket scientist to know that you are retrieve the first name of the user "Fred", giving there's at least one -usually there should be a UUID instead of a name, but hey, it's an example, give me a break-.
In order to start using Firebase, as with Parse, add up their CDN Javascript
<script type='text/javascript' src='https://cdn.firebase.com/v0/firebase.js'></script>
Now, create a reference object that will allow you to consume the Firebase API
var myRootRef = new Firebase('https://myprojectname.firebaseIO-demo.com/');
From there, you can create a bunch of neat applications.
var USERS_LOCATION = 'https://SampleChat.firebaseIO-demo.com/users';
var userId = "Fred"; // Username
var usersRef = new Firebase(USERS_LOCATION);
usersRef.child(userId).once('value', function(snapshot) {
var exists = (snapshot.val() !== null);
if (exists) {
console.log("Username "+userId+" is part of our database");
} else {
console.log("We have no register of the username "+userId);
}
});
What about authentication and security?
You are in luck! Firebase released their Security API about two weeks ago! I have yet to explore it, but I'm sure it fills most of the gaps that allowed random people to use your reference to their own purpose.
Did you REALLY used in a web application?
Eeehm... ok, no. I used it in a Chrome Extension! It's still in process but it's going to be a Real Time chat inside a Chrome Extension. Ain't that cool? Fine. I find it cool. Anyway, you can browse more awesome examples for Firebase in their examples page.
What's the magic of these services? If you read your Dependency Injection and Mock Object Testing, at some point you can completely replace all of those services for your own through a REST Web Service provider.
Since these services were created to be used inside any application, they are CORS ready. As stated before, I have successfully used both of them from multiple domains without any issue (I'm even trying to use Firebase in a Chrome Extension, and I'm sure I will succeed soon).
Both Parse and Firebase have Data Browser managers, which means that you can see the data you are manipulating through a simple web browser. As a final disclaimer, I have no relationship with any of those services other than the face that James Taplin (Firebase Co-founder) was amazing enough to lend me some Beta access to Firebase.
You actually CAN use SQS from the browser, even without CORS, as long as you only need the browser to send messages, not receive them. Warning: this is a kludge that would make my CS professors cry.
When you perform a GET request via javascript, the browser will always perform the request, however, you'll only get access to the response if it was from the same origin (protocol, host, port). This is your ticket to ride, since messages can be posted to an SQS queue with just a GET, and who really cares about the response anyways?
Assuming you're using jquery, your queue is https://sqs.us-east-1.amazonaws.com/71717171/myqueue, and allows anyone to post a message, the following will post a message with the body "HITHERE" to the queue:
$.ajax({
url: 'https://sqs.us-east-1.amazonaws.com/71717171/myqueue' +
'?Action=SendMessage' +
'&Version=2012-11-05' +
'&MessageBody=HITHERE'
})
The'll be an error in the console saying that the request failed, but the message will show up in the queue anyways.
Have you considered JSONP? That is one way of calling cross-domain scripts from javascript without running into the same origin policy. You're going to have to set up some script somewhere to send you the data, though. Javascript just isn't up to the task.
Depending in what kind of data you want to send, and what you're going to do with it, one way of solving it would be to post the data to a Google Spreadsheet using Ajax. It's a bit tricky to accomplish though.Here is another stackoverflow question about it.
If presentation isn't that important you can just have an embedded Google Spreadsheet Form.
What about mailto:youremail#goeshere.com ? ihihi
Meantime, you can turn on some free hostings like Altervista or Heroku or somenthing else like them .. so you can connect to their server , if i remember these free services allows servers p2p, so you can create a sort of personal web services and push ajax requests as well, obviously their servers are slow for free accounts, but i think it's enought if you do not have so much users traffic, else you should turn on some better VPS or Hosting or Cloud solution.
Maybe CouchDB can provide what you're after. IrisCouch provides free CouchDB instances. Lock it down so that users can't view documents and have a sensible validation function and you've got yourself an easy RESTful place to stick your data in.
I'm wondering if I can count the times user loads pages on my site, with JavaScript. Probably like this?
var pageloads = 1;
$(document).ready(function(){
var pageloads =++
});
But where would I store it? In a cookie?
If older browsers like IE7 and below are'nt an issue, you can use local storage:
$(function(){
var loaded = parseInt(localStorage.getItem('loaded'), 10),
loaded_numb = loaded?loaded+1:1;
localStorage.setItem('loaded', loaded_numb);
$('body').append('<p>This page was loaded by you '+loaded_numb+' times !');
});
FIDDLE
Easier to just do it with cookies (especially since there's no reason to totally block out IE7 and lower)
var numLoads = parseInt(getCookie('pageLoads'), 10);
if (isNaN(numLoads) || numLoads <= 0) { setCookie('pageLoads', 1); }
else { setCookie('pageLoads', numLoads + 1); }
console.log(getCookie('pageLoads'));
getCookie/setCookie simple get/set functions (can be found in the jsFiddle)
jsFiddle Demo
You could store it in a database. If you are looking for monitoring the traffic on your web page you should look at Google Analytics http://www.google.com/analytics/.
They show you how many people visited your site, whether they are new or returning, the path they took through your site, bounce rate etc. Best part is it's free.
Why would you want to do this with Javascript? Whatever server you're using should have access logs that store all requests, IPs that make the requests, and a lot more. There are even free log file analyzers like awstats and Google Analytics. You should do this on the server side, not the client side.
If you really want to store it with JavaScript, then your only options are a cookie and LocalStorage -- both of those are quite transient.
It's not possible - edit: to track an actual user.
You can only ever track a particular instance of a browser using cookies.
There is no such thing as tracking a "user" using javascript alone. You can reliably count things like user logins though.
I'm working with an old intranet site written in classic ASP. I'm trying to retrieve their username they logged into their machine with. Each user is logged into AD, but I can't retrieve it from the server since the intranet site does not use AD.
I was told I could use ActiveX in order to retrieve it. I did some research and I found the following code (javascript):
var wshshell = new ActiveXObject("WScript.shell");
var username = wshshell.ExpandEnvironmentalStrings("%username%");
Currently I'm using IE8 and I get an "Automation server can't create object" error on that first line.
1) Any ideas why I'm getting the error?
2) Is there a better way to be doing this given my limitations?
If this is done client-side, then you must have the user add the site to the Trusted Sites zone and set the security level to the lowest. Line 1 should work server-side, but I don't think line 2 is right.
Try this
var net = new ActiveXObject ( "WScript.NetWork" );
var username = net.UserName;
Basically, its impossible to retrieve client's Windows machine information using Javascript.
Because its scope is upto browser only.
For doing so you need to create COM object or say an Activex object, and using ASPX page you need to deploy it on Client's system at the very first time your page is accessed from a browser.
Now, ActiveX object has a featured to interact using javascript. You have to access the COM object or the class and function of the COM, which further interact with the system classes to get the system Information. i.e logged in client's windows user information.
var net = new ActiveXObject ( "WScript.NetWork" );
var username = net.UserName;
Above code is also initializing a COM object, if it is not deployed to your client system this script won't work.