Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@envelop/generic-auth

Package Overview
Dependencies
Maintainers
0
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 8.0.0-alpha-20240812121953-81638fef to 8.0.0-alpha-20240812201747-f93b5b19

8

cjs/index.js

@@ -8,12 +8,12 @@ "use strict";

exports.DIRECTIVE_SDL = `
directive @authenticated on FIELD_DEFINITION
directive @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE
`;
exports.SKIP_AUTH_DIRECTIVE_SDL = `
directive @skipAuth on FIELD_DEFINITION
directive @skipAuth on FIELD_DEFINITION | OBJECT | INTERFACE
`;
exports.REQUIRES_SCOPES_DIRECTIVE_SDL = `
directive @requiresScopes(scopes: [[String!]!]!) on FIELD_DEFINITION
directive @requiresScopes(scopes: [[String!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE
`;
exports.POLICY_DIRECTIVE_SDL = `
directive @policy(policies: [String!]!) on FIELD_DEFINITION
directive @policy(policies: [String!]!) on FIELD_DEFINITION | OBJECT | INTERFACE
`;

@@ -20,0 +20,0 @@ function createUnauthenticatedError(params) {

@@ -5,12 +5,12 @@ import { getNamedType, isInterfaceType, isIntrospectionType, isObjectType, isUnionType, } from 'graphql';

export const DIRECTIVE_SDL = /* GraphQL */ `
directive @authenticated on FIELD_DEFINITION
directive @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE
`;
export const SKIP_AUTH_DIRECTIVE_SDL = /* GraphQL */ `
directive @skipAuth on FIELD_DEFINITION
directive @skipAuth on FIELD_DEFINITION | OBJECT | INTERFACE
`;
export const REQUIRES_SCOPES_DIRECTIVE_SDL = /* GraphQL */ `
directive @requiresScopes(scopes: [[String!]!]!) on FIELD_DEFINITION
directive @requiresScopes(scopes: [[String!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE
`;
export const POLICY_DIRECTIVE_SDL = /* GraphQL */ `
directive @policy(policies: [String!]!) on FIELD_DEFINITION
directive @policy(policies: [String!]!) on FIELD_DEFINITION | OBJECT | INTERFACE
`;

@@ -17,0 +17,0 @@ export function createUnauthenticatedError(params) {

{
"name": "@envelop/generic-auth",
"version": "8.0.0-alpha-20240812121953-81638fef",
"version": "8.0.0-alpha-20240812201747-f93b5b19",
"sideEffects": false,

@@ -10,3 +10,3 @@ "peerDependencies": {

"dependencies": {
"@envelop/extended-validation": "4.1.0-alpha-20240812121953-81638fef",
"@envelop/extended-validation": "4.1.0-alpha-20240812201747-f93b5b19",
"@graphql-tools/utils": "^10.5.1",

@@ -13,0 +13,0 @@ "tslib": "^2.5.0"

@@ -249,6 +249,6 @@ ## `@envelop/generic-auth`

##### Protect a field using a field `directive`
##### Protect a field using a field or type `directive`
> By default, we assume that you have the GraphQL directive definition as part of your GraphQL
> schema (`directive @authenticated on FIELD_DEFINITION`).
> schema (`directive @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE`).

@@ -271,3 +271,3 @@ Then, in your GraphQL schema SDL, you can add `@authenticated` directive to your fields, and the

##### Protect a field using a field extension
##### Protect a field or type using extensions

@@ -315,62 +315,104 @@ ```typescript

##### With a custom directive with arguments
##### Role/scope based authentication with `@requiresScope` directive
It is possible to add custom parameters to your `@authenticated` directive. Here's an example for
adding role-aware authentication:
You can use `@requiresScope` directive to protect your schema based on the user's role or scope.
Here's an example of how you can use it:
```graphql
enum Role {
ADMIN
MEMBER
directive @requiresScopes(scopes: [[String!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE
type Query {
me: User! @requiresScopes(scopes: [["read:user"]])
protectedField: String @requiresScopes(scopes: [["read:admin"]])
publicField: String
}
directive @authenticated(role: Role!) on FIELD_DEFINITION
```
Then, you use the `directiveNode` parameter to check the arguments:
By default, the plugin will try to extract available scopes for the current user from `scope`
property which is expected to be a string like `read:user read:admin`. However you can customize
this behavior by providing a custom `extractScopes` function.
```ts
import { ValidateUserFn } from '@envelop/generic-auth'
useGenericAuth({
resolveUserFn,
validateUser,
mode: 'protect-granular',
extractScopes: user => user.scopes // Expected to return an array of strings
})
```
const validateUser: ValidateUserFn<UserType> = ({ user, fieldAuthDirectiveNode }) => {
// Now you can use the fieldAuthDirectiveNode parameter to implement custom logic for user validation, with access
// to the resolver auth directive arguments.
You can also apply `AND` or `OR` logic to the scopes:
if (!user) {
return new Error(`Unauthenticated!`)
}
```graphql
type Query {
# This field requires the user to have `read:user` OR `read:admin` scopes
me: User! @requiresScopes(scopes: [["read:user"], ["read:admin"]])
# This field requires the user to have `read:user` AND `read:admin` scopes
protectedField: String @requiresScopes(scopes: [["read:admin", "read:user"]])
publicField: String
}
```
const valueNode = fieldAuthDirectiveNode.arguments.find(arg => arg.name.value === 'role')
.value as EnumValueNode
const role = valueNode.value
##### `@policy` directive to fetch the roles from a policy service
if (role !== user.role) {
return new Error(`No permissions!`)
}
You can use the `@policy` directive to fetch the roles from a policy service. Here's an example of
how you can use it:
```graphql
directive @policy(name: String!) on FIELD_DEFINITION | OBJECT | INTERFACE
type Query {
me: User! @policy(policies: [["read:user"]])
protectedField: String @policy(policies: [["read:admin"]])
publicField: String
}
```
##### With a custom field extensions
It has the same logic with `@requiresScopes` but it can asynchronously fetch the roles from a
source;
You can use custom field extension to pass data to your `validateUser` function instead of using a
directive. Here's an example for adding role-aware authentication:
```ts
import { ValidateUserFn } from '@envelop/generic-auth'
useGenericAuth({
resolveUserFn,
validateUser,
mode: 'protect-granular',
fetchPolicies: async user => {
const res = await fetch('https://policy-service.com', {
headers: {
Authorization: `Bearer ${user.token}`
}
})
// Expected to return an array of strings
return res.json()
}
})
```
const validateUser: ValidateUserFn<UserType> = ({ user, fieldAuthExtension }) => {
// Now you can use the fieldAuthDirectiveNode parameter to implement custom logic for user validation, with access
// to the resolver auth directive arguments.
##### Reject the whole operation if the user is not authenticated for the entire selection set
if (!user) {
return new Error(`Unauthenticated!`)
}
By default, the plugin will reject the whole operation if the user is not authenticated for the
selection set fully. But if you want to allow partial execution, you can set `rejectUnauthorized` to
`false`.
const role = fieldAuthExtension.role
When `rejectUnauthorized` is set to `false`, the plugin will behave like below;
if (role !== user.role) {
return new Error(`No permissions!`)
```graphql
query {
me {
# This field will not be executed if the user is not authenticated
id
name
email
}
protectedField # This field will not be executed if the user is not authenticated
publicField # This field will be executed even if the user is not authenticated
}
```
##### With a custom field extensions
You can use custom field extension to pass data to your `validateUser` function instead of using a
directive. Here's an example for adding role-aware authentication:
```ts
const resolvers = {

@@ -382,4 +424,4 @@ Query: {

directives: {
authenticated: {
role: 'USER'
requiresScopes: {
scopes: [['read:user']]
}

@@ -386,0 +428,0 @@ }

@@ -40,6 +40,6 @@ import { ExecutionArgs, FieldNode, GraphQLError, GraphQLField, GraphQLInterfaceType, GraphQLObjectType } from 'graphql';

export type ValidateUserFn<UserType> = (params: ValidateUserFnParams<UserType>) => void | GraphQLError;
export declare const DIRECTIVE_SDL = "\n directive @authenticated on FIELD_DEFINITION\n";
export declare const SKIP_AUTH_DIRECTIVE_SDL = "\n directive @skipAuth on FIELD_DEFINITION\n";
export declare const REQUIRES_SCOPES_DIRECTIVE_SDL = "\n directive @requiresScopes(scopes: [[String!]!]!) on FIELD_DEFINITION\n";
export declare const POLICY_DIRECTIVE_SDL = "\n directive @policy(policies: [String!]!) on FIELD_DEFINITION\n";
export declare const DIRECTIVE_SDL = "\n directive @authenticated on FIELD_DEFINITION | OBJECT | INTERFACE\n";
export declare const SKIP_AUTH_DIRECTIVE_SDL = "\n directive @skipAuth on FIELD_DEFINITION | OBJECT | INTERFACE\n";
export declare const REQUIRES_SCOPES_DIRECTIVE_SDL = "\n directive @requiresScopes(scopes: [[String!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE\n";
export declare const POLICY_DIRECTIVE_SDL = "\n directive @policy(policies: [String!]!) on FIELD_DEFINITION | OBJECT | INTERFACE\n";
export type GenericAuthPluginOptions<UserType extends {} = {}, ContextType = DefaultContext, CurrentUserKey extends string = 'currentUser'> = {

@@ -46,0 +46,0 @@ /**

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