From f2ec9834600ad48ecdc6f99212141ace739beb49 Mon Sep 17 00:00:00 2001 From: Brandon Villa Date: Fri, 29 Mar 2019 00:33:05 -0600 Subject: [PATCH 1/5] change type for Context --- src/utils.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index e7bb17c..aa15a65 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,9 +1,9 @@ import * as jwt from 'jsonwebtoken' import { Prisma } from './generated/prisma-client' +import { ContextParameters } from 'graphql-yoga/dist/types' -export interface Context { +export interface Context extends ContextParameters { prisma: Prisma - request: any } export function getUserId(ctx: Context) { From 4e4385b60c73cb047f5a897b79902f945e8c477c Mon Sep 17 00:00:00 2001 From: Brandon Villa Date: Sun, 31 Mar 2019 22:48:05 -0600 Subject: [PATCH 2/5] add cookie parser package --- package.json | 2 ++ yarn.lock | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/package.json b/package.json index 903b97c..defd378 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,13 @@ }, "dependencies": { "bcryptjs": "2.4.3", + "cookie-parser": "^1.4.4", "graphql-yoga": "1.17.4", "jsonwebtoken": "8.5.0" }, "devDependencies": { "@types/bcryptjs": "2.4.2", + "@types/cookie-parser": "^1.4.1", "@types/node": "10.12.27", "dotenv-cli": "1.4.0", "nodemon": "1.18.10", diff --git a/yarn.lock b/yarn.lock index 5fda140..f9af837 100644 --- a/yarn.lock +++ b/yarn.lock @@ -46,6 +46,13 @@ dependencies: "@types/node" "*" +"@types/cookie-parser@^1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@types/cookie-parser/-/cookie-parser-1.4.1.tgz#e88a39c41960f31549b4c52dd8620aa4a2feb4bb" + integrity sha512-iJY6B3ZGufLiDf2OCAgiAAQuj1sMKC/wz/7XCEjZ+/MDuultfFJuSwrBKcLSmJ5iYApLzCCYBYJZs0Ws8GPmwA== + dependencies: + "@types/express" "*" + "@types/cors@^2.8.4": version "2.8.4" resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.4.tgz#50991a759a29c0b89492751008c6af7a7c8267b0" @@ -829,6 +836,14 @@ content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" +cookie-parser@^1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.4.tgz#e6363de4ea98c3def9697b93421c09f30cf5d188" + integrity sha512-lo13tqF3JEtFO7FyA49CqbhaFkskRJ0u/UAiINgrIXeRCY41c88/zxtrECl8AKH3B0hj9q10+h3Kt8I7KlW4tw== + dependencies: + cookie "0.3.1" + cookie-signature "1.0.6" + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" From 06b0063f84a0e95c9a7082d0e476f235a642e9c8 Mon Sep 17 00:00:00 2001 From: Brandon Villa Date: Sun, 31 Mar 2019 22:48:56 -0600 Subject: [PATCH 3/5] use cookie parser & cors config --- src/index.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 6f78f71..0e51606 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,7 @@ -import { GraphQLServer } from 'graphql-yoga' +import { GraphQLServer, Options } from 'graphql-yoga' import { prisma } from './generated/prisma-client' import resolvers from './resolvers' +import * as cookieParser from 'cookie-parser' const server = new GraphQLServer({ typeDefs: './src/schema.graphql', @@ -11,7 +12,13 @@ const server = new GraphQLServer({ }), }) -const options = { +server.express.use(cookieParser()); + +const options: Options = { port: process.env.GRAPHQL_SERVER_PORT, + cors: { + credentials: true, + origin: process.env.CLIENT_HOST + } } server.start(options, ({ port }) => console.log(`Server is running on http://localhost:${port}`)) From b6791703101f0027061f23af1f3a2926466c7b52 Mon Sep 17 00:00:00 2001 From: Brandon Villa Date: Sun, 31 Mar 2019 22:49:34 -0600 Subject: [PATCH 4/5] add token as a cookie in response --- src/resolvers/Mutation/auth.ts | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/resolvers/Mutation/auth.ts b/src/resolvers/Mutation/auth.ts index 07f86f2..c46a802 100644 --- a/src/resolvers/Mutation/auth.ts +++ b/src/resolvers/Mutation/auth.ts @@ -1,14 +1,21 @@ import * as bcrypt from 'bcryptjs' import * as jwt from 'jsonwebtoken' import { Context } from '../../utils' +const ONE_YEAR = 1000 * 60 * 60 * 24 * 365 export const auth = { async signup(parent, args, ctx: Context) { const password = await bcrypt.hash(args.password, 10) const user = await ctx.prisma.createUser({ ...args, password }) + const token = jwt.sign({ userId: user.id }, process.env.APP_SECRET) + + ctx.response.cookie('token', token, { + httpOnly: true, + maxAge: ONE_YEAR, + }); return { - token: jwt.sign({ userId: user.id }, process.env.APP_SECRET), + token, user, } }, @@ -24,9 +31,21 @@ export const auth = { throw new Error('Invalid password') } + const token = jwt.sign({ userId: user.id }, process.env.APP_SECRET) + + ctx.response.cookie('token', token, { + httpOnly: true, + maxAge: ONE_YEAR, + }); + return { - token: jwt.sign({ userId: user.id }, process.env.APP_SECRET), + token, user, } }, + + async logout(parent, args, ctx: Context) { + ctx.response.clearCookie('token') + return { message: 'logout' } + } } From efe197c460ffcaadb3e8cb5125c35284ccedea83 Mon Sep 17 00:00:00 2001 From: Brandon Villa Date: Sun, 31 Mar 2019 22:49:55 -0600 Subject: [PATCH 5/5] add logout mutation --- src/schema.graphql | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/schema.graphql b/src/schema.graphql index 199f498..fe8afe8 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -1,3 +1,7 @@ +type SuccessMessage { + message: String +} + type Query { feed: [Post!]! drafts: [Post!]! @@ -8,6 +12,7 @@ type Query { type Mutation { signup(email: String!, password: String!, name: String!): AuthPayload! login(email: String!, password: String!): AuthPayload! + logout: SuccessMessage! createDraft(title: String!, content: String!): Post! publish(id: ID!): Post! deletePost(id: ID!): Post!