Reputation: 1947
I'm trying to write some authentication logic based on apollo server documentation but it doesn't seem to be firing. Here's my code:
// schemas/auth-schema.js
import gql from 'graphql-tag';
export const typeDefs = gql`
directive @auth(requires: Role = ADMIN) on OBJECT | FIELD_DEFINITION
`;
// directives/auth-directive.js
import { SchemaDirectiveVisitor } from 'apollo-server';
export default class AuthDirective extends SchemaDirectiveVisitor {
visitObject(type) {
console.log('HERE');
}
visitSchema() {
console.log('HERE');
}
visitFieldDefinition() {
console.log('HERE');
}
}
// schemas/post-schema.js
import gql from 'graphql-tag';
import { Post } from '../models';
export const typeDefs = gql`
type Post @auth(requires: ADMIN) {
body: String!
description: String!
id: ID!
image: String!
publishedAt: DateTime
readingTime: Int!
slug: String!
title: String!
}
input PostInput {
body: String!
description: String!
image: String!
publishedAt: DateTime
title: String!
}
extend type Query {
posts: [Post!]! @auth(requires: ADMIN)
}
extend type Mutation {
addPost(input: PostInput!): Post! @auth(requires: ADMIN)
}
`;
export const resolvers = {
Query: {
posts: () => Post.find({}),
},
Mutation: {
addPost: (_, { input }) => Post.create(input),
},
};
// index.js
import { ApolloServer } from 'apollo-server';
import mongoose from 'mongoose';
import AuthDirective from './directives/auth-directive';
import * as config from './config';
mongoose.set('useNewUrlParser', true);
mongoose.set('useCreateIndex', true);
mongoose.set('debug', config.env !== 'production');
const server = new ApolloServer({
modules: [
require('./schema/auth-schema'),
require('./schema/date-schema'),
require('./schema/post-schema'),
require('./schema/role-schema'),
require('./schema/user-schema'),
],
schemaDirectives: {
auth: AuthDirective,
},
});
async function boot() {
await mongoose.connect(config.mongo.url);
await server.listen(config.http.port);
console.log(`server listening on port ${config.http.port}`);
}
async function shutdown() {
await server.stop();
await mongoose.disconnect();
console.log(`server shutted down`);
process.exit(0);
}
process.on('SIGINT', shutdown);
process.on('SIGTERM', shutdown);
boot();
So, I've tried putting the @auth directive in every possible case and nothing is being fired.
type Post @auth(requires: ADMIN) { ... } // not firing
type Query {
posts: [Post!]! @auth(requires: ADMIN) // not firing
}
This is what AdminDirective is evaluated from the console:
What am I doing wrong?
Upvotes: 2
Views: 1297
Reputation: 84657
So, looking at the code for apollo-server
, when you use the modules
option, internally your schema is built using buildServiceDefinition
. While this function does merge directives from all the modules, it's not passed your schemaDirectives
object and does not apply it.
In other words, this looks like a bug with apollo-server
itself. You can file an issue, and in the meantime, just use the typeDefs
and resolvers
options, combining the necessary files yourself.
Upvotes: 2