accessing pouchdb.authentication.js user metadata

110 views
Skip to first unread message

Bill Stephenson

unread,
Apr 10, 2016, 6:55:38 PM4/10/16
to PouchDB
How do I access metadata stored in the CouchDB _users database when using pouchdb.authentication.js?

The metadata is there, in the users db record:

{
 
"_id": "org.couchdb.user:tester3",
 
"_rev": "1-ff6bfdd3950cec6fa7e00a1effb95665",
 
"password_scheme": "pbkdf2",
 
"iterations": 10,
 
"name": "tester3",
 
"roles": [],
 
"type": "user",
 
"email": "te...@test3.com",
 
"member_name": "test 3",
 
"derived_key": "6b1e0e96ddf32b24da6ccc6beb1ebd4aa3da0c6d",
 
"salt": "862cd740fab74feee82cdd6f52c6f5f2"
}


Here's how I tried to access it, but no joy:

function getUserID() {
  db
.getSession(function (err, response) {
 
if (err) {
 
// network error
  console
.log('network error ');
 
} else if (!response.userCtx.name) {
 
// nobody's logged in
  console
.log('Not Logged In ');
 
} else {


// response.userCtx.name is the current user


// getting the user name works...
  console
.log('Session: User: ' +response.userCtx.name);


// these don't work for getting metadata....
  console
.log('Session: Member Name1: ' +response.member_name);
  console
.log('Session: Member Name2: ' +response.userCtx.member_name);
  console
.log('Session: Member Name3: ' +response.userCtx.metadata.member_name);
  console
.log('Session: Member Name4: ' +response.metadata.member_name);
 
}
 
});
}


Here's how I create the user record:

function add_user() {


 
var data={};
 
var inputs = $('#join-us').serializeArray();
 $
.each(inputs, function (i, input) {
 data
[input.name] = input.value;
//      alert(input.name +'='+ input.value);
 
})


 db
.signup(data.username, data.password, {
  metadata
: {
 email
: data.email,
 member_name
: data.member_name,
 
}
 
}, function (err, response) {

 
if (response) {
 console
.log('Successfully posted '+data.name);
 document
.getElementById("message_alert").innerHTML="<strong>Thank You!</strong> Together we will make a difference.";
 $
("#message_alert").fadeIn('2000');
 
}


 
if (err) {
 console
.log('Error: ' +err);
 
}
 
// etc.
 
});
}


Alexander Harm

unread,
Apr 11, 2016, 3:29:13 AM4/11/16
to PouchDB
After you retrieve the username via getSession() you have to retrieve the user doc via getUser(username). Also your "else if" regarding the username is superfluous. If there is no error you will receive the username. For authentication errors check for error.status === 404. I edited your example, it should work like this:

function getUserID() {
  db.getSession(function (err, response) {
    if (err) {
      if (err.status === 401) {
        // authentication error
        console.log('Authentication error ');
      } else {
        // network error
        console.log('network error ');
      }
    } else {
      // get user doc
      db.getUser(response.userCtx.name, function (err, response) {
        if (err) {
          if (err.status === 401) {
            // authentication error
            console.log('Authentication error ');
          } else {
            // network error
            console.log('network error ');
          }
        } else {
          // you have the user doc
          console.log('Session: Member Name1: ' +response.member_name);
          console.log('Session: Member Name4: ' +response.metadata.member_name);
        }
      });
    }
  });
}

Alexander Harm

unread,
Apr 11, 2016, 3:30:24 AM4/11/16
to PouchDB
The error code is 401, sorry.


On Monday, April 11, 2016 at 12:55:38 AM UTC+2, Bill Stephenson wrote:

Bill Stephenson

unread,
Apr 11, 2016, 5:25:53 PM4/11/16
to pou...@googlegroups.com
You need all the databases set up to run it, but as you can see the info I'm trying to access is in the "_users" database record that is used by pouchdb.authentication.js. Here's an example with metadata:

{
  
"_id": "org.couchdb.user:tester3",
  
"_rev": "1-ff6bfdd3950cec6fa7e00a1effb95665",
  
"password_scheme": "pbkdf2",
  
"iterations": 10,
  
"name": "tester3",
  
"roles": [],
  
"type": "user",
  
"email": "te...@test3.com",
  
"member_name": "test 3",
  
"derived_key": "6b1e0e96ddf32b24da6ccc6beb1ebd4aa3da0c6d",
  
"salt": "862cd740fab74feee82cdd6f52c6f5f2"
}

The metadata I've added is:

"email": "te...@test3.com",
"member_name": "test 3",

The "name" in that record is the username that a user logs in with.

I can access the "name" in that record with this:


Everything else is working as documented. The docs say this about metadata:

Options
  • metadata : Object of metadata you want to store with the username, e.g. an email address or any other info. Can be as deeply structured as you want.

But "response.userCtx.member_name" doesn't return a value for the metadata I've added. 

I did find a question about this same issue on stack exchange. It hasn't been answered yet, but I'm not the only one who's either does not understand this, or there could be an issue in pouchdb.authentication (or even CouchDB) that's preventing us from accessing that data. 

The reason I ask is because I wanted to use that database and those records to create a user "Preferences" app, but if can't find a way to get at that metadata I'm stuck from going any further in that direction. :(

I suppose I could try letting a user access the "_users" database directly to see if I can get at that metadata, but pouchdb.authentication.js creates a fairly complex design document that I've assumed would restrict users from doing that. I could be wrong about that. Maybe Nolan expects us to do that. :D 


--
You received this message because you are subscribed to a topic in the Google Groups "PouchDB" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pouchdb/fJYxr27MX6A/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pouchdb+u...@googlegroups.com.
To post to this group, send email to pou...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pouchdb/63d47cc6-459f-4c81-ab7e-2cdfa0a7df30%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Bill Stephenson

unread,
Apr 11, 2016, 5:59:51 PM4/11/16
to pou...@googlegroups.com
Thank you!

I don't know how I missed that, but I very much appreciate you taking the time to point it out and demonstrate it for me. 

--
You received this message because you are subscribed to a topic in the Google Groups "PouchDB" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pouchdb/fJYxr27MX6A/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pouchdb+u...@googlegroups.com.
To post to this group, send email to pou...@googlegroups.com.

Bill Stephenson

unread,
Apr 11, 2016, 11:08:23 PM4/11/16
to pou...@googlegroups.com
I moved on to trying to update a user's record but no joy there.

While "db.changePassword" works for changing a user's password it does not update the metadata (at least not how I tried to do it), so I still haven't figured out how use that file for a user's preferences. 

Not a huge deal, I just made another database for that instead, but it'd be cleaner if I could figure it out. Here's what I tried that failed:

function savePrefs() {

 console.log('savePrefs');
     
 remote_user_db.getSession(function (err, response) {
if (err) {
 // network error
 console.log('network error ');
} else if (!response.userCtx.name) {
 // nobody's logged in
 console.log('Not Logged In ');
} else {
 // response.userCtx.name is the current user
 console.log('name: ' +name);

 password = $("input:password.userpass").val();
 member_name = $("input:text.member_name").val();
 email = $("input:text.email").val();

 console.log('password: ' +password);
 console.log('member_name: ' +member_name);
 console.log('email: ' +email);

 remote_user_db.changePassword(name, password, {
metadata : {
 email : email,
 member_name : member_name,
 updated: new Date().toISOString(),
}
 }, function (err, response) {
if (response) {
 document.getElementById("message_alert").innerHTML="<strong>Preferences have been updated.";
}
if (err) {
 console.log('Error: ' +err);
}
 });
}
 });
}

Alexander Harm

unread,
Apr 12, 2016, 2:37:17 AM4/12/16
to pou...@googlegroups.com
To update a users record with your custom metadata you need to directly connect to the _users database.

pdbUsers = new PouchDB(‘http://your/address/_users')

Then retrieve the users document with a simple get, update it and put it back.

Regards.

Bill Stephenson

unread,
Apr 13, 2016, 5:27:57 PM4/13/16
to pou...@googlegroups.com
Thank you again Alexander!!

I messed with this quite a bit yesterday but got stuck on the design document that pouchdb.authentication creates for _users database. 

My problems are bigger than this though. I've been pretty much avoiding learning what I need about using CouchDB by using PouchDB with Cloudant during this design process, but things are growing more complex now. I finally built CouchDB from source on my VPS recently so I could start digging into it properly so I've got a lot to learn yet.

All that said, I have learned a lot already in the past few days, and you've been a great help and I sincerely appreciate you taking the time to help me. 


Bill Stephenson

unread,
May 7, 2016, 2:32:28 PM5/7/16
to PouchDB
Unless I completely missed it before, it looks to me like the latest update to pouchdb.authentication.js (0.5.1) provides a solution to the issue I was dealing with by adding the  "db.getUser" function.

Either way, this worked for me and I want to thank Nolan Lawson for providing this. 

Nolan Lawson

unread,
May 19, 2016, 9:27:02 PM5/19/16
to PouchDB
No problem, actually it was contributed by someone else, so I can't really take credit for it. :)
Reply all
Reply to author
Forward
0 new messages