Skip to content

Instantly share code, notes, and snippets.

@max10rogerio
Created November 5, 2019 13:20
Show Gist options
  • Save max10rogerio/69811cf9e6411e31f6332c20024de5e4 to your computer and use it in GitHub Desktop.
Save max10rogerio/69811cf9e6411e31f6332c20024de5e4 to your computer and use it in GitHub Desktop.
Problem with Context and directives (Auth)
/* eslint-disable no-underscore-dangle */
// This is a example of my|problem
import { SchemaDirectiveVisitor } from 'graphql-tools'
import { GraphQLField, defaultFieldResolver, GraphQLResolveInfo } from 'graphql'
export interface UserToken {
id: number
instituicao?: number
sessao?: string
}
// Please ignore types like PubSub, Tedis and Dataloader
export interface Context {
pubsub: PubSub
redis: Tedis
dataloader: Dataloader
user?: UserToken
token?: string
permissoes?: string[]
}
type CustomField = GraphQLField<any, Context> & { _permissao: string; _autenticado: boolean }
/**
* Diretiva de autenticação
*
* Executa determiando query ou mutation conforme a permissão do usuário
* Add on your querie/mutation @Auth
*/
export class Auth extends SchemaDirectiveVisitor {
visitFieldDefinition(field: CustomField): void {
this.ensureFieldWrapped(field)
field._permissao = this.args.permissao
}
ensureFieldWrapped(field: CustomField): void {
if (field._autenticado) {
return
}
field._autenticado = true
const { resolve = defaultFieldResolver } = field
field.resolve = async (
source: any,
args: { [key: string]: any },
context: Context,
info: GraphQLResolveInfo
): Promise<void> => {
const permissao = field._permissao
if (!context.user) {
throw new Error('Você deve estar autenticado')
}
// caso a query/mutation não necessite de uma permissão específica então libera o usuário
// ex: @Auth
if (!permissao) {
return resolve.apply(this, [source, args, context, info])
}
if (!context.permissoes) {
throw new Error('Permissões não encontradas')
}
if (!context.permissoes.includes(permissao)) {
throw new Error('Você não tem permissão para esta funcionalidade')
}
return resolve.apply(this, [source, args, context, info])
}
}
}
type Pessoa @Base {
nome: String!
email: String
dataNascimento: Date
rg: String
cpf: String
instituicao: Instituicao! @Get
sessoes: [Sessao!]! @Get
}
type Query {
usuarioLogado: Pessoa! @Auth
}
import { QueryResolvers } from "../../../generated/graphql";
export const Query: QueryResolvers = {
usuarioLogado: (source, args, { user }) => {
// see in Auth.ts the validation on line 55
// if i try acess user.id, intellisense show me an error, then i need create a guard validation
if (!user) {
throw new Error('User not found')
}
user.id // works fine
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment