Graphql-shield: Upload Scalar with Apollo 2 midleware

Created on 2 Apr 2019  路  23Comments  路  Source: maticzav/graphql-shield

I am trying to use graphql-shield in my apollo-server2 . Which is built on top of express.
I was using makeExecutableSchema to apply applyMiddleware as suggested many places like : [https://gist.github.com/donedgardo/ed2d36f6e650991543e5a55c77cddc0d]
But getting error :' "Upload". Did you mean "Float"?'
This error is coming because I have 'Upload' scalar in my schema. And few post has suggested makeExecutableSchema and Upload scalar don't work together. :(

Do you have any other way to apply Middleware or graphql-shield in apollo-server2

Most helpful comment

The problem lies in your permissions.
You cant do not(true). The logical rules and and or only work with other rules. So you need to use not(allow) or deny. Those are default rules which can be imported from graphql-shield.

All 23 comments

Hey @Meghajnct :wave:,

Thank you for opening an issue. We will get back to you as soon as we can. Also, check out our Open Collective and consider backing us.

https://opencollective.com/graphql-shield

PS.: We offer priority support for all backers. Don't forget to add priority label when you start backing us :smile:

hey @Meghajnct 馃憢,
Thanks for opening the issue. Could you also share the error log you are getting, schema and the server initiator function? This way I can help you better.

PS.: a reproduction repo would be 馃挴馃挴

imports ...

const app = express()

const schema = applyMiddleware(
makeExecutableSchema({
typeDefs:gqlOptions.typeDefs,
resolvers: gqlOptions.resolvers
}),
permissions
);
const server = new ApolloServer({
typeDefs: gqlOptions.typeDefs,
resolvers: gqlOptions.resolvers,
schema,
context: async ({ req }) => {
....
},
formatError: (error, req) => {
...
},
persistedQueries: {
...
)
}
})

server.applyMiddleware({
app: app
})

app.listen({ port: PORT }, () =>
log.info(
Server ready at http://localhost:${PORT}
}
)
)
`

And Error I am getting :

../node_modules/graphql/validation/validate.js:89
throw new Error(errors.map(function (error) {
^

Error: Unknown type "Upload". Did you mean "Float"?

Unknown type "Upload". Did you mean "Float"?

Unknown type "Upload". Did you mean "Float"?

Unknown type "Upload". Did you mean "Float"?

Unknown type "Upload". Did you mean "Float"?
at assertValidSDL (/Users/meghagupta/dev/code/../node_modules/graphql/validation/validate.js:89:11)
at Object.buildASTSchema (/Users/meghagupta/dev/code/../node_modules/graphql/utilities/buildASTSchema.js:78:34)
at Object.buildSchemaFromTypeDefinitions (/Users/meghagupta/dev/code/.../node_modules/graphql-tools/src/generate/buildSchemaFromTypeDefinitions.ts:43:32)
at makeExecutableSchema (/Users/meghagupta/dev/code/../node_modules/graphql-tools/src/makeExecutableSchema.ts:52:16)
at Object. (/Users/meghagupta/dev/code/../src/server.js:38:3)
at Module._compile (internal/modules/cjs/loader.js:689:30)
at Module._compile (/Users/meghagupta/dev/code/../node_modules/pirates/lib/index.js:99:24)
at Module._extensions..js (internal/modules/cjs/loader.js:700:10)
at Object.newLoader [as .js] (/Users/meghagupta/dev/code/../node_modules/pirates/lib/index.js:104:7)
at Module.load (internal/modules/cjs/loader.js:599:32)
at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
at Function.Module._load (internal/modules/cjs/loader.js:530:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
at startup (internal/bootstrap/node.js:282:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:743:3)

and the schema 馃檪

edit: schema is typeDefs, I believe the two are synonymous

Afaik you should either provide typeDefs and resolvers or an already compiled schema.
So I would remove typeDefs and resolvers from your apollo constructor.
However I don't think this solves the issue. Instead something in your gqlOptions.typeDefs seems to be wrong.

Yes, @P4sca1 you are correct. I have removed them still got same error.
I think issue is I am using upload scalar, which is not go well with makeExecutableSchema.

Could you post your typeDefs?

I have so many typeDefs. can't post all of then. but can post upload scalar one
its like :
extend type Mutation {
addUsers(file: Upload!): UserResponseType
}

And where is the Upload type defined?

its by apollo-graphql in built type I no need to define it like Int

I found something interesting in the docs:

Apollo Server 2.0 automatically adds the Upload scalar to the schema, when you are not setting the schema manually.

So because you are setting the schema manually, apollo server does not automatically add the Upload scalar.

Try to add scalar Upload to your typeDefs manually as explained here: https://github.com/apollographql/apollo-server/issues/1317#issuecomment-403648624

It does I am able to upload files

They have fixed that issue.

sry by mistake I click on close issue

How I can open it again ? :(

They have fixed that issue.

The error is not thrown by apollo-server but in the makeExecutableSchema call before.
This function has no clue about apollo-server adding the type later on so you can鈥檛 rely on it. You need to add the type manually to your typedefs.

This issue is fixed. thanks a lot 馃憤

I am having the same error, I tried many ways, one of which is asked on https://spectrum.chat/graphql/general/best-strategies-to-implement-access-control-in-graphql~f497245c-ca95-471c-9263-209a584d30ff, For the sake of simplicity I am just writing here for 1 api in query. I tried another way, that is :-
`let userPermissions = [];

const fetchPermissions = async token => {
const user = await sequelize.models.User.findOne({
where: { id: jwt.verify(token, process.env.JWT_SECRET).id }
});
const role = await sequelize.models.Role.findOne({
where: { id: user.role_id }
});
const permissions = await role.getPermissions();
userPermissions = permissions;
console.log("user", user, role, permissions, isAdmin, isRoleActionTrue);
};

const isAdmin = rule()(async (parent, args, ctx, info) => {
return true;
});

const isNotAdmin = rule()(async (parent, args, ctx, info) => {
return false;
});

const isRoleActionTrue = rule()(async (parent, args, ctx, info) => {
let returnValue = false;
console.log("test", parent, args, ctx, info);
userPermissions.forEach(({ name, isAction }) => {
if (name === "ROLE" && isAction === true) {
returnValue = true;
}
});
return returnValue;
});

const resolvers = {
Query: {
getRole
}
};

const permissions = shield({
Query: {
getRole: not(true)
}
});

const schema = applyMiddleware(
makeExecutableSchema({
typeDefs,
resolvers
}),
permisions
);

export default {
typeDefs,
resolvers,
schema,
context: ({ req }) => {
console.log("here in context", shield);
const token = req.headers.token || "";
fetchPermissions(token);
return {
token,
jwtEncode,
jwtDecode,
sequelize,
passwordHash,
comparePassword
};
}
};
the typeDef is :-
type Role {
id: Int
name: String
status: Boolean
permissions: [Permission]
}

type Query {
getRole: [Role]
}`

error code is something like :-
Error: Unknown type "Upload". Did you mean "Float"? at assertValidSDL (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/graphql/validation/validate.js:89:11) at Object.buildASTSchema (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/graphql/utilities/buildASTSchema.js:76:34) at Object.buildSchemaFromTypeDefinitions (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/graphql-tools/src/generate/buildSchemaFromTypeDefinitions.ts:43:32) at makeExecutableSchema (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/graphql-tools/src/makeExecutableSchema.ts:52:16) at Object.<anonymous> (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/graphql/index.js:180:3) at Module._compile (module.js:652:30) at loader (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/babel-register/lib/node.js:144:5) at Object.require.extensions.(anonymous function) [as .js] (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/babel-register/lib/node.js:154:7) at Module.load (module.js:565:32) at tryModuleLoad (module.js:505:12) at Function.Module._load (module.js:497:3) at Module.require (module.js:596:17) at require (internal/module.js:11:18) at Object.<anonymous> (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/server.js:3:1) at Module._compile (module.js:652:30) at loader (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/babel-register/lib/node.js:144:5) at Object.require.extensions.(anonymous function) [as .js] (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/babel-register/lib/node.js:154:7) at Module.load (module.js:565:32) at tryModuleLoad (module.js:505:12) at Function.Module._load (module.js:497:3) at Module.require (module.js:596:17) at require (internal/module.js:11:18) at Object.<anonymous> (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/index.js:14:1) at Module._compile (module.js:649:14) at Object.Module._extensions..js (module.js:663:10) at Module.load (module.js:565:32) at tryModuleLoad (module.js:505:12) at Function.Module._load (module.js:497:3) at Function.Module.runMain (module.js:693:10) at startup (bootstrap_node.js:188:16) at bootstrap_node.js:609:3

Maybe we should add this to the docs as it seems to be a common issue? @maticzav

#324 (comment)

#324 (comment)

Basically add scalar Upload to your typeDefs.

@P4sca1 thanks for the quick reply, I didnt actually knew that my colleague has this upload in api. I did added that, not getting that erro anymore, but I am getting a new error in rule , without even passing anything into it :-
TypeError: rule.extractFragment is not a function at fragments.rules.reduce (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/graphql-shield/src/rules.ts:247:16) at Array.reduce (<anonymous>) at RuleNot.extractFragments (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/graphql-shield/src/rules.ts:242:34) at generateFieldMiddlewareFromRule (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/graphql-shield/src/generator.ts:86:23) at Object.keys.reduce (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/graphql-shield/src/generator.ts:145:18) at Array.reduce (<anonymous>) at applyRuleToType (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/graphql-shield/src/generator.ts:142:46) at Object.keys.filter.reduce (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/graphql-shield/src/generator.ts:249:25) at Array.reduce (<anonymous>) at generateMiddlewareFromSchemaAndRuleTree (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/graphql-shield/src/generator.ts:243:8) at MiddlewareGenerator.generator (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/graphql-shield/src/generator.ts:277:24) at MiddlewareGenerator.generate (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/graphql-middleware/src/generator.ts:19:17) at /Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/graphql-middleware/src/middleware.ts:72:25 at Array.map (<anonymous>) at applyMiddlewareWithOptions (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/graphql-middleware/src/middleware.ts:70:45) at applyMiddleware (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/graphql-middleware/src/middleware.ts:129:36) at Object.<anonymous> (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/graphql/index.js:179:16) at Module._compile (module.js:652:30) at loader (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/babel-register/lib/node.js:144:5) at Object.require.extensions.(anonymous function) [as .js] (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/babel-register/lib/node.js:154:7) at Module.load (module.js:565:32) at tryModuleLoad (module.js:505:12) at Function.Module._load (module.js:497:3) at Module.require (module.js:596:17) at require (internal/module.js:11:18) at Object.<anonymous> (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/server.js:3:1) at Module._compile (module.js:652:30) at loader (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/babel-register/lib/node.js:144:5) at Object.require.extensions.(anonymous function) [as .js] (/Users/shreyan.mehta/work/buyer-persona-Backend/buyer-persona-backend/node_modules/babel-register/lib/node.js:154:7) at Module.load (module.js:565:32) at tryModuleLoad (module.js:505:12) at Function.Module._load (module.js:497:3) at Module.require (module.js:596:17) at require (internal/module.js:11:18)

The problem lies in your permissions.
You cant do not(true). The logical rules and and or only work with other rules. So you need to use not(allow) or deny. Those are default rules which can be imported from graphql-shield.

Was this page helpful?
0 / 5 - 0 ratings