I have two collections in my Mongo DB: users and roles. A user can have many roles. Using Mongoose I want to find out whether a particular user (based on their id) has the admin role. How do I perform that query? In SQL one way of finding out would be to write this query:
SELECT *
FROM Users
INNER JOIN Roles ON Users.id = Roles.userID
WHERE (Users.id = <some user id> AND Roles.name='admin')
But I'm failing to see how the equivalent query is done using Mongoose. Below are my Mongoose schemas:
let RoleSchema = new Schema({
name: String,
owner: {
type: Schema.Types.ObjectId,
ref: "User"
}
})
export let Role = mongoose.model("Role", RoleSchema)
let userSchema = new Schema({
username: {
type: String,
unique: true,
required: true,
trim: true
},
roles: [
{
type: Schema.Types.ObjectId,
ref: "Role"
}
]
})
export let User = mongoose.model("User", userSchema)
Read - https://mongoosejs.com/docs/populate.html#query-conditions
User.
findById(id). // can also use find/findOne depending on your use-case
populate({
path: 'roles',
match: { name: 'admin' }
}).
exec();
This will fetch you User details and roles where name is admin.
You can check the user.roles array count to get the user is having admin role or not.
Related
I am learning to use mongoDB AND ExpressJS by building a Rest API that I would use with ReactJS.
I have always chosen MySQL for the management of my database, but the mongoDB database is not relational and it is still difficult for me to understand.
An example of what I want to do
Let's say that I have created a blog and want to get all the articles from a user logged in with an account.
All these operations are managed with a REST API and MongoDB.
How to create a OneToMany relationship between articles and a user.
With MySQL I just had to specify a user_id key for each article in an article table.
But with mongoDB how to create this and especially for a user who is logged in with an account, so that only a logged in user can view his articles.
EDIT
I have tried something, it works but I don't know if it's the right approach.
Context:
I made a REST API with NodeJS and ExpressJS.
The API will allow a user to organize their applications to facilitate the search for a job.
A user must create an account and log in to take advantage of all of the application's features, so no information is publicly available.
For registration and authentication of a user, I use PassportJS, mongoConnect and ExpressSession
To start, the User model of mongoDB
const userSchema = mongoose.Schema({
name: {
type:String
},
email: {
type:String,
required:true,
unique:true
},
email_is_verified: {
type:Boolean,
default:false
},
password: {
type:String,
},
referral_code : {
type:String,
default: function() {
let hash = 0;
for(let i=0; i < this.email.length; i++){
hash = this.email.charCodeAt(i) + ((hash << 5) - hash);
}
let res = (hash & 0x00ffffff).toString(16).toUpperCase();
return "00000".substring(0, 6 - res.length) + res;
}
},
referred_by : {
type: String,
default:null
},
third_party_auth: [ThirdPartyProviderSchema],
date: {
type:Date,
default: Date.now
}
},
{ strict: false }
);
module.exports = mongoose.model('Users', userSchema);
The Apply model represents an apply for a job, for now there is only the title.
To create the OneToMany relationship, I add a User field which refers to my User model
Function to retrieve all applies, so I retrieve the user id of the session.
const applySchema = mongoose.Schema({
title: { type:String, required:true },
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
}
})
module.exports = mongoose.model('Apply', applySchema);
I created a controller for the management of a user's applies
exports.getAllApplies = (req, res, next) => {
res.locals.currentUser = req.user;
const userId = res.locals.currentUser.id
Apply.find({ user:userId })
.then(applies => res.status(200).json({ message:'success',
applies:applies }))
.catch(error => res.status(400).json({ error:error, message: 'Failed'}))
}
Function allowing to consult an apply
exports.getOneApply = (req, res, next) => {
res.locals.currentUser = req.user;
const userId = res.locals.currentUser.id
Apply.findOne({ _id:req.params.id, user:userId })
.then(apply => res.status(200).json({ message: `Apply with id
${apply._id} success`, apply:apply}))
.catch(error => res.status(500).json({ error:error, message:'Failed'}))
}
The routes of my api, I add an auth middleware to allow requests only for a user with a token
const express = require('express');
const router = express.Router();
const auth = require('../middleware/auth');
const applyCtrl = require('../controllers/apply');
router.get('/', auth, applyCtrl.getAllApplies);
router.get('/:id', auth, applyCtrl.getOneApply);
module.exports = router;
I apologize for the length of the post, if you have any questions, I would be happy to answer them.
Thank you in advance for your help and your answers.
I am trying to set up a keystone project with a remote database server hosted on mLab. I am using this guide here https://itnext.io/building-a-node-cms-with-keystonejs-mongo-db-react-and-redux-part-i-ae5958496df2
I have edited the mongo url in the keystone.init() configuration, with my mLab database URL, and managed to run the project.
'mongo': 'mongodb://*username*:*password*#ds127624.mlab.com:27624/keystone',
However, I am unable to login as a user.
The login page returned:
"The email and password you entered are not valid."
Do I need to do some more configurations for it to work properly?
....
user.js
var keystone = require('keystone');
var Types = keystone.Field.Types;
var User = new keystone.List('User');
User.add({
name: { type: Types.Name, required: true, index: true },
email: { type: Types.Email, initial: true, required: true, index: true },
password: { type: Types.Password, initial: true },
canAccessKeystone: { type: Boolean, initial: true },
});
User.register();
0.0.01-admin.js file
var keystone = require('keystone');
var User = keystone.list('User');
exports = module.exports = function (done) {
new User.model({
name: { first: 'admin', last: 'user' },
email: 'admin#keystonejs.com',
password: 'admin',
canAccessKeystone: true,
}).save(done);
};
For remote database with password you also have to add authsource option. basically add ?authSource=admin to your mongo url. admin is default db, you can change that as well
mongodb://*username*:*password*#ds127624.mlab.com:27624/keystone?authSource=admin
Iam building a node js application and OrientDB as the database. Is there someway to create a model for my vertices in node like we do if were using MongoDB?
For instance, I have a class called Account with propertise name, password and email.
Is it possible to create a model for this in node when using OrientDB and OrientJS as the language driver?
Appreciate any help.
I don't know if I understood it correctly, but this is how to create the class you described:
var OrientDB = require('orientjs');
var server = OrientDB({
host: 'localhost',
port: 2424,
username: '<username>',
password: '<password>'
})
var db = server.use({
name: 'mydb',
username: '<username>',
password: '<password>'
})
db.class.get('Account')
.then(function (MyClass) {
MyClass.property.create([{
name: 'name',
type: 'String'
},{
name: 'password',
type: 'String'
},{
name: 'email',
type: 'String'
}])
.then(function () {
console.log('Properties created')
});
})
server.close();
Hope it helps
Regards
I want to change my Rest-API validation to node simple schema for schema definition and collection2#core for schema validation.
I want to use the Person schema to validate the data provided by the users.
Schemas = {};
Schemas.Person = new SimpleSchema({
name: {
type: String,
label: "Person's Name",
unique: true,
max: 200
},
surname: {
type: String,
unique: true,
label: "person's surname"
},
};
validData = API.utility.validate(data, Schemas.Person });
API: {
utility: {
validate: function(data, schema) {
return "The SimpleSchema Validation";
}
}
};
This case is described in the simpl-schema documentation
With your schema definition you can just do:
Schemas.person.validate(data);
If right after that you want to look at the result or the errors:
Schemas.person.isValid();
Schemas.person.validationErrors();
I am trying to send all the permissions for an authenticated user via JSON from Sails.
My current code to find permissions for a single model type:
hasPermission: function hasPermission(req, res) {
var permitted = PermissionService.isAllowedToPerformAction({
method: req.param('method'),
model: sails.models[req.param('model')],
user: req.user
});
return res.json(200, { permitted: permitted });
}
This code doesn't work as isAllowedToPerformAction wants a single instance of a model. Is there a way to return a single JSON file accounting for all permissions?
Try creating roles and give them permissions.
Assign role to users
Ex.
PermissionService.createRole({
name: 'carsCategoryAdmin',
permissions: [
{ action: 'update', model: 'review', criteria: [{ where: { category: 'cars'}}]},
{ action: 'delete', model: 'review', criteria: [{ where: { category: 'cars'}}]}
],
users: ['venise']
})
You can examine the role and related permissions and users,
Role.find({name:'carsCategoryAdmin'})
.populate('users')
.populate('permissions')
.exec(console.log)
See more # sails-permissions-by-example
See how to get user permissions with code in comment given by skrichten on May 10, 2014 .