auth
auth copied to clipboard
Is there a way to make schema filtering work with external policy?
Hi i'm fairly new to Fastify and Mercurius, I'm trying to setup a graphql api project for 1 of my side project. I saw there's a documentation to filter schema for auth policy directive, n it works great, but for my use case i prefer to use the external auth policy, is there a way to make external policy work for schema filtering, as i might need to expose the graphql playground for potential authenticated users. Here's a minimal snippets of my setup:
const schema = await loadSchema('src/schemas/*.graphql', {
loaders: [new GraphQLFileLoader()],
});
const options: MercuriusAuthOptions<any, any, MercuriusContext, TPolicy> = {
mode: 'external',
authContext(ctx): TAuthContext {
const { device, location, role, staff, token, venue } = ctx;
return { device, location, role, staff, token, venue };
},
async applyPolicy(policy, _parent, _args, ctx, _info) {
const isRolesPolicySatisfied = policy.roles?.length
? !!(ctx.auth!.role && policy.roles.includes(ctx.auth!.role.type as USER_ROLE))
: true;
const isUserRequiredPolicySatisfied = policy.isUserRequired ? !!ctx.auth!.user : true;
const isVenueRequiredPolicySatisfied = policy.isVenueRequired ? !!ctx.auth!.venue : true;
const isRoleRequiredPolicySatisfied = policy.isRoleRequired ? !!ctx.auth!.role : true;
const isLocationRequiredPolicySatisfied = policy.isLocationRequired ? !!ctx.auth!.location : true;
const isDeviceRequiredPolicySatisfied = policy.isDeviceRequired ? !!ctx.auth!.device : true;
const areAllConditionsSatisfied =
isRolesPolicySatisfied &&
isUserRequiredPolicySatisfied &&
isVenueRequiredPolicySatisfied &&
isRoleRequiredPolicySatisfied &&
isLocationRequiredPolicySatisfied &&
isDeviceRequiredPolicySatisfied;
return areAllConditionsSatisfied;
},
policy: {
// TODO: Add more policies
Query: {
getCurrentMenu: {
isVenueRequired: true,
},
},
Mutation: {},
Subscription: {},
Location: {
current_orders: {
roles: AUTHENTICATED_ROLES,
},
venue: {
roles: AUTHENTICATED_ROLES,
},
},
Menu: {
posCategories: {
roles: AUTHENTICATED_ROLES,
},
},
Category: {
posItems: {
roles: AUTHENTICATED_ROLES,
},
},
Item: {
posOptions: {
roles: AUTHENTICATED_ROLES,
},
},
},
};
type TPolicy = {
isRoleRequired?: boolean;
isUserRequired?: boolean;
isVenueRequired?: boolean;
isLocationRequired?: boolean;
isDeviceRequired?: boolean;
roles?: USER_ROLE[];
};
await fastify.register(mercurius, {
schema,
resolvers,
loaders,
ide: true,
graphiql: true,
path: '/graphql',
allowBatchedQueries: true,
queryDepth: 10,
jit: 1,
context: buildContext,
subscription: {
emitter,
context: buildSubscriptionContext,
},
validationRules: isRelease ? [NoSchemaIntrospectionCustomRule] : [],
});
await fastify.register(mercuriusAuth, options);