Files
Superalgos/server/schema/schema.js
T

367 lines
13 KiB
JavaScript

const MODULE_NAME = "schema";
const graphql = require('graphql');
const _ = require('lodash');
const User = require('../models/user');
const tokenDecoder = require('../auth/TokenDecoder');
const {
GraphQLObjectType,
GraphQLString,
GraphQLSchema,
GraphQLID,
GraphQLInt,
GraphQLList,
GraphQLNonNull
} = graphql; // Destructuring this variables from inside the package.
let roles = [
{id: '1', name: 'Not Defined'},
{id: '2', name: 'Developer'},
{id: '3', name: 'Trader'},
{id: '4', name: 'Data Analyst'}
];
// Types
const UserType = new GraphQLObjectType({
name: 'User',
fields: () => ({
id: { type: GraphQLID},
authId: { type: GraphQLString},
alias: {type: GraphQLString},
firstName: {type: GraphQLString},
middleName: {type: GraphQLString},
lastName: {type: GraphQLString},
email: {type: GraphQLString},
emailVerified: {type: GraphQLInt},
isDeveloper: {type: GraphQLInt},
isTrader: {type: GraphQLInt},
isDataAnalyst: {type: GraphQLInt},
role: {
type: RoleType,
resolve(parent, args) {
return _.find(roles, {id: parent.roleId});
}
}
})
});
const RoleType = new GraphQLObjectType({
name: 'Role',
fields: () => ({
id: { type: GraphQLID},
name: {type: GraphQLString},
users: {
type: new GraphQLList(UserType),
resolve(parent, args) {
return User.find({roleId: parent.id});
}
}
})
});
// RootQueries
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
user: {
type: UserType,
args: {id: {type: GraphQLID}},
resolve(parent,args) {
// Code to get data from data source.
return User.findById(args.id);
}
},
userByAuthId: {
type: UserType,
args: {authId: {type: GraphQLString}},
resolve(parent,args) {
// Code to get data from data source.
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> RootQuery -> userByAuthId -> resolve -> Entering function."); }
/* In order to be able to wait for asyc calls to the database, we need to return a promise to GraphQL. */
const promiseToGraphQL = new Promise((resolve, reject) => {
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> RootQuery -> userByAuthId -> resolve -> Promise -> Entering function."); }
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> RootQuery -> userByAuthId -> resolve -> Promise -> args.authId = " + args.authId); }
findUserByAuthId(args.authId, onUserFound);
function onUserFound(err, responseToGraphQL) {
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> RootQuery -> userByAuthId -> resolve -> Promise -> onUserFound -> Entering function."); }
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> RootQuery -> userByAuthId -> resolve -> Promise -> onUserFound -> responseToGraphQL = " + JSON.stringify(responseToGraphQL)); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
if (global.ERROR_LOG === true) { console.log("[ERROR] " + MODULE_NAME + " -> RootQuery -> userByAuthId -> resolve -> Promise -> onUserFound -> err.message = " + err.message); }
reject (responseToGraphQL);
} else {
resolve (responseToGraphQL);
}
}
});
return promiseToGraphQL;
}
},
role: {
type: RoleType,
args: {id: {type: GraphQLID}},
resolve(parent,args) {
// Code to get data from data source.
return _.find(roles, {id: args.id});
}
},
users: {
type: new GraphQLList(UserType),
resolve(parent, args){
return User.find({});
}
},
roles: {
type: new GraphQLList(RoleType),
resolve(parent, args){
return roles;
}
}
}
})
// Mutations
const Mutation = new GraphQLObjectType({
name: 'Mutation',
fields: {
authenticate: {
type: UserType,
args: {
idToken: {type: new GraphQLNonNull(GraphQLString)}
},
resolve(parent, args) {
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> Mutation -> authenticate -> resolve -> Entering function."); }
/* In order to be able to wait for asyc calls to the database, and authorization authority, we need to return a promise to GraphQL. */
const promiseToGraphQL = new Promise((resolve, reject) => {
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> Mutation -> authenticate -> resolve -> Promise -> Entering function."); }
authenticate(args.idToken, onAuthenticated);
function onAuthenticated(err, responseToGraphQL) {
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> Mutation -> authenticate -> resolve -> Promise -> onAuthenticated -> Entering function."); }
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> Mutation -> authenticate -> resolve -> Promise -> onAuthenticated -> responseToGraphQL = " + JSON.stringify(responseToGraphQL)); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
if (global.ERROR_LOG === true) { console.log("[ERROR] " + MODULE_NAME + " -> Mutation -> authenticate -> resolve -> Promise -> onAuthenticated -> err.message = " + err.message); }
reject (responseToGraphQL);
} else {
resolve (responseToGraphQL);
}
}
});
return promiseToGraphQL;
}
},
updateUser:{
type: UserType,
args: {
id: {type: new GraphQLNonNull(GraphQLID)},
firstName: {type: GraphQLString},
middleName: {type: GraphQLString},
lastName: {type: GraphQLString},
email: {type: GraphQLString},
emailVerified: {type: GraphQLInt},
isDeveloper: {type: GraphQLInt},
isTrader: {type: GraphQLInt},
isDataAnalyst: {type: GraphQLInt},
roleId: {type: new GraphQLNonNull(GraphQLString)}
},
resolve(parent, args) {
let key = {
_id: args.id
};
let updatedUser = {
firstName: args.firstName,
middleName: args.middleName,
lastName: args.lastName,
email: args.email,
emailVerified: args.emailVerified,
isDeveloper: args.isDeveloper,
isTrader: args.isTrader,
isDataAnalyst: args.isDataAnalyst,
roleId: args.roleId
};
return User.update(key, updatedUser);
}
}
}
})
function findUserByAuthId(authId, callBackFunction) {
try {
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> findUserByAuthId -> Entering function."); }
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> findUserByAuthId -> authId = " + authId); }
if (authId === null || authId === undefined) {
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> findUserByAuthId -> User requested not specified."); }
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> findUserByAuthId -> args.authId = " + authId); }
callBackFunction(global.DEFAULT_FAIL_RESPONSE, { error: "Bad Request" });
return;
}
User.findOne({authId: authId}, onUserReceived)
function onUserReceived(err, user) {
if(err) {
if (ERROR_LOG === true) { console.log("[ERROR] " + MODULE_NAME + " -> findUserByAuthId -> onUserReceived -> Database Error."); }
if (ERROR_LOG === true) { console.log("[ERROR] " + MODULE_NAME + " -> findUserByAuthId -> onUserReceived -> err = " + err); }
callBackFunction(global.DEFAULT_FAIL_RESPONSE, { error: err });
}
else{
if (user === null) {
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> findUserByAuthId -> onUserReceived -> User not found at Database."); }
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> findUserByAuthId -> onUserReceived -> args.authId = " + authId); }
let customResponse = {
result: global.CUSTOM_OK_RESPONSE.result,
message: "User Not Found"
};
callBackFunction(customResponse, { error: customResponse.message });
return;
}
if (user.authId === authId && user.authId !== undefined) {
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> findUserByAuthId -> onUserReceived -> User found at Database."); }
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> findUserByAuthId -> onUserReceived -> args.authId = " + authId); }
callBackFunction(global.DEFAULT_OK_RESPONSE, user);
return;
} else {
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> findUserByAuthId -> onUserReceived -> User found at Database is not the user requested."); }
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> findUserByAuthId -> onUserReceived -> args.authId = " + authId); }
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> findUserByAuthId -> onUserReceived -> user.authId = " + user.authId); }
callBackFunction(global.DEFAULT_FAIL_RESPONSE, { error: err });
return;
}
}
}
} catch(err) {
if (global.ERROR_LOG === true) { console.log("[ERROR] " + MODULE_NAME + " -> findUserByAuthId -> err.message = " + err.message); }
callBackFunction(global.DEFAULT_FAIL_RESPONSE, { error: err });
}
}
function authenticate(encodedToken, callBackFunction) {
try {
if (INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> authenticate -> Entering function."); }
let authId = "";
let alias = "";
let email = "";
let emailVerified = false;
tokenDecoder(encodedToken, onValidated);
function onValidated(err, decodedToken) {
if (global.INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> authenticate -> onValidated -> Entering function."); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
if (global.ERROR_LOG === true) { console.log("[ERROR] " + MODULE_NAME + " -> authenticate -> onValidated -> err.message = " + err.message); }
callBackFunction(global.DEFAULT_FAIL_RESPONSE, { error: err });
return;
}
authId = decodedToken.sub;
alias = decodedToken.nickname;
email = decodedToken.email;
emailVerified = decodedToken.email_verified;
findUserByAuthId(authId, onUserFound);
function onUserFound(err, user){
if (global.INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> authenticate -> onValidated -> onUserFound -> Entering function."); }
if (err.result === global.DEFAULT_FAIL_RESPONSE.result) {
if (global.ERROR_LOG === true) { console.log("[ERROR] " + MODULE_NAME + " -> authenticate -> onValidated -> onUserFound -> err.message = " + err.message); }
callBackFunction(global.DEFAULT_FAIL_RESPONSE, { error: err });
return;
}
if (err.result === global.DEFAULT_OK_RESPONSE.result) {
if (global.INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> authenticate -> onValidated -> onUserFound -> User already exists at database"); }
callBackFunction(global.DEFAULT_OK_RESPONSE, { authId: authId, alias: user.alias });
return;
}
if (
err.result === global.CUSTOM_OK_RESPONSE.result &&
err.message === "User Not Found"
) {
if (global.INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> authenticate -> onValidated -> onUserFound -> User does not exist at database"); }
/* The authenticated user is NOT at our module database. We need to add him. */
let newUser = new User({
alias: alias,
authId: authId,
email: email,
emailVerified: emailVerified,
roleId: "1"
});
if (global.INFO_LOG === true) { console.log("[INFO] " + MODULE_NAME + " -> authenticate -> onValidated -> onUserFound -> " + alias + " being added to the database"); }
newUser.save();
callBackFunction(global.DEFAULT_OK_RESPONSE, { authId, alias });
}
}
}
} catch(err) {
if (global.ERROR_LOG === true) { console.log("[ERROR] " + MODULE_NAME + " -> authenticate -> err.message = " + err.message); }
callBackFunction(global.DEFAULT_FAIL_RESPONSE, { error: err });
}
}
module.exports = new GraphQLSchema({
query: RootQuery,
mutation: Mutation
});