Frontend Serverless with React and GraphQL

Start at the beginning and work your way through this project. The code for each step as well as the finished project can be found in the Github repository.


42. Add Banned Mutation Check

Objective: Create a function that will block unauthorized mutation types from being executed in the GraphCMS server.

We need to write a function that will search the incoming graphQL query for any of the banned mutation types. These include deleteMany, updateMany, or publishMany*. An easy way to do this, is create a function that searches for a substring using regular expression matching. If it finds a match then it throws an error which immediately stops the proxy request before it can fire off its request to the GraphCMS backend.

pages/api/graphql.ts

import * as _ from 'lodash';
export const verifyNotABannedMutation = async (req, res) => {
const isBannedMutation = req.body.query.match(
/deleteMany|updateMany|publishMany/g,
);
if (!_.isNil(isBannedMutation)) {
throw new Error('Invalid Mutation Requested');
}
};

Now we can just call the verifyNotABannedMutation function from the graphql api endpoint:

pages/api/graphql.ts

import getConfig from 'next/config';
import { GraphQLClient } from 'graphql-request';
import { verifyNotABannedMutation } from '../../utils/verify';
const { serverRuntimeConfig } = getConfig();
const {
BRANCH,
GRAPHCMSURL,
GRAPHCMSPROJECTID,
GRAPHCMS_TOKEN,
} = serverRuntimeConfig.graphcms;
const graphqlEndpoint = `${GRAPHCMSURL}/${GRAPHCMSPROJECTID}/${BRANCH}`;
export const graphQLClient = new GraphQLClient(graphqlEndpoint, {
headers: {
authorization: `Bearer ${GRAPHCMS_TOKEN}`,
},
});
async function proxyGraphql(req, res) {
try {
await verifyNotABannedMutation(req, res);
const { variables, query } = req.body;
const data = await graphQLClient.rawRequest(query, variables);
res.json(data);
} catch (e) {
res.json({ data: {}, errors: [{ message: e.message }] });
}
}
export default proxyGraphql;