Create users own document in CouchDB with node.js - node.js

I want to make documents, which can be updated/changed by one concrete user(the user which has created it). Document content wich all users can see but only the owner can change it. The question is:
If I have user with username "TheUser" how can create his own document named "TheUserDocument". It's not a problem to use just Nodejs, Nano or something else for database.

This can be accomplished with a document update validation function. When you originally create the document, store the user who created it, then your update validation function might look something like this:
function(newDoc, oldDoc, userCtx, secObj) {
if ( oldDoc.creator == userCtx.name ){
return;
}
throw({forbidden: 'Permission denied.'});
}
You can read more about validation functions here: http://docs.couchdb.org/en/latest/ddocs.html#validate-document-update-functions

Related

Srapi - retrieve 1-n property from the Lifecycle call back model parameter

i am using Strapi for a prototype and i am meeting the following issue. I have created a new content type "Checklist" and i added in it a relation property 1 to many with the User model provided by the users-permissions plugin.
Then i wanted to add some custom logic on the lifecycle call back, in beforeSave and in beforeUpdate from which i would like to access the user assigned to the Checklist.
The code looks like that:
{
var self = module.exports = {
// Before saving a value.
// Fired before an `insert` or `update` query.
generateLabel : (model) => {
var label = "";
var day = _moment(model.date,_moment.ISO_8601).year();
var month = _moment(model.date,_moment.ISO_8601).day();
var year = _moment(model.date,_moment.ISO_8601).month();
console.log(model);
if (model.user) {
label = `${model.user}-${year}-${month}-${day}`;
}else{
label = `unassigned-${year}-${month}-${day}`;
}
return label;
I call the method generateLabel from the callback. It works, but my model.user always returned undefined. It is a 1-n property. I can access model.date property (one of the field i have created) without any issue, so i guess the pbs is related to something i have to do to populate the user relation, but i am not sure on how to proceed.
When i log the model object, the console display what i guess is a complete mongoose object but i am not sure where to go from there as if i try to access the property that i see in the console, i will always reach an undefined.
Thanks in advance for your time, i use the following
strapi: 3.0.0-alpha.13.0.1
nodejs: v9.10.1
mongodb: 3.6.3
macos high sierra
Also running into the similar / same issue, I think this has to do with the user permissions plugin, and having to use that to access the User model. Or I thought about trying to find the User that’s associated with the id of the newly created record. I’m trying to use AfterCreate. Anyone that could shed some light on this would be great!
It's because relational attributes are not send in create fonction (See your checklist service add function).
Relations are handled in an other function updateRelations.
The thing you can do is to send values in Checklit.create()

Kentico 10 - How do I update the username of an existing user?

Using a kentico 10 website with claims based authentication. We have the facility to update their email address in the external system. So what I want to do is update the user's email address and username by looking up based on the external userid from our sso platform.
var existingUser = UserInfoProvider.GetUsers().Where("ExternalGuid", QueryOperator.Equals, userId).FirstOrDefault();
if (existingUser.IsInSite(SiteContext.CurrentSiteName))
UserInfoProvider.RemoveUserFromSite(existingUser.UserName, SiteContext.CurrentSiteName);
loggingInUser = UserInfoProvider.GetUserInfo(existingUser.UserID);
loggingInUser.UserName = e.UserName;
UserInfoProvider.SetUserInfo(loggingInUser);
I'm getting the error:
The user with code name 'ac.aa#test.com' already exists.
This is happening on that SetUserInfo line. So I'm thinking there must be another way to update the username properly.
You need to do a few things:
Check if the user exists already:
UserInfo ui = UserInfoProvider.GetUserInfo(newUserName);
if (ui != null)
{
// user exists with new username so don't continue
}
Check if the username can be used as a username (no spaces, special characters, etc):
if (!ValidationHelper.IsUserName(newUserName))
{
// username cannot be used as a username
}
Check if the username is reserved or not:
if (UserInfoProvider.NameIsReserved(siteName, newUserName))
{
// reserved username so cannot use it
}
I'm willing to bet the username is reserved or not valid which is why it is not saving. The assignment you have done should work without issue.
It also looks like you're performing this update in a global handler so this could cause problems with a few things. So you may have to perform that username update later on or simply write a record to a custom table and then update it from there based on the event of creating those records in the custom table.
So I'd debug through your code and verify it is working properly by removing it from the global event handler, if it works, then it's an issue with having too many things happen at one time.
Try using SetValue(string columnName, value) method, I just tested this one and it worked fine:
UserInfo updateUser = UserInfoProvider.GetUserInfo("NewUser");
if (updateUser != null)
{
// Updates the user's properties
updateUser.SetValue("UserName", "NewUserName");
// Saves the changes to the database
UserInfoProvider.SetUserInfo(updateUser);
}
For some properties/columns, which are acting like "read only", you need to use the SetValue method like it was a custom field (API examples)

Can you use CouchDB 'document update handlers' with replication?

I am replicating docs from DB A to DB B, every time a Doc from DB A arrives in DB B I want to run a 'stored procedure' to remove most of the fields from DB A (DB A is private, but has attachments that I want to be publicly available)
So far I've seen that this might be achieved using the _changes feed (continuous)and then running an 'update' handler on each document.
The document update handlers doc: https://wiki.apache.org/couchdb/Document_Update_Handlers
This seems like something that CouchDB would implement for me... (and I'm not really sure yet how to do the above).
Is there something like a 'hook' that can be run on every document that enters the database?
== EDIT ==
It seems that I would want to somehow include the update handler command in the replication trigger?
It sounds like with some changes to how your storing documents you may be able to benefit from CouchDB's filtered replication. You'd need to store the attachments in documents that could be equivalently copied (without modification) between the two databases.
If that's not an option, then you could potentially use transform-pouchdb plus PouchDB's .replicate.from() method to manage the replication.
Some quick pseudo-code for this idea looks a bit like this:
var PouchDB = require('pouchdb');
PouchDB.plugin(require('transform-pouch'));
var dbA = new PouchDB('a'); // "a" could be a URL to CouchDB or Cloudant
var dbB = new PouchDB('b');
dbB.transform({
incoming: function (doc) {
// do something to the document before storage
return doc;
}
});
dbB.replicate.from(dbA);
In theory, that (or something like it) should do what you're wanting...or at least giving you the framework in which to do what you're wanting. ^_^
Hope that helps!

validate_on_update prevents deletion of a specified document

I have a simple validate_on_update function:
if (!newDoc.type) {
throw({forbidden: "All documents must have a type specified"});
}
If I do
curl -X DELETE $HOST/$DB/$DOC?rev=$REV
I get back
{"error":"forbidden","reason":"All documents must have a type specified"}
This happens even if I do
rev=$REV&type=type
Or if I do
-d'{"type":"type"}'
with curl
How can I bypass validation for deletion of documents?
CouchDB internals only know reads and updates. An update can eb the creation of the doc, an edit of a doc, or the deletion of the doc. Update funs can’t be circumvented for any type. To solve this, use if(!newDoc.type || doc._deleted) {

How do I design a couchdb view for following case ?

I am migrating an application from mySQL to couchDB. (Okay, Please dont pass judgements on this).
There is a function with signature
getUserBy($column, $value)
Now you can see that in case of SQL it is a trivial job to construct a query and fire it.
However as far as couchDB is concerned I am supposed to write views with map functions
Currently I have many views such as
get_user_by_name
get_user_by_email
and so on. Can anyone suggest a better and yet scalable way of doing this ?
Sure! One of my favorite views, for its power, is by_field. It's a pretty simple map function.
function(doc) {
// by_field: map function
// A single view for every field in every document!
var field, key;
for (field in doc) {
key = [field, doc[field]];
emit(key, 1);
}
}
Suppose your documents have a .name field for their name, and .email for their email address.
To get users by name (ex. "Alice" and "Bob"):
GET /db/_design/example/_view/by_field?include_docs=true&key=["name","Alice"]
GET /db/_design/example/_view/by_field?include_docs=true&key=["name","Bob"]
To get users by email, from the same view:
GET /db/_design/example/_view/by_field?include_docs=true&key=["email","alice#gmail.com"]
GET /db/_design/example/_view/by_field?include_docs=true&key=["name","bob#gmail.com"]
The reason I like to emit 1 is so you can write reduce functions later to use sum() to easily add up the documents that match your query.

Resources