How can i store my user's tasks in different collections in mongodb? - node.js

I have a simple crud task manager backend. How can i separate the data between the users? For example if one user in one device adds a new task the second user can see, delete and update that task. How can i separate the users without making a login? I searched for a bit about sessions but i don't think that's what i want in this case.

I guess you can create a uuid whenever someone comes to the page, and save that uuid in user local storage in order to manage the records.

Related

Caching user permissions in redis, good idea?

For last few days I am working on improving app performance. What do you think about caching user data and permission in redis? In my case every time when user create post or try to upload file app check in database, if user exist and fetch user permission and role. My first idea was to put permission and user role in session but user can have multiple session on different device, so every time when user get ban or user permission change app need to update every user's session and as far as I know express-session do not support this kind of feature.
Unfortunately it's a very open question with no strict answer. But as an advice, I'd say Redis is perfect for storing user session altogether. Moving parts of the session would still require you to query the database (you get the session, you must query for user information, and also ping Redis for permissions & roles). So I think you should put all session data in one place, and the fastest would be Redis. It would also let you save that data so it's not entirely in the memory. There are also many ways to optimize it, like when to write the data (like every second) and so forth.
Querying Redis is extremely fast and efficient since you don't have any user to user relations, and most of the times you won't search on anything different than "get me that user session by id".
It's a very standard solution to put user session in Redis, if not the most often used one :) Good luck!

Possible to add data into commands on certain MongoDB collections?

Is it possible to add data into commands on certain MongoDB collections?
The use case here is for simple management of multitenancy. We have data that doesn't contain the tenant's id and we then want to insert the tenant's id in on every command (find, update, updateOne, insert, insertMany, etc.) to particular collections (some collections are generic tenant wide collections). We are using the MongoDB driver (rather not use Mongoose).
Currently, we have to remember to add the tenant id whenever we use a command, but this is a bit dangerous as it is possible to miss adding the tenant's id...
Thanks!
Out of the box Mongo does not come with this feature set.
Mongoose actually shines for these kind of things with its middleware infrastructure.
If mongoose is not an option you can look into these smaller hooks implementations:
https://www.npmjs.com/package/mongohooks
https://www.npmjs.com/package/mongodb-hooks
They give you something to work with I believe.
In the end we created a helper function which we passed the data to. The helper then adds the tenant's id to any commands nessasay and send the command to MongoDB.
This allows us to control when to restrict by tenant per collection per command type.

PouchDB/CouchDB usage/schema for user data

I'm using PouchDB + CouchDB to store and sync data in an angular app currently in development. Data is stored per user and contains things such as user authorities/settings, recently viewed content and cart items.
Currently, I have a single CouchDB database that contains a doc for each user. While this structure works well for quickly retrieving user-specific data, it's logically flawed because all user docs are synced to any device that accesses the app. In other words, I ultimately only need the currently logged in user's data to sync.
So, my question is, should I create a Couch database for each user instead of using a single database with a doc for each user? Or is there a better way to go about this?
If you look at the pouchdb-authentication plugin you'll see that you can store metadata for a user in the _user database. That might be all you need.

CouchDB simple document design: need feedback

I am in the process of designing document storage for CouchDB and would really appreciate some feedback. These documents are to represent "assets".
These databases will also be synced locally to the browser via pouchdb.
Requirements:
Each user can have many assets
Users can share assets with others by providing them with a URI such as (xyz.com/some_id). Once users click this URI, they are considered to have been "joined" and are now part of a group.
Group users can share assets of their own with other members of the group.
My design
Each user will have his/her own database to store assets - let's call it "user". Each user DB will be prefixed with the his/her unique ID.
Shared assets will be stored in a separate database - let's call it "group". shared assets are DUPLICATED here and have an additional field for userId (to indicate creator).
Group database is prefixed with a unique ID just like a user database is prefixed with one too.
The reason for storing group assets in a separate database is because when pouchdb runs locally, it only knows about the current user and his/her shared assets. It does not know about other users and will should not query these "other" users' databases.
Any input would be GREATLY appreciated.
Seems like a great design. Another alternative would be to just have one database per group ("role"), and then replicate from a user's group(s) into their local PouchDB.
That might get hairy, though, when it comes time to replicate back to the server, because you're going to have to filter the documents as they leave the user's local database, depending on which group-database they belong to. Still, you're going to have to do that on the server side anyway with your current design.
Either way is fine, honestly. The only downside of your current approach is that documents are duplicated on the server side (once per user-db and once per group-db). On the other hand, your client code becomes dead-simple, because you don't have to do any filtered replication. If you have enough space on your server not to worry about it, then I would definitely go with your approach. :)

CouchDB - Figuring out database security

CouchDB offers validation prior to allowing an object/row to be inserted into the database. This make sure that if you have a public facing couch application, you're database won't be filled with junk by just anyone.
User <-> CouchDB
However, I'm tring to figure out what that looks like comming from the standard application design process where you have a trusted middle layer that does much of the auth work. For example, most apps place Ruby or PHP between the database and user agent which allows the application to figure out information about the user agent before allowing something like a post to be saved to the database.
User -> Ruby -> MySQL
User <- Ruby <- MySQL
How do you trust the user to do administrative tasks when the user can't be trusted?
For example, how would you do something like "email verification" prior to inserting a user row using just couchDB? You can't let the user agent insert the row - because they would fill the system with spam accounts. On the other hand, there is no middle layer either that can insert the row after they click the link in the email.
How about this, I would assume that you would allow anyone to enter their email by creating a new record in a public table like email_verify. This is something that a public user agent could do as the table would not do anything in the application - it would just be a holding tank.
Then node.js could track the _changes feed and send an activation email while creating a new entry in a private table (like email_confirm) (node.js would serve as a trusted middle layer). If the user clicks that link and comes back then... [unknown] ... and node.js could finally create a record in the private user table (user).
At this point we could then rely on couchdb validation for the rest of the application since we got a confirmed user account created.
As more background lets imagine a discussion built on couchdb that anyone can register for. We don't want to allow just anyone to directly submit content without some kind of verification - yet the user agents all directly run the system. (Tables would be Thread, Comment, & User). How would this work?
I would think about adding roles to existing users in this issue.
Using couchdb's validation and changing _design/_auth can be a good idea to add email, email_verified and randomly generated email_verification_code in _users database when the user firsts registers.
To send mail, get confirmation, resend confirmation you can use external processes. (for an example usage of external process you can check couchdb-lucene).
And at last you can again do a quick check in _design/_auth in user update process if verification code matches and add verified_user role for that user.
This way all your requests would pass over couchdb, you would use external process only when you need to send mail and get confirmation.
Edit : Forgot to add (since it was pretty obvious), I would add verified_user role to database readers.
Couldn't you just make use of CouchDb's Validation ?
Users could be flagged. Upon registration, a User is added to the Users database. He gets his mail and then is flagged "valid:true" or something like this upon answering to that mail or clicking a link.
With validation users could not only be "logged in/out" but also access authorization can be implemented with more granular access rights. E.g.: Only mark threads solved if one is the author, admin, whatever...
Or does this seem impracticable?
After talking with some people on #couchdb IRC, it seems that they can't figure out out a way to do something administrative (like activation users that click on a email link) with out using a "backend" process like a node.js server which keeps track of the _changes feed.
I was hoping for a pure couchdb app - but it seems like couchdb still has a little ways to go.
Still, the good news is that you can hand off 80% of your applications logic/processing to your users. The other 20% will be 1) a node.js instance for things like sending emails or checking recaptcha and 2) record validation functions running in your couchdb, and 3) map/reduce (query) functions. These three things cannot be offloaded to something "untrusted" like a user-agent.

Resources