graphql-compose / graphql-compose/graphql-compose-mongoose

Whitelist fields in queries

Open
#334 1 comment 1 reaction 0 assignees View on GitHub
Dominant language
TypeScript
Stars
706
Forks
98
PR merge metrics
No merged PRs in 30d

Description

I have a user model like this:
```js
//shortened schema
const UserSchema = new mongoose.Schema({
name: {
type: String,
},
email: {
type: String,
},
password: { //hashed
type: String,
},
role: {
type: String,
},
favouriteColor: {
type: String,
}
}, {
timestamps: true,
});

export const User = mongoose.model('User', UserSchema)
```

and I want to have different "views" for different permission roles:
An admin has full access.
A moderator can view all fields except `password` and `email`
A basic user can only see the `name` and `favouriteColor`.

The way I am currently doing it (which works) is to create a different TC for every permission role:
```js
export const UserTCAdmin = composeMongoose(User, {
name: "UserAdmin",
description: "Full User Model. Exposed only for Admins."
});

export const UserTCMod = composeMongoose(User, {
name: "UserMod",
description: "Hide login information",
removeFields: [
"email",
"password"
]
});

export const UserTCPublic = composeMongoose(User, {
name: "UserPublic",
description: "Contains all public fields of users. Use this for filtering as well",
onlyFields: [
"name",
"favouriteColor"
]
})
```
but I have the feeling this is a suboptimal solution. If I have a custom resolver that I want to reuse in different `UserTC`s I have to copy-paste the code.

I think it could be a good solution to whitelist fields resolver-based in the options. An example of how this could look like:
```js
export const UserTC = composeMongoose(User, {
name: "User",
description: "One UserTC for all"
});

//resolvers

//example custom resolver
UserTCAdmin.addResolver({
kind: "query",
name: "random",
description: "Get a random user",
...
})

const publicFields = {
onlyFields: [
"name",
"favouriteColor"
]
}

const modFields = {
removeFields: [
"email",
"password"
]
}

export const UserQuery = {
...requireAuthentication({
userOnePublic: UserTC.mongooseResolvers.findOne({fields: publicFields}),
usernameRandom: UserTC.getResolver("superSpecial", {fields: onlyFields: "name"} //allow users to only get the name
}),
...requireAuthorization({
userOneMod: UserTC.mongooseResolvers.findOne({fields: modFields}),
},
"mod"
),
...requireAuthorization({
userOneAdmin: UserTC.mongooseResolvers.findOne(),
userRandom: UserTC.getResolver("superSpecial",) //allow admins to get the full schema
},
"admin"
),
};
```

What do you think?

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.