@pothos/plugin-scope-auth
Version:
A Pothos plugin for adding scope based authorization checks to your GraphQL Schema
64 lines (52 loc) • 2.34 kB
text/typescript
import { isThenable, type MaybePromise, type SchemaTypes } from '@pothos/core';
import type { GraphQLIsTypeOfFn, GraphQLResolveInfo } from 'graphql';
import { ForbiddenError } from './errors.js';
import type { PothosScopeAuthPlugin, ResolveStep, UnauthorizedForTypeErrorFn } from './index.js';
import RequestCache from './request-cache.js';
export function isTypeOfHelper<Types extends SchemaTypes>(
steps: ResolveStep<Types>[],
plugin: PothosScopeAuthPlugin<Types>,
isTypeOf: GraphQLIsTypeOfFn<unknown, Types['Context']> | undefined,
) {
const globalUnauthorizedError = plugin.builder.options.scopeAuth?.unauthorizedError;
const createError: UnauthorizedForTypeErrorFn<Types, object> = (parent, context, info, result) =>
globalUnauthorizedError
? globalUnauthorizedError(parent, context, info, result)
: result.message;
return (parent: unknown, context: Types['Context'], info: GraphQLResolveInfo) => {
const cache = RequestCache.fromContext(context, plugin.builder);
function runSteps(index: number): MaybePromise<boolean> {
for (let i = index; i < steps.length; i += 1) {
const { run, errorMessage } = steps[i];
const stepResult = run(cache, parent, {}, context, info, () => {});
if (isThenable(stepResult)) {
return stepResult.then((result) => {
if (result) {
const error = createError(parent as object, context, info, {
message:
typeof errorMessage === 'function'
? errorMessage(parent, {}, context, info)
: errorMessage,
failure: result,
});
throw typeof error === 'string' ? new ForbiddenError(error, result) : error;
}
return runSteps(i + 1);
});
}
if (stepResult) {
const error = createError(parent as object, context, info, {
message:
typeof errorMessage === 'function'
? errorMessage(parent, {}, context, info)
: errorMessage,
failure: stepResult,
});
throw typeof error === 'string' ? new ForbiddenError(error, stepResult) : error;
}
}
return isTypeOf ? isTypeOf(parent, context, info) : true;
}
return runSteps(0);
};
}