2

I'd like to extend a module (or create my own) to auto add users to Apostrophe (aposUsersSafe collection).

I don't see any built in method in the apostrophe-users module for doing this, and am looking for some guidance as to how it might be implemented? Thanks!

lance-p
  • 1,050
  • 1
  • 14
  • 28

1 Answers1

2

As mentioned previously I'm the principal architect of Apostrophe at P'unk Avenue.

The aposUsersSafe collection is for storing password hashes and denormalized copies of a few closely related properties only. You normally would never need to interact with it directly. Like all other docs in Apostrophe, users live in the aposDocs collection. And it's best to interact with them via the methods provided by the module that manages that type of piece. In this case, that would be apos.users (the apostrophe-users module).

Check out this method; this is refactored lightly from the addFromTask method of apostrophe-users, which implements adding a user and also adds them to a group, something you will almost certainly want to do also.

There is no code here to hash the password because the insert method of apos.users will do that for us.

self.addUser = function(req, username, password, groupname, callback) {
  // find the group
  return self.apos.groups.find(req, { title: groupname }).permission(false).toObject(function(err, group) {
    if (err) {
      return callback(err);
    }
    if (!group) {
      return callback('That group does not exist.');
    }
    return self.apos.users.insert(req, {
      username: username,
      password: password,
      title: username,
      firstName: username,
      groupIds: [ group._id ]
    }, { permissions: false }, callback);
  });
};

permission(false) is called on the cursor and an options object with { permissions: false } is passed to insert because I am assuming you want this to happen at this point regardless of who triggers it.

I recommend reading this tutorial on Apostrophe's model layer to get a solid grounding in how to work with Apostrophe's content types without getting into trouble. You can use MongoDB directly, but you have to know when to do that and when not to.

You can pass more properties when inserting the user; this is just the bare minimum for reasonable behavior.

As for calling the method, if you were to add it to lib/modules/apostrophe-users/index.js at project level inside construct, then you might call it like this from middleware:

return self.apos.users.addUser(req, username, password, groupname, function(err, newUser) {
  if (err) {
    // Handle the error as you see fit, one way is a 403 forbidden response
    res.statusCode = 403;
    return res.send('forbidden');
  }
  // newUser is the new user. You could log them in and redirect,
  // with code I gave you elsewhere, or continue request:
  return next();
});

Hope this is helpful!

Tom Boutell
  • 7,281
  • 1
  • 26
  • 23
  • Thanks. This is definitely helpful. If I understand your suggestion, I would add self.AddUser to construct in my lib\modules\apostrophe-users module. I then want to invoke this method from the check that I am performing in my apostrophe-express module: `middleware: [ function(req, res, next) { const email = //from cookie const auth = //from cookie if(email && auth) { //how do I invoke addUser here? //apostrophe-users.addUser(req, email, '', 'admin', null) } }` Not sure how to invoke? – lance-p Oct 04 '16 at 01:10
  • Looking at the other answer you provided in the auto login users (demo-autologin module), you use the self.pageBeforeSend method. I was thinking that this would only get executed on matching routes, but it looks like this is executed on each request by virtue of the module being defined in app.js. From my understanding then, this self.pageBeforeSend method can be used to execute any code I want to on any page request - having access to the request and apos objects. If this isn't the way to execute code on each request, can you point me to a better approach? – lance-p Oct 04 '16 at 15:20
  • If you add this method to apostrophe-users/index.js as you suggest, then you would invoke it like this from a middleware function in another module: return self.apos.users.addUser(req, username, password, groupname, function(err, newUser) { if (err) { // Handle the error as you see fit, one way is a 403 forbidden response res.statusCode = 403; return res.send('forbidden'); } // newUser is the new user. You could log them in and redirect, // with code I gave you elsewhere, or continue request: return next(); }); – Tom Boutell Oct 05 '16 at 01:03