graphql-mesh
graphql-mesh copied to clipboard
Support custom jwt claims in postgraphile handler.
Is your feature request related to a problem? Please describe.
I was able to get the postgraphile handler working with our CRM without any issues. But I hit a wall when it came to the RLS (row level security) and JWT claims. There does not seem to be any way to change or add claims to postgraphile (even with the postgraphile options when it's run in schema mode).
This is a blocker for us to use an unmodified version of graphql-mesh
Describe the solution you'd like
graphql-mesh should add an optional function or static object to the postgraphile handler options called pgSettings
which takes meshContext
as the parameter.
I was able to get postgraphile in graphql-mesh working for us, by editing this file: node_modules/@graphql-mesh/postgraphile/index.js
These are the lines I changed to get it to work:
// This function just parses the jwt token from the Authorization header.
const parseJwt = (token) => {
var base64Url = token.split('.')[1];
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
var jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
return JSON.parse(jsonPayload);
};
// π This function creates a valid pgSettings object with our custom jwt claims
// (This is the function i would like to pass in .meshrc.yml) to support custom jwt claims
const getPgSettings = (context) => {
try {
const jwtToken = context.headers.authorization.split(' ')[1]
const decodedToken = parseJwt(jwtToken)
return {
'role': `${decodedToken.x_role}`,
'request.jwt.claim.allowed_uids': `${decodedToken.allowed_uids}`,
'request.jwt.claim.iss': `${decodedToken.iss}`,
'request.jwt.claim.sub': `${decodedToken.sub}`
}
} catch(err) {
return {
'role': 'api_user',
}
}
}
return {
schema,
executor: ({ document, variables, context: meshContext, rootValue, operationName, extensions }) => postgraphile.withPostGraphileContext({
pgPool,
pgSettings: getPgSettings(meshContext), // π I added this line to pass custom pgSettings to the postgraphile context
queryDocumentAst: document,
operationName,
variables,
}, pgContext => jitExecutor({
document,
variables,
context: {
...meshContext,
...pgContext,
},
rootValue,
operationName,
extensions,
})),
};
Describe alternatives you've considered
When using postgraphile builder for schema usage there it does NOT allow pgSettings
to be passed to builder options which is the only one that's possible to edit from graphql-mesh
settings right now.
https://www.graphile.org/postgraphile/usage-schema/
Additional context
To get this working we either have to fork graphql-mesh
or write a hacky script that insets the function in in withPostGraphileContext
to add in pgSettings.
Please consider allowing users to add their own settings or overrides here.
An alternative to this would be support & docs to easily implement custom handlers, so I could just copy the postgraphile handler and add my own settings to it for less common settings like jwt claims.
I ended up solving this for myself temporarily by copying the postgraphile handler, and adding my own pgSettings and publishing it as a private npm package.
Not very clean and it already broke once due to other graphql mesh packages I had to rebase on.
But at least there's a workaround for now.