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 3.0.0 to 4.0.0-alpha-7aee595.0

46

index.d.ts
import { DefaultContext, Plugin } from '@envelop/core';
import { DirectiveNode, GraphQLError, GraphQLResolveInfo } from 'graphql';
export * from './utils';
import { DirectiveNode, FieldNode, GraphQLError, GraphQLObjectType } from 'graphql';
export declare class UnauthenticatedError extends GraphQLError {
}
export declare type ResolveUserFn<UserType, ContextType = DefaultContext> = (context: ContextType) => null | UserType | Promise<UserType | null>;
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 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 const DIRECTIVE_SDL = "\n directive @auth on FIELD_DEFINITION\n";

@@ -24,7 +30,2 @@ 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`.

@@ -46,2 +47,8 @@ * @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>;
} | {

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

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

@@ -65,6 +72,13 @@ * 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 defaultValidateFn<UserType, ContextType>(user: UserType, contextType: ContextType): void;
export declare function defaultProtectAllValidateFn<UserType>(params: ValidateUserFnParams<UserType>): void | UnauthenticatedError;
export declare function defaultProtectSingleValidateFn<UserType>(params: ValidateUserFnParams<UserType>): void | UnauthenticatedError;
export declare const useGenericAuth: <UserType extends {} = {}, ContextType extends DefaultContext = DefaultContext>(options: GenericAuthPluginOptions<UserType, ContextType>) => Plugin<{
validateUser: ValidateUserFn<UserType, ContextType>;
validateUser: ValidateUserFn<UserType>;
}>;

@@ -6,13 +6,4 @@ '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 {

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

`;
function defaultValidateFn(user, contextType) {
if (!user) {
throw new UnauthenticatedError('Unauthenticated!');
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 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) => {
const fieldName = options.contextFieldName || 'currentUser';
const validateUser = options.validateUser || defaultValidateFn;
if (options.mode === 'protect-all') {
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),
};
};
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({
[fieldName]: user,
validateUser,
[contextFieldName]: user,
});
},
async onResolverCalled({ args, root, context, info }) {
const authDirectiveNode = getDirective(info, options.authDirectiveName || 'skipAuth');
if (authDirectiveNode)
return;
await context.validateUser(context[fieldName], context);
},
};

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

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

@@ -64,24 +112,2 @@ },

}
else if (options.mode === 'protect-auth-directive') {
return {
async onContextBuilding({ context, extendContext }) {
const user = await options.resolveUserFn(context);
extendContext({
[fieldName]: user,
validateUser,
});
},
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 {};

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

exports.UnauthenticatedError = UnauthenticatedError;
exports.defaultValidateFn = defaultValidateFn;
exports.getDirective = getDirective;
exports.defaultProtectAllValidateFn = defaultProtectAllValidateFn;
exports.defaultProtectSingleValidateFn = defaultProtectSingleValidateFn;
exports.useGenericAuth = useGenericAuth;
{
"name": "@envelop/generic-auth",
"version": "3.0.0",
"version": "4.0.0-alpha-7aee595.0",
"sideEffects": false,

@@ -9,2 +9,5 @@ "peerDependencies": {

},
"dependencies": {
"@envelop/extended-validation": "^1.3.1"
},
"repository": {

@@ -11,0 +14,0 @@ "type": "git",

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