diff --git a/sources/apollo/server.js b/sources/apollo/server.js index e8d422cf..d5406d9d 100644 --- a/sources/apollo/server.js +++ b/sources/apollo/server.js @@ -15,8 +15,11 @@ const StoryAPI = require('./stories/story.datasources.js'); const MessAPI = require('./mess/mess.datasource.js'); const typeDefs = require('./schema.js'); const resolvers = require('./resolvers.js'); -const { firebaseApp } = require('../helpers/firebase'); -const { populatePermissions } = require('../helpers/permissions'); +const {firebaseApp}=require("../helpers/firebase"); +const { populatePermissions } = require("../helpers/permissions"); + +const NodeCache = require( "node-cache" ); +const tokenCache = new NodeCache(); //Datasources const dataSources = () => ({ @@ -44,16 +47,27 @@ const server = new ApolloServer({ */ context: async ({ req }) => { if (req.headers && req.headers.authorization) { - const idToken = req.headers.authorization; + const idToken=req.headers.authorization; try { - const decodedToken = await firebaseApp.auth().verifyIdToken(idToken); - const { uid } = decodedToken; - if (decodedToken.mongoID) { - return { uid, permissions: await populatePermissions(decodedToken.mongoID) }; + console.time("firebase"); + + let userToken = tokenCache.get(idToken); + if (userToken === undefined) { + const decodedToken = await firebaseApp.auth().verifyIdToken(idToken) + // eslint-disable-next-line prefer-destructuring + userToken={ uid: decodedToken.uid, mongoID: decodedToken.mongoID } + tokenCache.set(idToken, userToken,36000); + } + + console.timeEnd("firebase"); + + if(userToken.mongoID){ + return {uid: userToken.uid, permissions: await populatePermissions(userToken.mongoID)}; } - return { uid, permissions: ['users.Auth'] }; - } catch (error) { - const errorMessage = error.errorInfo ? error.errorInfo.message : error; + return {uid: userToken.uid, permissions: ["users.Auth"]}; + + } catch (error) { + const errorMessage= error.errorInfo? error.errorInfo.message : error; return { error: { message: errorMessage, code: 'UNAUTHORIZED' }, }; diff --git a/sources/apollo/users/user.datasources.js b/sources/apollo/users/user.datasources.js index 828a6ef6..a0f56058 100644 --- a/sources/apollo/users/user.datasources.js +++ b/sources/apollo/users/user.datasources.js @@ -18,6 +18,19 @@ class UserAPI extends DataSource { getUserByUsername(username) { return Users.findOne({ username }); } + async updateUserAfterSignUp(newUser,uid) { + const accessLevelObj = { + level: '1', + name:newUser.name, + user: newUser + }; + const createdAccessLevel = await AccessLevel.create(accessLevelObj); + await newUser.clubAccess.push(createdAccessLevel); + await newUser.save(); + if (process.env.NODE_ENV !== "test") { + firebase.updateJWT(uid,{mongoID:newUser._id}); + } + } /** * Single function which handles both sign up and sign in of a user * If the user already exists in the database, it simply fetches the existing doucment @@ -28,9 +41,10 @@ class UserAPI extends DataSource { * @param {String} uid firebase uid * @returns {Object} created user object */ - async authUser(user,uid) { + async authUser(user, uid) { + console.time("authuser"); let incomingUser; - const exisitingUser=await Users.findOne({firebaseUID:uid}); + const exisitingUser=await Users.findOne({firebaseUID:uid}).lean(); // User document exists(Sign in) if(exisitingUser){ incomingUser=exisitingUser; @@ -48,19 +62,12 @@ class UserAPI extends DataSource { emergencyContact: user.emergencyContact, displayPicture: user.displayPicture, }); - const accessLevelObj = { - level: '1', - name:newUser.name, - user: newUser, - }; - const createdAccessLevel = await AccessLevel.create(accessLevelObj); - await newUser.clubAccess.push(createdAccessLevel); - await newUser.save(); - if (process.env.NODE_ENV !== "test") { - firebase.updateJWT(uid,{mongoID:newUser._id}); - } - incomingUser= await Users.findOne({firebaseUID:uid}) + this.updateUserAfterSignUp(newUser,uid) + // incomingUser = await Users.findOne({ firebaseUID: uid }).lean() + incomingUser = newUser + // console.log(newUser, incomingUser); } + console.timeEnd("authuser"); return incomingUser; } /** @@ -112,7 +119,7 @@ class UserAPI extends DataSource { return {...INVALID_INPUT,message:"User Not Found"}; } - await Users.deleteOne({ id: foundUser._id }) + await Users.deleteOne({ _id: foundUser._id }) await AccessLevel.deleteMany({ user: foundUser._id }); if(process.env.NODE_ENV !== "test") { diff --git a/sources/helpers/permissions.js b/sources/helpers/permissions.js index 83e2868f..5f2efdf9 100644 --- a/sources/helpers/permissions.js +++ b/sources/helpers/permissions.js @@ -27,8 +27,11 @@ const rolesPermissionsMap={ * * @param {String} id Mongo User id */ -const populatePermissions = async id => { - const userAccessLevels = await AccessLevels.find({ user: id }) +const populatePermissions = async id => { + console.time("permission") + const userAccessLevels = await AccessLevels.find({ user: id }).select({club:1,level:1}).lean() + + console.timeEnd("permission") if(userAccessLevels===null){ throw new Error("User not found, Possibly outdated JWT") }else{ diff --git a/sources/package.json b/sources/package.json index 78da0d03..5096a751 100644 --- a/sources/package.json +++ b/sources/package.json @@ -28,7 +28,8 @@ "firebase-admin": "^9.4.2", "graphql": "^15.4.0", "graphql-iso-date": "^3.6.1", - "mongoose": "^5.11.10" + "mongoose": "^5.11.10", + "node-cache": "^5.1.2" }, "devDependencies": { "apollo-server-testing": "^2.19.2",