Skip to content

Instantly share code, notes, and snippets.

@ZempTime
Created January 25, 2020 17:03
Show Gist options
  • Save ZempTime/9baea5da47d68d4bfc5a9b92de0ee490 to your computer and use it in GitHub Desktop.
Save ZempTime/9baea5da47d68d4bfc5a9b92de0ee490 to your computer and use it in GitHub Desktop.
GraphQL Directives
// Example usage:
// type Query {
// organizations(
// where: OrganizationWhereInput
// first: Int
// skip: Int
// orderBy: OrganizationOrderByInput
// ): [Organization]! @hasPermission(requires: [OEM_ADMIN, ORG_ADMIN])
// organization(id: ID!): Organization
// associatedOrganization: Organization @isAuthenticated
// }
// type Organization {
// id: ID!
// name: String!
// phone: String
// signupNote: String
// createdAt: DateTime!
// updatedAt: DateTime!
// approvalStatus: ApprovalStatus!
// passcode: String
// files: [TinFile]! @hasPermission(requires: [OEM_ADMIN, ORG_ADMIN])
/
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 HasPermissionDirective 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 actualPermissions = ctx.state.user.permissions || [];
const requiredPermissions = requires;
const hasPermission = requiredPermissions.some((permission: any) => {
return actualPermissions.includes(permission);
});
if (!hasPermission) {
throw new Error(
`You don't have permission to do this. Yours: ${actualPermissions}. Required: ${requiredPermissions}`
);
}
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