@envelop/generic-auth
Advanced tools
Comparing version 4.0.0-alpha-bed7c7d.0 to 4.0.0
@@ -42,6 +42,6 @@ import { DefaultContext, Plugin } from '@envelop/core'; | ||
/** | ||
* Overrides the default directive name | ||
* Overrides the default directive name or extension field for marking a field available for unauthorized users. | ||
* @default skipAuth | ||
*/ | ||
authDirectiveName?: 'skipAuth' | string; | ||
directiveOrExtensionFieldName?: 'skipAuth' | string; | ||
/** | ||
@@ -64,8 +64,8 @@ * Customize how the user is validated. E.g. apply authorization role based validation. | ||
*/ | ||
mode: 'protect-single'; | ||
mode: 'protect-granular'; | ||
/** | ||
* Overrides the default directive name | ||
* Overrides the default directive name or extension field for marking a field available only for authorized users. | ||
* @default auth | ||
*/ | ||
authDirectiveName?: 'auth' | string; | ||
directiveOrExtensionFieldName?: 'auth' | string; | ||
/** | ||
@@ -72,0 +72,0 @@ * Customize how the user is validated. E.g. apply authorization role based validation. |
@@ -31,4 +31,4 @@ 'use strict'; | ||
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'); | ||
if (options.mode === 'protect-all' || options.mode === 'protect-granular') { | ||
const directiveOrExtensionFieldName = (_a = options.directiveOrExtensionFieldName) !== 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); | ||
@@ -38,4 +38,4 @@ const extractAuthMeta = (input) => { | ||
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), | ||
fieldAuthExtension: (_a = input.extensions) === null || _a === void 0 ? void 0 : _a[directiveOrExtensionFieldName], | ||
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 === directiveOrExtensionFieldName), | ||
}; | ||
@@ -42,0 +42,0 @@ }; |
{ | ||
"name": "@envelop/generic-auth", | ||
"version": "4.0.0-alpha-bed7c7d.0", | ||
"version": "4.0.0", | ||
"sideEffects": false, | ||
"peerDependencies": { | ||
"@envelop/core": "^2.0.0", | ||
"@envelop/core": "^2.1.0", | ||
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" | ||
}, | ||
"dependencies": { | ||
"@envelop/extended-validation": "^1.3.1" | ||
"@envelop/extended-validation": "^1.4.0" | ||
}, | ||
@@ -12,0 +12,0 @@ "repository": { |
@@ -9,5 +9,5 @@ ## `@envelop/generic-auth` | ||
- **Option #1 - Complete Protection**: protected the entire GraphQL schema from unauthenticated access. | ||
- **Option #2 - Manual Validation**: the plugin will just resolve the user and injects it into the `context` without validating the user. | ||
- **Option #3 - Automatic validation using GraphQL directives**: Look for `@auth` directive and automatically protect specific GraphQL fields. | ||
- **Option #1 - Complete Protection**: protected the entire GraphQL schema from unauthenticated access. Allow unauthenticated access for certain fields by annotating them with a `@skipAuth` directive or `skipAuth` field extension. | ||
- **Option #2 - Manual Validation**: the plugin will just resolve the user and injects it into the `context` without validating access to schema field. | ||
- **Option #3 - Granular field access by using schema field directives or field extensions**: Look for an `@auth` directive or `auth` extension field and automatically protect those specific GraphQL fields. | ||
@@ -106,2 +106,4 @@ ## Getting Started | ||
##### Allow unauthenticated access for specific fields using a field `directive` | ||
> By default, we assume that you have the GraphQL directive definition as part of your GraphQL schema (`directive @skipAuth on FIELD_DEFINITION`). | ||
@@ -121,4 +123,25 @@ | ||
> If you are using a different directive for authentication, you can pass `authDirectiveName` configuration to customize it. | ||
> If you are using a different directive for authentication, you can pass `directiveOrExtensionFieldName` configuration to customize it. | ||
##### Allow unauthenticated access for specific fields using a field extension | ||
```typescript | ||
import { GraphQLObjectType, GraphQLInt } from 'graphql'; | ||
const GraphQLQueryType = new GraphQLObjectType({ | ||
name: 'Query', | ||
fields: { | ||
foo: { | ||
type: GraphQLInt, | ||
resolve: () => 1, | ||
extensions: { | ||
skipAuth: true, | ||
}, | ||
}, | ||
}, | ||
}); | ||
``` | ||
> If you want to use a different directive for authentication, you can use the `directiveOrExtensionFieldName` configuration to customize it. | ||
#### Option #2 - `resolve-only` | ||
@@ -169,5 +192,5 @@ | ||
#### Option #3 - `protect-auth-directive` | ||
#### Option #3 - `protect-granular` | ||
This mode is similar to option #2, but it uses `@auth` SDL directive to automatically protect specific GraphQL fields. | ||
This mode is similar to option #2, but it uses the `@auth` SDL directive or `auth` field extension for protecting specific GraphQL fields. | ||
@@ -194,3 +217,3 @@ ```ts | ||
validateUser, | ||
mode: 'protect-auth-directive', | ||
mode: 'protect-granular', | ||
}), | ||
@@ -201,2 +224,4 @@ ], | ||
##### Protect a field using a field `directive` | ||
> By default, we assume that you have the GraphQL directive definition as part of your GraphQL schema (`directive @auth on FIELD_DEFINITION`). | ||
@@ -216,12 +241,34 @@ | ||
> If you are using a different directive for authentication, you can pass `authDirectiveName` configuration to customize it. | ||
> If you are using a different directive for authentication, you can pass `directiveOrExtensionFieldName` configuration to customize it. | ||
##### Protect a field using a field extension | ||
```typescript | ||
import { GraphQLObjectType, GraphQLInt } from 'graphql'; | ||
const GraphQLQueryType = new GraphQLObjectType({ | ||
name: 'Query', | ||
fields: { | ||
foo: { | ||
type: GraphQLInt, | ||
resolve: () => 1, | ||
extensions: { | ||
auth: true, | ||
}, | ||
}, | ||
}, | ||
}); | ||
``` | ||
> If you are using a different field extension for authentication, you can pass `directiveOrExtensionFieldName` configuration to customize it. | ||
##### Extend authentication with custom directive logic | ||
You can also specify a custom `validateUser` function and get access to the `GraphQLResolveInfo` object while using the `protect-auth-directive` mode: | ||
You can also specify a custom `validateUser` function and get access to a handy object while using the `protect-all` and `protect-granular` mode: | ||
```ts | ||
import { GraphQLError } from 'graphql'; | ||
import { ValidateUserFn } from '@envelop/generic-auth'; | ||
const validateUser: ValidateUserFn<UserType> = async (user, context, { root, args, context, info }) => { | ||
const validateUser: ValidateUserFn<UserType> = async ({ user }) => { | ||
// Now you can use the 3rd parameter to implement custom logic for user validation, with access | ||
@@ -231,3 +278,3 @@ // to the resolver data and information. | ||
if (!user) { | ||
throw new Error(`Unauthenticated!`); | ||
return new GraphQLError(`Unauthenticated.`); | ||
} | ||
@@ -253,3 +300,3 @@ }; | ||
const validateUser: ValidateUserFn<UserType> = async (user, context, { root, args, context, info }, directiveNode) => { | ||
const validateUser: ValidateUserFn<UserType> = async ({ user, fieldAuthDirectiveNode }) => { | ||
// Now you can use the 3rd parameter to implement custom logic for user validation, with access | ||
@@ -262,3 +309,3 @@ // to the resolver data and information. | ||
const valueNode = directiveNode.arguments.find(arg => arg.name.value === 'role').value as EnumValueNode; | ||
const valueNode = fieldAuthDirectiveNode.arguments.find(arg => arg.name.value === 'role').value as EnumValueNode; | ||
const role = valueNode.value; | ||
@@ -265,0 +312,0 @@ |
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
26048
1
308