couchDB / pouchDB / IONIC best practice - ionic-framework

I want to create an app with IONIC to manage buildings. A user can hold multiple buildings. Each building has rooms. Each rooms has logs. Each user is a member of a cooperation.
For many years I've used LAMP. Now moving to mobile and made some IONIC apps. With 2 apps I've used sqlLite as datastore on the mobile device.
But now I've read up on couchDB and pouchDB and really like the concept and the sync option. So now I'm looking into this to use as my datastore (on the mobile and also on the backend).
Now I've got 2 major questions/concerns:
1) Authentication
In my LAMP situation, I usually have an SESSION (table which holds the sessions strings and userID) and an USERS table.
When the user logs in, the user is lookup in the USERS table, and a session string is created and saved with the userID.
Now each time a request is made to the server (for example update data), the session string is also supplied and matched to the SESSION table and retrieve the correct user. From that point on, I can validate if the post is valid and the data also belongs to the correct user.
Back to couchDB, I know there is a cookie management in couchDB (http://guide.couchdb.org/editions/1/en/security.html).
So here I can validate if an user exists and validate the credentials. Now the app can send requests with a cookie.
2) Fetch/Update the right data
In my LAMP situation, I always knew which data belongs to which user. And the back end always checks if this is correct.
In my couchDB I want to create database and each document is an user with all the data.
So now here comes the problem. I can validate an user in couchDB, put there's no way to validate the data (at least as far I know of) that it belongs to the right user.
My goal is that the mobile device syncs the document to the couchDB server.
3) Database structure
At first I wanted to create a database per user. But this is not scalable. Also an user is an member of a cooperation. I also need to generate reports per cooperation/user.
So now I was thinking to create a database per cooperation. But now the problem is, when a user login, I need to know wich database to connect to lookup the user data.
Now I want to use 1 database and each document is an user and holds al data (buildings/logs).
Has anybody got some other suggestions/resources on this approach?

You can try couchdb in combination with superlogin:
SuperLogin is a full-featured NodeJS/Express user authentication solution for APIs and Single Page Apps (SPA) using CouchDB or Cloudant.
github
Tutorial

Related

Keycloak. Storage SPI with external database

We already have DB with users.
We have to migrate all records to Keycloak DB or we can just implement Storage SPI ?
We don't want to migrate records, because we should also support old DB, it brings problems because we will need synchronize 2 DB.
Can you please write what could be the problems in this approach and write your advices for resolve theirs ?
USER DATA SOURCES
Moving to a system such as Keycloak will require an architectural design on how to manage user fields. Some user fields will need migrating to an identity database managed by Keycloak. Applications can then receive updates to these fields within tokens.
KEYCLOAK DATA
Keycloak will expect to have its own user account storage, and this is where each user's subject claim will originate from. If a new user signs up, the user will be created here before being created in your business data.
Keycloak user data will include fields such as name and email if they are sent in forgot password workflows. You can keep most other user fields in your business data if you prefer.
So to summarize, a migration will be needed, but you don't have to migrate all user fields.
BUSINESS DATA
This may include other user fields that you want to keep where they are, but also include in access tokens and use for authorization in APIs. Examples are values like roles, permissions, tenant ID, partner ID, supscription level.
DESIGN STEPS
My recent blog post walks through some examples and suggests a way to think through your end-to-end flows. There are a couple of different user data scenarios mentioned there.
It is worth doing a day or two of sketching out how you want your system to work. In particular how your APIs will authorize requests, and how you will manage both existing and new users. This avoids the potential for finding expensive problems later.

Android data persistence (Room) with different accounts

Let's assume I have a project similar to the google sample code:
https://github.com/googlesamples/android-architecture-components
I want to add an account system to the app. How can I persist data and make the following scenario work:
go to persistent-data-fragment and load data from backend
log out
log into a different account
go to that same fragment
As a result, I should not be able to see the first user's data and instead load them from backend for the second user. How to use Room for that?
It a generic question, so I can answer with a generic answer :).
1 - on the server side you need to authenticate a user that access to REST services. There are many ways to do this. JWT is a good solution. Start reading this article.
2 - on the client side, probably you need to introduce in your database a user table and link other database's entities to user identity. Using Room you have to declare a user bean and then link them to other room entities.
I hope it helps.

CloudKit Data Management

How to secure that all data related to a customer will be deleted from CloudKit when the user removes the app from his iPhone?
I got an app that saves data to a public CloudKit DB with a reference to a userID. But I don't know how to manage the data when someone deletes the app.
But I am sure there must be a possibility to manage dead data.
You will not be able to detect when a user has removed his app. What you can do is that you update a timestamp in your user record for when the app was used last. Then you could create a procedure that queries all users that have not used the app for more than ... (6 months?) And then delete all related data.
You probably don't want that procedure inside your app. You could create an admin app that connects to the same container. You will be able to access the same production container if you do an ad-hoc distribution to yourself. Or you could use the web api to do this.

GAE implementing consistant facebook login using Datastore

I am implementing an mobile app for android and iOS and I am using GAE with the datastore for persistance as the server side of my app. My app uses facebook login for user authentication. One of the key aspects of the app is that users can interact with each other through the app but I want to keep their actual facebook-id secret so that user cannot discover the facebook profile of another user through my app.
My original design for this was using MySQL and there I had a simple implementation of a users table with the table primary key, an auto-increment integer served as the user id for the app. So I could safely send the user id of other users to the client app, and this did not give away any information I did not want to give away. When a user logs in, the client app performs all the necessary facebook login procedures and sends the facebook access token to the server. The server would extract the facebook user information from this token chech if a user with this id already exists, if so use this user row, otherwise create a new one.
On an SQL database this works great since it is strongly consistent, and there is no way I will "miss" the fact that the user is already in the table. However now when I am using the eventual consistent datastore with the same idea, I ran into a problem where if a user logs in for the first time ever, an entry is added to the datastore, but then if the user logs in again shortly after the query I am performing to check if a "User" entity with the same facebook-id is already present this query sometimes still return no results. This leads to the same facebook id being assosiated with 2 different users of my app and this is obviously bad.
(I know this seems like an unlikely scenario, but I actually accidentally ran into it during development)
I thought of a few ways to mitigate this:
Instead of using the app user id as the entity key use the facebook id, this ensures consistency (since there is no index involved in the lookup now). This would imply I need to use the facebook id as the id for my app and this violates one of the design principles (the facebook id of other users will now leak to the client app).
Instead of relying on the datastore generated entity key id for the user, specify the id myself, by performing some sort of deterministic manipulation of the facebook user id, such as a hashing it or encrypting it. This way I can use the key to perform the lookup and no matter how many times the same user logs in their user id will be generated the same. But this seems like too heavy an approach to do correctly. If I hash it I will need to make sure to use a good hashing algorithm to prevent collisions. A good hash or encryption will output a long string as a user id, which is not too bad, but I would like to keep the user id as a simple long integer value if possible.
Accept the fact that this is eventually consistent, during a log in if we find more then one corresponding entity, delete them and stay with one. This is bad, because what if the user has already performed some operations that are stored on the previous entity? I will have to run through all the data for the multiple user entities from the same user and perform some sort of merging operation on them. This will also require me to run through other entities that store the user id and change them all.
Use memcache to store the user, this will probably make this scenario even more unlikely, but not eliminate it entirely. Memcache entries can be evicted prematurely, and in this case we are back to swaure one.
What is the best approach here? Is there something I am missing? Would really appropriate your input.

Multi database authentication system, where should I store sessions using Zend Framework?

I am writing an ERM application using the Zend Framework in which user accounts are created under a main company account, enabling me to limit the number of user accounts for a company based on the license which the company paid for. Each company account has its own database (with identical structure to other companies) on my server to store data relevant to that company. The name of each companies database is stored in my "back end" database along with the rest of the companies account information and license key. The authentication system works as follows:
A new user (having never used the application before) lands on the index page and is greeted by a single text field for "Company Account Number"
After clicking "Submit", the next step in authentication is for username and password. When the user submits this form, all three pieces of information (account number, user name and password) are sent to my application's Authentication handler.
My "back end" database which stores company accounts is first queried to see if the account entered by the user exists. If it does, the company_db_name column is returned and a connection established then saved in the Zend_Registry. Otherwise, authentication has failed.
If the company account does exist, the database that was returned then has its users table queried for the specified username and password hash which either returns a successful instance of MyApp_Auth or false if the credentials were incorrect.
At first, I planned on storing user session data in the individual companies database, however I have run into the problem that there is no connection to this database when first landing on the application's index page. I have planned a workaround as follows:
Move my session storage table out of the customer's database to my "backend" database, which has a connection as soon as the application launches.
Add a "company account number" column to the table and index this column.
When a user lands on the application index page, the backend database can then be queried for the current user agent's sessionid. If it is found, then return all the necessary information i.e. the company database name to establish a connection, and the user's information to build a model with.
I have a couple questions regarding this approach:
Question 1 : Is there any risk in storing all session information for every user of my application in a single back-end database table? I am thinking in the multi-thousand user mindset.
Question 2 : I am concerned that a new user may visit the index page and by complete chance (understanding that this is a very low possibility, but still possible) have the same session_id as an existing session in the back-end database. Is this a valid concern, and if so, can it be mitigated?
Question 3 : Is there a better way, or would you recommend a different method to achieve my required functionality?
Thank you for your time!
To answer your 3 questions:
Answer 1. The is not risk as such for the storing session information of every user as long as you remove it on session expiration. The issue here is "scalability" what approach are you using? Is it scalable enough? What is the write/read speed? MySQL is 'structured' approach just like MSSQL. What processing time are you looking for? How much of information is stored? What is the architectural studies. Is it feasible enough for your client?
Answer 2. Ideally the session_id will not be the same so that should not be your concern.
Answer 3. You need NoSQL (Not Only SQL but, even more) approach. Read this
Looking at the MASSIVE-ness of your data, I strongly suggest you to go for HBASE (uses Hadoop, easy for multi cluster) or CouchDB or if you are Amazon fan dynamoDB.
Questions? :)
EDIT: Just realized you are using Zend Framework. In that case, you can also use MongoDB, and use Shanty Mongo library.