New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@envelop/generic-auth

Package Overview
Dependencies
Maintainers
1
Versions
1325
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@envelop/generic-auth - npm Package Compare versions

Comparing version 2.0.0-alpha-c8eef8e.0 to 2.0.0-alpha-f336686.0

utils.d.ts

46

index.d.ts
import { DefaultContext, Plugin } from '@envelop/core';
import { DirectiveNode, FieldNode, GraphQLError, GraphQLObjectType } from 'graphql';
import { DirectiveNode, GraphQLError, GraphQLResolveInfo } from 'graphql';
export * from './utils';
export declare class UnauthenticatedError extends GraphQLError {
}
export declare type ResolveUserFn<UserType, ContextType = DefaultContext> = (context: ContextType) => null | UserType | Promise<UserType | null>;
export declare type ValidateUserFnParams<UserType> = {
/** The user object. */
user: UserType;
/** The field node from the operation that is being validated. */
fieldNode: FieldNode;
/** The object type which has the field that is being validated. */
objectType: GraphQLObjectType;
/** The directive node used for the authentication (If using an SDL flow). */
fieldAuthDirectiveNode: DirectiveNode | undefined;
/** The extensions used for authentication (If using an extension based flow). */
fieldAuthExtension: unknown | undefined;
};
export declare type ValidateUserFn<UserType> = (params: ValidateUserFnParams<UserType>) => void | UnauthenticatedError;
export declare type ValidateUserFn<UserType, ContextType = DefaultContext> = (user: UserType, context: ContextType, resolverInfo?: {
root: unknown;
args: Record<string, unknown>;
context: ContextType;
info: GraphQLResolveInfo;
}, directiveNode?: DirectiveNode) => void | Promise<void>;
export declare const DIRECTIVE_SDL = "\n directive @auth on FIELD_DEFINITION\n";

@@ -30,2 +24,7 @@ export declare const SKIP_AUTH_DIRECTIVE_SDL = "\n directive @skipAuth on FIELD_DEFINITION\n";

/**
* Here you can implement any custom to check if the user is valid and have access to the server.
* This method is being triggered in different flows, besed on the mode you chose to implement.
*/
validateUser?: ValidateUserFn<UserType, ContextType>;
/**
* Overrides the default field name for injecting the user into the execution `context`.

@@ -47,8 +46,2 @@ * @default currentUser

authDirectiveName?: 'skipAuth' | string;
/**
* Customize how the user is validated. E.g. apply authorization role based validation.
* The validation is applied during the extended validation phase.
* @default `defaultProtectAllValidateFn`
*/
validateUser?: ValidateUserFn<UserType>;
} | {

@@ -65,3 +58,3 @@ /**

*/
mode: 'protect-single';
mode: 'protect-auth-directive';
/**

@@ -72,13 +65,6 @@ * Overrides the default directive name

authDirectiveName?: 'auth' | string;
/**
* Customize how the user is validated. E.g. apply authorization role based validation.
* The validation is applied during the extended validation phase.
* @default `defaultProtectSingleValidateFn`
*/
validateUser?: ValidateUserFn<UserType>;
});
export declare function defaultProtectAllValidateFn<UserType>(params: ValidateUserFnParams<UserType>): void | UnauthenticatedError;
export declare function defaultProtectSingleValidateFn<UserType>(params: ValidateUserFnParams<UserType>): void | UnauthenticatedError;
export declare function defaultValidateFn<UserType, ContextType>(user: UserType, contextType: ContextType): void;
export declare const useGenericAuth: <UserType extends {} = {}, ContextType extends DefaultContext = DefaultContext>(options: GenericAuthPluginOptions<UserType, ContextType>) => Plugin<{
validateUser: ValidateUserFn<UserType>;
validateUser: ValidateUserFn<UserType, ContextType>;
}>;

@@ -6,4 +6,13 @@ 'use strict';

const graphql = require('graphql');
const extendedValidation = require('@envelop/extended-validation');
function getDirective(info, name) {
var _a;
const { parentType, fieldName, schema } = info;
const schemaType = schema.getType(parentType.name);
const field = schemaType.getFields()[fieldName];
const astNode = field.astNode;
const authDirective = (_a = astNode === null || astNode === void 0 ? void 0 : astNode.directives) === null || _a === void 0 ? void 0 : _a.find(d => d.name.value === name);
return authDirective || null;
}
class UnauthenticatedError extends graphql.GraphQLError {

@@ -17,83 +26,29 @@ }

`;
function defaultProtectAllValidateFn(params) {
if (params.user == null && !params.fieldAuthDirectiveNode && !params.fieldAuthExtension) {
const schemaCoordinate = `${params.objectType.name}.${params.fieldNode.name.value}`;
return new UnauthenticatedError(`Accessing '${schemaCoordinate}' requires authentication.`, [params.fieldNode]);
function defaultValidateFn(user, contextType) {
if (!user) {
throw new UnauthenticatedError('Unauthenticated!');
}
}
function defaultProtectSingleValidateFn(params) {
if (params.user == null && (params.fieldAuthDirectiveNode || params.fieldAuthExtension)) {
const schemaCoordinate = `${params.objectType.name}.${params.fieldNode.name.value}`;
return new UnauthenticatedError(`Accessing '${schemaCoordinate}' requires authentication.`, [params.fieldNode]);
}
}
const useGenericAuth = (options) => {
var _a, _b;
const contextFieldName = options.contextFieldName || 'currentUser';
if (options.mode === 'protect-all' || options.mode === 'protect-single') {
const directiveName = (_a = options.authDirectiveName) !== null && _a !== void 0 ? _a : (options.mode === 'protect-all' ? 'skipAuth' : 'auth');
const validateUser = (_b = options.validateUser) !== null && _b !== void 0 ? _b : (options.mode === 'protect-all' ? defaultProtectAllValidateFn : defaultProtectSingleValidateFn);
const extractAuthMeta = (input) => {
var _a, _b, _c;
return {
fieldAuthExtension: (_a = input.extensions) === null || _a === void 0 ? void 0 : _a[directiveName],
fieldAuthDirectiveNode: (_c = (_b = input.astNode) === null || _b === void 0 ? void 0 : _b.directives) === null || _c === void 0 ? void 0 : _c.find(directive => directive.name.value === directiveName),
};
};
const fieldName = options.contextFieldName || 'currentUser';
const validateUser = options.validateUser || defaultValidateFn;
if (options.mode === 'protect-all') {
return {
onPluginInit({ addPlugin }) {
addPlugin(extendedValidation.useExtendedValidation({
rules: [
function AuthorizationExtendedValidationRule(context, args) {
const user = args.contextValue[contextFieldName];
const handleField = (fieldNode, objectType) => {
const field = objectType.getFields()[fieldNode.name.value];
if (field == null) {
// field is null/undefined if this is an introspection field
return;
}
const { fieldAuthExtension, fieldAuthDirectiveNode } = extractAuthMeta(field);
const error = validateUser({
user,
fieldNode,
objectType,
fieldAuthDirectiveNode,
fieldAuthExtension,
});
if (error) {
context.reportError(error);
}
};
return {
Field(node) {
const fieldType = graphql.getNamedType(context.getParentType());
if (graphql.isIntrospectionType(fieldType)) {
return false;
}
if (graphql.isObjectType(fieldType)) {
handleField(node, fieldType);
}
else if (graphql.isUnionType(fieldType)) {
for (const objectType of fieldType.getTypes()) {
handleField(node, objectType);
}
}
else if (graphql.isInterfaceType(fieldType)) {
for (const objectType of args.schema.getImplementations(fieldType).objects) {
handleField(node, objectType);
}
}
return undefined;
},
};
},
],
}));
},
async onContextBuilding({ context, extendContext }) {
const user = await options.resolveUserFn(context);
extendContext({
[contextFieldName]: user,
[fieldName]: user,
validateUser,
});
},
onExecute() {
return {
async onResolverCalled({ args, root, context, info }) {
const authDirectiveNode = getDirective(info, options.authDirectiveName || 'skipAuth');
if (authDirectiveNode)
return;
await context.validateUser(context[fieldName], context);
},
};
},
};

@@ -106,3 +61,4 @@ }

extendContext({
[contextFieldName]: user,
[fieldName]: user,
validateUser: () => validateUser(user, context),
});

@@ -112,2 +68,28 @@ },

}
else if (options.mode === 'protect-auth-directive') {
return {
async onContextBuilding({ context, extendContext }) {
const user = await options.resolveUserFn(context);
extendContext({
[fieldName]: user,
validateUser,
});
},
onExecute() {
return {
async onResolverCalled({ args, root, context, info }) {
const authDirectiveNode = getDirective(info, options.authDirectiveName || 'auth');
if (authDirectiveNode) {
await context.validateUser(context[fieldName], context, {
info,
context: context,
args,
root,
}, authDirectiveNode);
}
},
};
},
};
}
return {};

@@ -119,4 +101,4 @@ };

exports.UnauthenticatedError = UnauthenticatedError;
exports.defaultProtectAllValidateFn = defaultProtectAllValidateFn;
exports.defaultProtectSingleValidateFn = defaultProtectSingleValidateFn;
exports.defaultValidateFn = defaultValidateFn;
exports.getDirective = getDirective;
exports.useGenericAuth = useGenericAuth;
{
"name": "@envelop/generic-auth",
"version": "2.0.0-alpha-c8eef8e.0",
"version": "2.0.0-alpha-f336686.0",
"sideEffects": false,
"peerDependencies": {
"@envelop/core": "^1.6.1",
"@envelop/core": "1.7.0-alpha-f336686.0",
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
},
"dependencies": {
"@envelop/extended-validation": "^1.3.1"
},
"repository": {

@@ -33,4 +30,5 @@ "type": "git",

"import": "./*.mjs"
}
},
"./package.json": "./package.json"
}
}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc