Manage user roles with Graphcool - javascript

I'm using the template graphcool/templates/auth/email-password with Graphcool and I'd like to add the ability to manage user roles.
This is my definition schema:
type User #model {
id: ID! #isUnique
createdAt: DateTime!
updatedAt: DateTime!
email: String! #isUnique
password: String!
role: UserRole!
}
enum UserRole {
EDITOR,
MODERATOR,
ADMIN
}
I'm already receiving the role in the query and saving it in local storage, but anyone would be able to change it affecting the frontend UI (if we add permissions, we shouldn't worry in the server side). What's the best/secure way to manage it?

Are you using the Graphcool framework?
If you need to setup permissions in the graphcool.yml. I would include the following:
graphcool.yml
- operation: User.create
authenticated: true
query: permissions/User.graphql:adminRole
- operation: User.read
authenticated: true
query: permissions/User.graphql:adminRole
- operation: User.update
authenticated: true
query: permissions/User.graphql:adminRole
- operation: User.delete
authenticated: true
query: permissions/User.graphql:adminRole
- operation: User.read
authenticated: true
query: permissions/User.graphql:user
fields:
- id
- name
- role
- createdAt
- updatedAt
- email
- company
- operation: User.update
authenticated: true
query: permissions/User.graphql:user
fields:
- name
- company
User.graphql
query user($node_id: ID, $user_id: ID!) {
SomeUserExists(filter: {AND: [{id: $user_id}, {id: $node_id}]})
}
query adminRole($user_id: ID!) {
SomeUserExists(filter: {id: $user_id, role: ADMIN})
}
This way the user can only update their name and company. Then the ADMIN user can do read and edit everyone. Only ADMIN users can create or update new users.
Then you're probably asking how do you create new users?
I would use the FaaS code from Graphcool templates for email-password authentication found here:
https://github.com/graphcool/templates/tree/master/auth/email-password
The signup.ts file should you how a new user can signup and then the admin creates a new user for you. Inside the signup function you can default the UserRole to what ever you want.
https://github.com/graphcool/templates/blob/master/auth/email-password/src/signup.ts

Related

How to get authenticated user info with express based on JWT token

Im new to express, before using express I spent a lot of time with laravel and PHP.
So this is my problems, I have a schema database like this :
Users table :
created_by
updated_by
I want auto fill it with authenticated user id, with laravel I can write something like this
$new_user->request('created_by') = \Auth::user()->id; \\ this code will show or get the information of user who already authenticated
this is the result that I want :
updated_by = 1,
created_by = 1
and how can I do that in express, how to get the authenticated user info???
this is my syntax :
User.update(
{
username: req.body.username,
name: req.body.name,
email: req.body.email,
status: req.body.status,
phone: req.body.phone,
keterangan: req.body.keterangan,
role: req.body.role,
password: bcrypt.hashSync(req.body.password, 8),
created_by : // what should i write ?,
updated_by : // what should i write ?,
},
{
where: { id: id },
}
)
thanks for reading this, and sorry for my bad english.
Solved by my friend help in front end code.

How do i make specific users for only them to have access to their own specific data in mongodb and nodejs

I am working on a blog project. I am done with the functionality to create,edit and delete posts. I have also setup and login and signup with passport authentication and can already restrict pages to only logged in users. I want to also restrict editing and deleting of posts to only the users who created the post. I just can't seem to figure out how the link the two collections(one being the users collection and the other being the posts collection).
Below are the schemas for the two collections
posts schema
const articleSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
markdown: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now
},
slug: {
type: String,
required: true,
unique: true
},
sanitizedHTML: {
type: String,
required: true
}
})
users schema
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
In the articleSchema you need a field createdBy which will be linked with the id in userSchema. So, when the user is logged in you will get the user's id. Through which you can check if the post is created by that particular user. This is the best approach for your case right now.
If you want to have more extensive roles. For e.g. editors who can edit any articles. There are two ways to do it:
If you need multiple roles and their permissions are configurable
You need to create roleSchema which will have roleName, permissions etc. And in userSchema will be a field called role which corresponds to role_id for each user. This will allow you to change permissions and create new roles easily in future through UI.
If you just have few roles and confident that it won't change often
You can just define for yourself what these roles are: for e.g 1 -> Editor, 2 -> Subscriber, 3 -> Admin etc. And add a role field in userSchema to put the relevant role. This will allow you to have fixed permission for each role. Now when you are doing anything with article's you can get the role and filter accordingly.

Modify user signup behaviour in meteor accounts

I am following the "To-do list" tutorial for meteor and trying to make a few changes to it. I am trying to add a few fields by default to a collection called records(same as the collection tasks until now) when she signs up.
I came across this and wrote the following piece of code in startup/accounts-config.js
import { Accounts } from 'meteor/accounts-base';
import { Meteor } from 'meteor/meteor';
import { Rec } from '../api/records.js';
Accounts.ui.config({
passwordSignupFields: 'USERNAME_ONLY',
});
Accounts.onCreateUser(function(options, user) {
Rec.insert({
"text",
createdAt: new Date(),
owner: this.userId,
username: Meteor.users.findOne(this.userId).username,
});
return user;
});
But my application wouldn't compile and throw this error
imports/startup/accounts-config.js:12:12: Unexpected token (12:12)
Could someone please help me with this? I am new to front end development.
"text" is sitting on it's own without a value, you probably mean this:
text: "something goes here...",
Its probably because you have this.userId. You should use user._id there which is the created user object and user.username for the username.
Rec.insert({
"text",
createdAt: new Date(),
owner: user._id,
username: user.username,
});
As Mikkel said,
There should always be a field and value pair in a query ,
You are passing only value here , This should be like
Accounts.onCreateUser(function(options, user) {
Rec.insert({
field:"text",
createdAt: new Date(),
owner: this.userId,
username: Meteor.users.findOne(this.userId).username,
});

Express returning "User is not authorized" when modifying object from another user

I have a Classroom model that looks like this:
/**
* Classroom Schema
*/
var ClassroomSchema = new Schema({
created: {
type: Date,
default: Date.now
},
participants: [{
type: Schema.ObjectId,
ref: 'User'
}],
lesson: {
type: Schema.ObjectId,
ref: 'Lesson',
required: 'Define a lesson for this classroom',
},
user: {
type: Schema.ObjectId,
ref: 'User'
},
currentTaskIndex: {
type: Number,
default: 0
},
});
As you can see, the model keeps a reference to the user that have created the Classroom (User) and it also has many participants (more Users).
I'm trying to add the functionality to allow other Users (not the creator of the Classroom) to join the Classroom by sending a PUT request to the classroom API with a new User in the participants field. However, since the User sending the request is not the one who created the object, Express is returning a 403 (Forbidden):
exports.hasAuthorization = function(req, res, next) {
if (req.classroom.user.id !== req.user.id) {
return res.status(403).send('User is not authorized');
}
next();
};
What's the best approach/pattern to solve this allowing Users to join Classrooms created by another User but not to do other actions like deleting the object. Other fields might be updated by another participants, like the currentTaskIndex.
Thanks for your help!
You could add a 'master' or 'admin' field to your classroom, and store the Creator's userId in it.
Then you can allow the delete/modify, etc actions only for the user who is master of this particular classroom, while letting everyone in.

Access user email address in Meteor JS app

I am building an app using Meteor and need to access the stored email address of a logged-in user.
I am currently using:
var userObj = Meteor.user();
console.log(userObj);
to access the user. However, I am only able to access the id. The email address is stored in a nested object that looks like this:
[Object {address="address#gmail.com", verified=false}]
I have tried various ways to traverse the JSON object but can't figure out how to access the value I need.
Meteor.user().emails[0].address works for me.
Here's what the doc says:
By default the server publishes username, emails, and profile. See
Meteor.users for more on the fields used in user documents.
Example user document:
{
_id: "bbca5d6a-2156-41c4-89da-0329e8c99a4f", // Meteor.userId()
username: "cool_kid_13", // unique name
emails: [
// each email address can only belong to one user.
{ address: "cool#example.com", verified: true },
{ address: "another#different.com", verified: false }
],
createdAt: 1349761684042,
profile: {
// The profile is writable by the user by default.
name: "Joe Schmoe"
},
services: {
facebook: {
id: "709050", // facebook id
accessToken: "AAACCgdX7G2...AbV9AZDZD"
},
resume: {
loginTokens: [
{ token: "97e8c205-c7e4-47c9-9bea-8e2ccc0694cd",
when: 1349761684048 }
]
}
}
}
You don't specify how you are authenticating users. For example, if you were using Google authentication only, the email address would be found only in
Meteor.user().services.google.email
So, it depends.
Try this:
Meteor.user().emails[0].address
Regards,

Categories

Resources