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

mercurius-auth

Package Overview
Dependencies
Maintainers
2
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mercurius-auth - npm Package Compare versions

Comparing version 1.4.0 to 1.5.0

test/repeteable-directives-gateway.js

37

lib/auth.js

@@ -29,4 +29,4 @@ 'use strict'

if (Array.isArray(astNode.directives) && astNode.directives.length > 0) {
const authDirective = astNode.directives.find(directive => directive.name.value === this[kAuthDirective])
if (typeof authDirective !== 'undefined') {
const authDirective = astNode.directives.filter(directive => directive.name.value === this[kAuthDirective])
if (authDirective.length > 0) {
return authDirective

@@ -118,19 +118,26 @@ }

if (typeof schemaType !== 'undefined' && typeof schemaType.getFields === 'function') {
for (const [fieldName, fieldPolicy] of Object.entries(typePolicy)) {
if (fieldName === '__typePolicy') {
if (typeof schemaType.resolveReference === 'function') {
// If type is a reference resolver, we wrap this function
const originalResolveReference = schemaType.resolveReference
schemaType.resolveReference = this[kMakeProtectedResolver](fieldPolicy, originalResolveReference)
for (let [fieldName, fieldPolicies] of Object.entries(typePolicy)) {
// this branch of code handles both internal and external policies registration
if (!Array.isArray(fieldPolicies)) {
fieldPolicies = [fieldPolicies]
}
for (const fieldPolicy of fieldPolicies) {
if (fieldName === '__typePolicy') {
if (typeof schemaType.resolveReference === 'function') {
// If type is a reference resolver, we wrap this function
const originalResolveReference = schemaType.resolveReference
schemaType.resolveReference = this[kMakeProtectedResolver](fieldPolicy, originalResolveReference)
} else {
// Wrap each field for a protected schema type
for (const schemaTypeField of Object.values(schemaType.getFields())) {
this[kWrapFieldResolver](schemaTypeField, fieldPolicy)
}
}
} else {
// Wrap each field for a protected schema type
for (const schemaTypeField of Object.values(schemaType.getFields())) {
const schemaTypeField = schemaType.getFields()[fieldName]
if (typeof schemaTypeField !== 'undefined') {
this[kWrapFieldResolver](schemaTypeField, fieldPolicy)
}
}
} else {
const schemaTypeField = schemaType.getFields()[fieldName]
if (typeof schemaTypeField !== 'undefined') {
this[kWrapFieldResolver](schemaTypeField, fieldPolicy)
}
}

@@ -137,0 +144,0 @@ }

@@ -88,3 +88,3 @@ 'use strict'

: {}
for (const [fieldName, fieldPolicy] of Object.entries(typePolicy)) {
for (const [fieldName, fieldPolicies] of Object.entries(typePolicy)) {
// each `fieldName` is a single GraphQL item associated with the directive

@@ -113,8 +113,12 @@

}
// The null parameters are: https://graphql.org/learn/execution/#root-fields-resolvers
// - parent: it is not possible know it since the resolver is not executed yet
// - args: it is not expected that the introspection query will have arguments for the directives policies
canShowDirectiveField = await policyFunction(fieldPolicy, null, null, context, info)
if (canShowDirectiveField instanceof Error || !canShowDirectiveField) {
canShowDirectiveField = false
for (const fieldPolicy of fieldPolicies) {
// The null parameters are: https://graphql.org/learn/execution/#root-fields-resolvers
// - parent: it is not possible know it since the resolver is not executed yet
// - args: it is not expected that the introspection query will have arguments for the directives policies
canShowDirectiveField = await policyFunction(fieldPolicy, null, null, context, info)
if (canShowDirectiveField instanceof Error || !canShowDirectiveField) {
canShowDirectiveField = false
break
}
}

@@ -121,0 +125,0 @@ } catch (error) {

{
"name": "mercurius-auth",
"version": "1.4.0",
"version": "1.5.0",
"description": "Mercurius Auth Plugin adds configurable Authentication and Authorization support to Mercurius.",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -639,3 +639,3 @@ 'use strict'

test('repeatable directive', async (t) => {
t.plan(4)
t.plan(5)

@@ -663,5 +663,4 @@ const app = Fastify()

applyPolicy: async () => {
t.pass('should be called once')
t.todo('should be called three times but repeatable directives are not supported')
return false
t.pass('should be called three times')
return true
}

@@ -682,3 +681,4 @@ })

fields: [
{ name: 'title' }
{ name: 'title' },
{ name: 'message' }
]

@@ -685,0 +685,0 @@ }

@@ -12,3 +12,3 @@ 'use strict'

directive @hasRole (role: String!) on OBJECT | FIELD_DEFINITION
directive @hasPermission (grant: String!) on OBJECT | FIELD_DEFINITION
directive @hasPermission (grant: String!) repeatable on OBJECT | FIELD_DEFINITION

@@ -18,2 +18,3 @@ type Message {

message: String @auth
notes: String @hasPermission(grant: "see-all") @hasPermission(grant: "notes")
password: String @hasPermission(grant: "see-all")

@@ -81,2 +82,3 @@ }

message: 'acme one',
notes: 'acme one',
password: 'acme-one'

@@ -87,2 +89,3 @@ },

message: 'acme two',
notes: 'acme two',
password: 'acme-two'

@@ -308,3 +311,3 @@ }

result (t, responseJson) {
t.plan(3)
t.plan(4)
const { types } = responseJson.data.__schema

@@ -317,3 +320,24 @@

t.ok(objMessage.fields.find(field => field.name === 'password'), 'role is right')
t.notOk(objMessage.fields.find(field => field.name === 'notes'), 'doesn\'t have the role "notes"')
}
},
{
name: 'Introspection query with multiple permissions',
query: getIntrospectionQuery(),
headers: {
'x-token': 'token',
'x-role': 'not-an-admin',
'x-permission': 'see-all,notes'
},
result (t, responseJson) {
t.plan(4)
const { types } = responseJson.data.__schema
t.notOk(types.find(type => type.name === 'AdminMessage'), 'the AdminMessage type has been filtered')
const objMessage = types.find(type => type.name === 'Message')
t.ok(objMessage, 'the Message type is present')
t.ok(objMessage.fields.find(field => field.name === 'password'), 'role is right')
t.ok(objMessage.fields.find(field => field.name === 'notes'), 'role is right')
}
}

@@ -496,7 +520,11 @@ ].forEach(({ name, query, result, headers }) => {

function hasPermissionContext (context) {
return { permission: context.reply.request.headers['x-permission'] }
const headerValue = context.reply.request.headers['x-permission']
return { permission: headerValue ? headerValue.split(',') : [] }
}
async function hasPermissionPolicy (authDirectiveAST, parent, args, context, info) {
const needed = authDirectiveAST.arguments.find(arg => arg.name.value === 'grant').value.value
const hasGrant = context.auth.permission === needed
const hasGrant = context.auth.permission.includes(needed)
if (!hasGrant) {

@@ -503,0 +531,0 @@ throw new Error(`Needed ${needed} grant`)

Sorry, the diff of this file is not supported yet

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