diff --git a/api/package-lock.json b/api/package-lock.json index 2c9d2943..2f356bbf 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -11,8 +11,10 @@ "dependencies": { "@apollo/server": "^4.5.0", "@prisma/client": "^4.11.0", + "@types/cookie-parser": "^1.4.3", "bcrypt": "^5.1.0", "body-parser": "^1.20.2", + "cookie-parser": "^1.4.6", "cors": "^2.8.5", "dotenv": "^16.0.3", "express": "^4.18.2", @@ -1542,6 +1544,14 @@ "@types/node": "*" } }, + "node_modules/@types/cookie-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.3.tgz", + "integrity": "sha512-CqSKwFwefj4PzZ5n/iwad/bow2hTCh0FlNAeWLtQM3JA/NX/iYagIpWG2cf1bQKQ2c9gU2log5VUCrn7LDOs0w==", + "dependencies": { + "@types/express": "*" + } + }, "node_modules/@types/cors": { "version": "2.8.13", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", @@ -2552,6 +2562,26 @@ "node": ">= 0.6" } }, + "node_modules/cookie-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", + "dependencies": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/cookie-parser/node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", @@ -7863,6 +7893,14 @@ "@types/node": "*" } }, + "@types/cookie-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.3.tgz", + "integrity": "sha512-CqSKwFwefj4PzZ5n/iwad/bow2hTCh0FlNAeWLtQM3JA/NX/iYagIpWG2cf1bQKQ2c9gU2log5VUCrn7LDOs0w==", + "requires": { + "@types/express": "*" + } + }, "@types/cors": { "version": "2.8.13", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", @@ -8581,6 +8619,22 @@ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" }, + "cookie-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", + "requires": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6" + }, + "dependencies": { + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + } + } + }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", diff --git a/api/package.json b/api/package.json index 3037d3ba..aba276e9 100644 --- a/api/package.json +++ b/api/package.json @@ -17,8 +17,10 @@ "dependencies": { "@apollo/server": "^4.5.0", "@prisma/client": "^4.11.0", + "@types/cookie-parser": "^1.4.3", "bcrypt": "^5.1.0", "body-parser": "^1.20.2", + "cookie-parser": "^1.4.6", "cors": "^2.8.5", "dotenv": "^16.0.3", "express": "^4.18.2", diff --git a/api/src/app.ts b/api/src/app.ts index c41eb023..ad45bc3b 100644 --- a/api/src/app.ts +++ b/api/src/app.ts @@ -35,6 +35,7 @@ export const createApp = (): Express => { endpoint: '/api/graphql', settings: { 'editor.theme': 'light', + 'request.credentials': 'include', }, }), ); diff --git a/api/src/graphql/context.ts b/api/src/graphql/context.ts index 8205b51d..81f03ab8 100644 --- a/api/src/graphql/context.ts +++ b/api/src/graphql/context.ts @@ -27,12 +27,13 @@ export function createContext(params: CreateContextParams): Context { logger.trace('Creating context with params: %o', params); const { req } = params; const authorizationHeader = req.get('Authorization'); + const cookieAuthHeader = req.cookies['gql:default']; const token = authorizationHeader?.replace('Bearer ', ''); return { request: params, prisma, apolloLogger, - getSession: async () => prisma.session.getSessionByToken(token), + getSession: async () => prisma.session.getSessionByToken(token || cookieAuthHeader), }; } diff --git a/api/src/graphql/server.ts b/api/src/graphql/server.ts index 21fab886..5cb99908 100644 --- a/api/src/graphql/server.ts +++ b/api/src/graphql/server.ts @@ -5,6 +5,7 @@ import { ApolloServerPlugin, ApolloServer } from '@apollo/server'; import { expressMiddleware } from '@apollo/server/express4'; import { ApolloServerPluginLandingPageDisabled } from '@apollo/server/plugin/disabled'; import bodyParser from 'body-parser'; +import cookierParser from 'cookie-parser'; import cors from 'cors'; import { PORT } from '../env'; import { schemaWithMiddleware } from './schema'; @@ -41,9 +42,15 @@ export const startServer = async ( const apollo = createApolloServer(); await apollo.start(); - app.use('/graphql', cors(), bodyParser.json(), expressMiddleware(apollo, { - context: async (params) => (createContext(params)), - })); + app.use( + '/graphql', + cors(), + cookierParser(undefined, { decode: (value: string) => value }), + bodyParser.json(), + expressMiddleware(apollo, { + context: async (params) => (createContext(params)), + }), + ); return httpServer.listen({ port: PORT }, () => { logger.info(`Running on ${PORT}`);