Updating hashed passwords in Mongoose - hash

this mongodb blog post shows how to store hashed passwords. It uses a pre-hook so when a password is saved, it's automatically hashed.
However, it also states that the hook doesn't get called on an 'update' operation, just on 'save'.
How would one update a password in Mongoose via the save pre-hook method?

According to the docs, there should also be a pre update hook available. It is at the bottom of this page.
This is the code (according to the docs) to update the updatedAt field.
schema.pre('update', function() {
this.update({},{ $set: { updatedAt: new Date() } });
});

Related

How to test whether an ID is a valid MongoDB Object ID using Jest?

I am new to javascript and came across this problem. After searching for a solution on Google I realized that there is no such question asked on StackOverflow. After I figured out the solution I thought of sharing it here in case it helps someone.
I'm building a To-Do list app where a user is created with fields username (email), password, and DOB. I'm using MongoDB to store user and todo data. After the user is created, they can log into the app with their username and password.
When the user logs in, I need to get their userID from their username. The path I'm using to GET the userID is - /api/user/username/:username I'm using Jest for TDD so I need to write tests first for the above case.
One of the specifications out of different test cases in the test suite is: get UserID from username and return userID in MongoDB ObjectID format.
How do I check whether the userID returned is in MongoDB ObjectID format?
To check if a userID is a valid MongoDB ObjectID using Jest, one can use
expect(ObjectID.isvalid(userID)).toBeTruthy();
One example is as follows:
it(`must get userID when username is in valid email format & available in db and return userID in mongoDB ObjectID format`, async (done) => {
const response = await request(app)
.get(`/api/user/username/${username}`)
.set({ "x-token-header": jwtToken })
.send();
const { body } = response;
expect(ObjectID.isValid(body)).toBeTruthy();
done();
});

Meteor reactively copy certain fields from user collection to custom userprofiles collection

On Meteor, I have installed konecty meteor-user-presence (link) package to enable user status for each users on my application. This package adds additional fields (status, statusConnection) on Meteor User collection. In my current application setup, I have a different collection called UserProfiles that is used to store additional information about each users. I used id from the user collection as an identifier for the UserProfiles collection, under the field owner.
Is there a way to reactively copy updates from the two fields (status & statusConnection) from the user collection, to the custom UserProfiles collection?
I am able to achieve this using another package from Atmospherejs called collection-hooks {matb33:collection-hooks}. I basically add this into my main.js on the server:
Meteor.users.after.update(function (userId, doc, fieldNames, modifier) {
UserProfiles.update({
owner : doc._id
}, {
$set: {
status : doc.status
}
}, {multi: true})
});
This package add a hook to collections. Every time the application fires update to Meteor.users collection, which is basically every time when the konecty meteor-user-presence changes the status & statusConnection fields in the user collection, the collection-hooks package hook on the update action and perform additional tasks. The package also has other useful hooks e.g. before.insert,before.update, before.remove,after.insert, after.update and after.remove.
The {multi: true} is needed to enable the behaviour to be applied to all users. I do not know whether this will have an impact on the app performance, i'm sure it has some impact especially when the app scales up with large userbase. You should apply this solution carefully.
Here's a good primer for you to start: A Look At Meteor Collection Hooks

How to pass MongoDB _id inside of get request to retrieve a collection

Building an app on Vue, Express, Mongo and Node. Trying to use _id from a mongo record to retrieve that records contents. I can use postman with the exact path /builds/5a9e3870b73d8f342ea7da56 and it returns what I need. But I want the user to be able to input an _id into a textbox and the get request will use that to get the record.
app.get('/builds/:id', function (req, res) {
console.log("query params:", req.query);
model.Build.find({_id: req.params.id }).then(function(build) {
res.set('Access-Control-Allow-Origin', '*');
res.json(build);
});
});
Basically what I am asking is what can I add on my html side so that whatever id the user enters into a text box gets sent as a get request.

How do relations work in MeteorJS/Mongodb?

and am not sure where to find this in the docs. How can I add more objects to the User object?
For instance if I run
meteor add accounts
and I get a full user collection with a working user login/signup template. I would like to add a posts collection/object inside this users collection, so that users can only view there own posts.
So how can I add each post to the current users object?
You can add users to the Meteor.users collection by adding accounts-password package. Use Accounts.createUser() method to create new users.
Find the documentation here: https://docs.meteor.com/api/passwords.html#Accounts-createUser
Meteor.users is a handle to users collection in Meteor. You can use it just as any other collection AKA
Meteor.users.findOne(id)
or
Meteor.users.update(...)
And of course you can't add posts collection to user collection. These will be different collections.
Storing objects in MongoDB under users collection document is pretty straight forward:
Meteor.users.update(
{ _id: userId },
{ $set: { objectFieldName: { a: 1, b: 2 }}}
)
Or if you need to do it on user create you should user Accounts package hooks.
You are approaching it wrong. Use pub/subs to achieve this.
When you insert a post, have a field called userId or ownerId
//inside Meteor.methods() on server side
Posts.insert({
owner: Meteor.userId(),
//some other fields
});
Then in your publication, return only the Posts that the user owns
//publication on server side
//checks if the visitor is a user
//if user, returns that user's posts
Meteor.publish('posts', function() {
if (this.userId) {
return Posts.find({owner: this.userId})
}
});
Then subscribe to the publication. No parameters needed:
//client side
Meteor.subscribe('posts')

How to related/associate to Mongo Collections in Meteor without using simple schema

I am working on a meteor project.
Step 1
I've added the accounts-password and the accounts-ui packages so in order to have a users collection and an authenticating system.
Step 2
I've created a Mongo collection 'Posts' of documents with the following fields: _id, title, description and createdOn(date).
Step 3
I've created another Mongo collection 'Comments' of documents with the following fields: _id, comment ,postedOn('date') and createdBy(Meteor.user()._id)
Step 4
I've added the iron router package and set some routing. You can view a blog list and go to single post detail page.
I want to give the possibility to the users who are logged in to post comments
on a single comment without using the aldeed simple-schema package.
Find below some snippets from my project:
Template.posts_list.helpers({
posts:function(){
return Posts.find({}, {sort: {createdOn: -1} });
}
})
Template.comments.helpers({
comments:function(){
return Comments.find({ ????? Ho can I associate comments to a single post? });
}
})
I am wondering how can I make the proper association between the 2 collections. I would like to show only those comments associated to the related post. As of now all the comments appear to every post without distinction. Any help? Thanks
You want to add a postId to your comments schema. Then, whenever you're submitting a comment, get the _id of the post in question and send it to your meteor method where you're inserting the comment. Something like this:
// In your template events:
'submitCommentForm': function( event, template ) {
var postId = this._id; // Make sure your post data context of this form is set in a #each or #with.
Meteor.call('addComment', event.target.comment, postId, ...) // Assuming your comment is in some sort of named input with comment as the name.
}