is there any possibility to access and retrieve data from MongoDB directly over JavaScript form browser without backend processing?
MongoDB natively does not have a fully usable REST interface. You will need either Python based Sleepy Mongoose or Node.js based MongoDB Rest
Please see http://www.mongodb.org/display/DOCS/Http+Interface for more information.
Mongo's inbuilt REST interface is very basic & read only.
If you happen to host your database on MongoLabs, they also expose a REST API. Watch out, it's not secure, as an API key is passed with each request, but your could use it to retrieve public data through Javascript:
https://support.mongolab.com/entries/20433053-Is-there-a-REST-API-for-MongoDB-
Once you have your mongolab db setup, you can access it thru REST request such as
$.getJSON("https://api.mongolab.com/api/1/databases/your-db/collections/your-collection/?apiKey=your-key", function(json) {
//console.log( "JSON Data: " + json );
});
Not in the standard security context.
If you have a situation where you have elevated security rights (such as inside a custom browser extension) then it may become possible.
Related
I am triying to use SQLQueries using Service Layer JavaScript Extension to get some info from table OCRD (field DocEntry) beacuse is not expossed in stanard CRUD entities (BusinessPartners). Is there a way to do it? I can retrieve the information by Postman, but I am unable to do it using JavaScript.
Thank you
Unique key for Business Partners is CardCode, and this one is exposed with the BP object, of course.
DocEntry, which can be queried from OCRD using SQL, is not exposed within SL's BusinessPartner object.
In Working with SAP Business One Service Layer user manual - has this in it:
To run the query, there are two ways in the Service Layer: one is to set a payload using POST and the other is to
specify a query parameter using GET.
By POST
POST https://server:50000/b1s/v1/SQLQueries('sql01')/List HTTP/1.1
{
"ParamList": "docTotal=10.1"
}
By GET
GET https://server:50000/b1s/v1/SQLQueries('sql07')/List?docTotal=10.1 HTTP/1.1
I'm building an app and would like some feedback on my approach to building the data sync process and API that supports it. For context, these are the guiding principles for my app/API:
Free: I do not want to charge people at all to use the app/API.
Open source: the source code for both the app and API are available to the public to use as they wish.
Decentralised: the API service that supports the app can be run by anyone on any server, and made available for use to users of the app.
Anonymous: the user should not have to sign up for the service, or submit any personal identifying information that will be stored alongside their data.
Secure: the user's data should be encrypted before being sent to the server, anyone with access to the server should have no ability to read the user's data.
I will implement an instance of the API on a public server which will be selected in the app by default. That way initial users of the app can sync their data straight away without needing to find or set up an instance of the API service. Over time, if the app is popular then users will hopefully set up other instances of the API service either for themselves or to make available to other users of the app should they wish to use a different instance (or if the primary instance runs out of space, goes down, etc). They may even access the API in their own apps. Essentially, I want them to be able to have the choice to be self sufficient and not have to necessarily rely on other's providing an instance on the service for them, for reasons of privacy, resilience, cost-saving, etc. Note: the data in question is not sensitive (i.e. financial, etc), but it is personal.
The user's sync journey works like this:
User downloads the app, and creates their data in the process of using the app.
When the user is ready to initially sync, they enter a "password" in the password field, which is used to create a complex key with which to encrypt their data. Their password is stored locally in plain text but is never sent to the server.
User clicks the "Sync" button, their data is encrypted (using their password) and sent to the specified (or default) API instance and responds by giving them a unique ID which is saved by the app.
For future syncs, their data is encrypted locally using their saved password before being sent to the API along with their unique ID which updates their synced data on the server.
When retrieving synced data, their unique ID is sent to the API which responds with their encrypted data. Their locally stored password is then used to decrypt the data for use by the app.
I've implemented the app in javascript, and the API in Node.js (restify) with MongoDB as a backend, so in practice a sync requests to the server looks like this:
1. Initial sync
POST /api/data
Post body:
{
"data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd..."
}
Response:
{
"id":"507f191e810c19729de860ea",
"lastUpdated":"2016-07-06T12:43:16.866Z"
}
2. Get sync data
GET /api/data/507f191e810c19729de860ea
Response:
{
"data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd...",
"lastUpdated":"2016-07-06T12:43:16.866Z"
}
3. Update synced data
POST /api/data/507f191e810c19729de860ea
Post body:
{
"data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd..."
}
Response:
{
"lastUpdated":"2016-07-06T13:21:23.837Z"
}
Their data in MongoDB will look like this:
{
"id":"507f191e810c19729de860ea",
"data":"DWCx6wR9ggPqPRrhU4O4oLN5P09onApoAULX4Xt+ckxswtFNH/QQ+Y/RgxdU+8+8/muo4jo/jKnHssSezvjq6aPvYK+EAzAoRmXenAgUwHOjbiAXFqF8gScbbuLRlF0MsTKn/puIyFnvJd...",
"lastUpdated":"2016-07-06T13:21:23.837Z"
}
Encryption is currently implemented using CryptoJS's AES implementation. As the app provides the user's password as a passphrase to the AES "encrypt" function, it generates a 256-bit key which which to encrypt the user's data, before being sent to the API.
That about sums up the sync process, it's fairly simple but obviously it needs to be secure and reliable. My concerns are:
As the MongoDB ObjectID is fairly easy to guess, it is possible that a malicious user could request someone else's data (as per step 2. Get sync data) by guessing their ID. However, if they are successful they will only retrieve encrypted data and will not have the key with which to decrypt it. The same applies for anyone who has access to the database on the server.
Given the above, is the CryptoJS AES implementation secure enough so that in the real possibility that a user's encrypted data is retrieved by a malicious user, they will not realistically be able to decrypt the data?
Since the API is open to anyone and doesn't audit or check the submitted data, anyone could potentially submit any data they wish to be stored in the service, for example:
Post body:
{
"data":"This is my anyold data..."
}
Is there anything practical I can do to guard against this whilst adhering to the guiding principles above?
General abuse of the service such as users spamming initial syncs (step 1 above) over and over to fill up the space on the server; or some user's using disproportionately large amounts of server space. I've implemented some features to guard against this, such as logging IPs for initial syncs for one day (not kept any longer than that) in order to limit a single IP to a set number of initial syncs per day. Also I'm limiting the post body size for syncs. These options are configurable in the API however, so if a user doesn't like these limitations on a public API instance, they can host their own instance and tweak the settings to their liking.
So that's it, I would appreciate anyone who has any thoughts or feedback regarding this approach given my guiding principles. I couldn't find any examples where other apps have attempted a similar approach, so if anyone knows of any and can link to them I'd be grateful.
I can't really comment on whether specific AES algorithms/keys are secure or not, but assuming they are (and the keys are generated properly), it should not be a problem if other users can access the encrypted data.
You can maybe protect against abuse, without requiring other accounts, by using captchas or similar guards against automatic usage. If you require a catcha on new accounts, and set limits to all accounts on data volume and call frequency, you should be ok.
To guard against accidental clear-text data, you might generate a secondary key for each account, and then check on the server with the public secondary key whether the messages can be decrypted. Something like this:
data = secondary_key(user_private_key(cleartext))
This way the data will always be encrypted, and in worst case the server will be able to read it, but others wouldn't.
A few comments to your API :) If you're already using HTTP and POST, you don't really need an id. The POST usually returns a URI that points to the created data. You can then GET that URI, or PUT it to change:
POST /api/data
{"data": "..."}
Response:
Location: /api/data/12345
{"data": "...", "lastmodified": "..." }
To change it:
PUT /api/data/12345
{"data": "..."}
You don't have to do it this way, but it might be easier to implement on the client side, and maybe even help with caching and cache invalidation.
When writing node.js code with the parse javascript library, it's required to initialized it with the "JavascriptKey". When using the JavascriptKey and creating a push notification, it is required to turn on "client push". The parse interface says this about client push:
Allow pushes to be sent using the public client keys. Useful during development, but we suggest disabling it on production apps.
So, it seems like something I'd rather not keep on in production, especially since I'm only creating push notifications from the server.
Do I have to use the JavaScript key with node.js? Should I be going about all this a different way?
JavascriptKey is unnecessary, so it is optional in open-sourced Parse-Server.
Try to send push with MasterKey.
Parse.Push.send({
where: query,
data: {
alert: "test"
}
},{
useMasterKey:true,
success: console.log,
error: console.error
});
If you host the Parse by yourself, you can setup it without JavascriptKey.
Some reference of open-sourced Parse-Server.
The client keys used with Parse are no longer necessary with Parse Server.
https://github.com/ParsePlatform/parse-server
Client push is not supported. You can only use masterKey to send push notifications
https://github.com/ParsePlatform/parse-server/wiki/Push
I just read this post, and I do understand what the difference is. But still in my head I have the question. Can/Should I use it in the same App/Website? Say I want the AngularJs to fetch content and update my page, connecting to a REST api and all of that top stuff. But on top of that I also want a realtime chat, or to trigger events on other clients when there is an update or a message received.
Does Angular support that? Or I need to use something like Socket.io to trigger those events? Does it make sense to use both?
If someone could help me or point me to some good reading about that if there is a purpose for using both of them together.
Hope I'm clear enough. thank you for any help.
Javascript supports WebSocket, so you don't need an additional client side framework to use it. Please take a look at this $connection service declared in this WebSocket based AngularJS application.
Basically you can listen for messages:
$connection.listen(function (msg) { return msg.type == "CreatedTerminalEvent"; },
function (msg) {
addTerminal(msg);
$scope.$$phase || $scope.$apply();
});
Listen once (great for request/response):
$connection.listenOnce(function (data) {
return data.correlationId && data.correlationId == crrId;
}).then(function (data) {
$rootScope.addAlert({ msg: "Console " + data.terminalType + " created", type: "success" });
});
And send messages:
$connection.send({
type: "TerminalInputRequest",
input: cmd,
terminalId: $scope.terminalId,
correlationId: $connection.nextCorrelationId()
});
Usually, since a WebSocket connection is bidirectional and has a good support, you can also use it for getting data from the server in request/response model. You can have the two models:
Publisher/Subscriber: Where the client declares its interest in some topics and set handlers for messages with that topic, and then the server publish (or push) messages whenever it sees fit.
Request/response: Where the client sends a message with a requestID (or correlationId), and listen for a single response for that requestId.
Still, you can have both if you want, and use REST for getting data, and WebSocket for getting updates.
In server side, you may need to use Socket.io or whatever server side framework in order to have a backend with WebSocket support.
As noted in the answer in your linked post, Angular does not currently have built-in support for Websockets. So, you would need to directly use the Websockets API, or use an additional library like Socket.io.
However, to answer your question of if you should use both a REST api and Websockets in a single Angular application, there is no reason you can't have both standard XmlHttpRequest requests for interacting with a REST api, using $http or another data layer library such as BreezeJS, for certain functionality included in various parts of the application and also use Wesockets for another part (e.g. real time chat).
Angular is designed to assist with handling this type of scenario. A typical solution to would be to create one or more controllers to handle the application functionality and update your page and then creating separate Services or Factories that encapsulate the data management of each of your data end points (i.e. the REST api and the realtime chat server), which are then injected into the Controllers.
There is a great deal of information available on using angular services/factories for managing data connections. If you're looking for a resource to help guide you on how to build an Angular application and where data services would fit in, I would recommend checking out John Papa's AngularJS Styleguide, which includes a section on Data Services.
For more information about factories and services, you can check out AngularJS : When to use service instead of factory
I want to build an entire web app using only Javascript and MYSQL . How can I go about this if it's possible.
Try something like Jaxer, which will allow you to execute JavaScript on the Web Server and query databases.
Here are some syntax examples and usages:
Database, file, and socket access from JavaScript
alt text http://jaxer.org/images/Picture+4_0.png
Easily create RESTful JSON data services
alt text http://jaxer.org/images/Picture+6.png
Directly call server-side functions from the browser
alt text http://jaxer.org/images/Picture+2_0.png
You can do it with Jaxer. There are some screencasts that'll get you started. Also check out project Phobos. Jaxer integrates nicely in Aptana studio, Phobos in Netbeans.
If you can run javascript on the server, you can build a web-application with it (without the need for any other language like PHP etc.). Search the web for 'connection string mysql' to find out how to connect to your mySQL database and use ADO/ODBC. You'll need the MySQL ODBC-connector on the MySQL server.
Here's an example database connection (where MySQL server resides on the same server as the web server):
function connectDB()
{
var connectStr = "DRIVER={MySQL ODBC 3.51 Driver}; " +
"SERVER=localhost; " +
"PORT=[MySQL server port];" +
"DATABASE=[your database]; " +
"UID=[username];PWD=[password];" +
"OPTION=3",
conection = Server.CreateObject("ADODB.Connection");
//ERRID=>lib::connectDB::open
try {connection.Open(connectStr) }
catch(e) {errAlert(e,'rs::connectDB','connection failed',1) }
return connection;
}
(Where errAlert is a custom function to return the error)
You could write your application entirely in client side javascript with AJAX / REST calls to your database server - using something like CloudKit on your server (or CouchDB, which features a native JSON HTTP interface). On the client side, Dojo or YUI abstract out a great deal of the IO handling…
It's quite possible to write a web application using only javascript. One the key benefits of that is that since all code runs locally, you can make an application which doesn't require online connectivity.
The main detractor though, is that you can't hook it up to a database. But there are alternative data storage hacks you can use.
One example of such a javascript application is TiddlyWiki which is a personal wiki, contained in a single html file. The javascript application rewrites that html file, so you can carry it with you on a USB-drive or something.
You could look at triplify which should expose your database as json and rdf. I haven't actually used this but I would imagine that would let you bypass writing any server side js and talk to the database directly in a language javascript understands, using an ajax request and json.
You can build client-side applications in javascript, with an embedded database. HTML 5 has support for databases, and a couple of browsers have already implemented this part of the spec (safari, firefox with the gears plugin).
But this is only for clientside usage. You wont be able to share the database with other users. Also you can select which database you want to use. I think gears uses sqlite.
You will not be able to use Javascript and MYSQL without using something such as PHP on the server side to bridge the gap between the database and the Javascript on the client side.
Edit: I may be wrong, however I have no idea how you would run Javascript on the server side.