Skip to content

Instantly share code, notes, and snippets.

@ZempTime
Created November 19, 2019 23:07
Show Gist options
  • Save ZempTime/87bc1bae6e8599d523b1f603c4ec90c5 to your computer and use it in GitHub Desktop.
Save ZempTime/87bc1bae6e8599d523b1f603c4ec90c5 to your computer and use it in GitHub Desktop.
Authz Schema Directives
import { SchemaDirectiveVisitor } from "apollo-server-koa";
import { GraphQLField, defaultFieldResolver } from "graphql";
class IsAuthenticatedDirective extends SchemaDirectiveVisitor {
visitFieldDefinition(field: GraphQLField<any, any>) {
const { resolve = defaultFieldResolver } = field;
field.resolve = async function(...args) {
const ctx = args[2];
if (!ctx.state.user.id) {
throw new Error("You must be signed in to do this.");
}
return resolve.apply(this, args);
};
}
}
class HasOperationsDirective extends SchemaDirectiveVisitor {
visitFieldDefinition(field: GraphQLField<any, any>) {
const { resolve = defaultFieldResolver } = field;
const { requires } = this.args;
field.resolve = async function(...args) {
const ctx = args[2];
const actualOperations = ctx.state.user.permissions || [];
const requiredOperations = requires;
const hasPermission = requiredOperations.some((operation: any) => {
return actualOperations.includes(operation);
});
if (!hasPermission) {
throw new Error(
`You don't have permission to do this. Yours: ${actualOperations}. Required: ${requiredOperations}`
);
}
return resolve.apply(this, args);
};
}
}
class IsUnauthenticatedDirective extends SchemaDirectiveVisitor {
visitFieldDefinition(field: GraphQLField<any, any>) {
const { resolve = defaultFieldResolver } = field;
field.resolve = async function(...args) {
const ctx = args[2];
if (ctx.state.user.id) {
throw new Error("You must can't be signed in to do this.");
}
return resolve.apply(this, args);
};
}
}
export {
IsAuthenticatedDirective,
HasPermissionDirective,
IsUnauthenticatedDirective
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment