const { GraphQLModule } = require("@graphql-modules/core"); const gql = require("graphql-tag"); const bcrypt = require("bcryptjs"); const jwt = require("jsonwebtoken"); const { prisma } = require('../../generated/prisma-client/index'); const getUser = token => { try { if(token) { return jwt.verify(token, process.env.JWT_SECRET); } return null; } catch(err) { return null; } } module.exports = new GraphQLModule({ name: "AUTHENTICATION_MODULE", typeDefs: gql` type User { id: ID! username: String! } type Query { currentUser: User! } type Mutation { register(username: String!, password: String!): User! login(username: String!, password: String!): LoginResponse! } type LoginResponse { token: String user: User } `, resolvers: { Query: { currentUser: (parent, args, {user, prisma}) => { // Check the authentication if(!user) { throw new Error("Not authenticated"); } return prisma.user({id: user.id}); } }, Mutation: { register: async(parent, {username, password}, ctx, info) => { if(process.env.ENABLE_REGISTRATION === "true") { const hashedPassword = await bcrypt.hash(password, 10); const user = await ctx.prisma.createUser({ username, password: hashedPassword }); return user; } throw new Error("Registration disabled"); }, login: async(parent, {username, password}, ctx, info) => { console.log(ctx); const user = await ctx.prisma.user({username}); if(!user) { throw new Error("Invalid login"); } const passwordMatch = await bcrypt.compare(password, user.password); if(!passwordMatch) { throw new Error("Invalid login"); } const token = jwt.sign ( { id: user.id, username: user.email }, process.env.JWT_SECRET, { expiresIn: "30d", // So that the token expires in 30 days } ) return { token, user } } } }, context: ({ req }) => { const tokenWithBearer = req.headers.authorization || ''; const token = tokenWithBearer.split(' ')[1]; const user = getUser(token); return { user, prisma } } })