graphql-compose / graphql-compose/graphql-compose-mongoose
Whitelist fields in queries
- 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.