forked from jwhenshaw/graphql-directives-auth
-
Notifications
You must be signed in to change notification settings - Fork 0
/
FieldAuthDirective.js
43 lines (35 loc) · 1.39 KB
/
FieldAuthDirective.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
const { SchemaDirectiveVisitor } = require("apollo-server");
const { defaultFieldResolver } = require("graphql");
const strategies = require("./strategies");
class FieldAuthDirective extends SchemaDirectiveVisitor {
// Visitor methods for nested types like fields and arguments
// also receive a details object that provides information about
// the parent and grandparent types.
visitFieldDefinition(field, details) {
console.log("FieldAuthDirective:visitFieldDef", { field, details });
this.ensureFieldWrapped(field);
field._requiredAuthRole = this.args.requires;
}
ensureFieldWrapped(field) {
const { resolve = defaultFieldResolver } = field;
field.resolve = async function(...args) {
// Get the required Role from the field first, falling back
// to the objectType if no Role is required by the field:
const requiredRole = field._requiredAuthRole;
if (!requiredRole) {
// Let's be on the safe side
throw new Error("not authorized");
}
const requestData = args[2];
await this.executeStrategy(requiredRole, requestData);
return resolve.apply(this, args);
}.bind(this);
}
async executeStrategy(role, requestData) {
const strategyResult = await strategies[role.toLowerCase()](requestData);
if (!strategyResult) {
throw new Error("not authorized");
}
}
}
module.exports = FieldAuthDirective;