From 617c6357cd60535b285db475c6f8ab67b3577d67 Mon Sep 17 00:00:00 2001 From: Jacqueline Tuyisenge Date: Wed, 23 Oct 2024 13:55:22 +0200 Subject: [PATCH] fix(#404): Getting the Client's Ip Adress using request_ip package --- package-lock.json | 16 ++++++++++++++++ package.json | 2 ++ src/context.ts | 8 +++++++- src/resolvers/userResolver.ts | 31 ++++++++++++++++++------------- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 169d05ee..ebb8b367 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,6 +38,7 @@ "node-fetch": "^2.6.12", "nodemailer": "^6.7.8", "normalize-mongoose": "^1.0.0", + "request-ip": "^3.3.0", "ts-node-dev": "^2.0.0", "tslog": "^4.9.2", "ws": "^8.11.0", @@ -55,6 +56,7 @@ "@types/node": "^13.13.52", "@types/node-fetch": "^2.6.4", "@types/nodemailer": "^6.4.6", + "@types/request-ip": "^0.0.41", "@types/ws": "^8.5.10", "@types/xlsx": "^0.0.35", "@typescript-eslint/eslint-plugin": "^4.0.1", @@ -3095,6 +3097,15 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, + "node_modules/@types/request-ip": { + "version": "0.0.41", + "resolved": "https://registry.npmjs.org/@types/request-ip/-/request-ip-0.0.41.tgz", + "integrity": "sha512-Qzz0PM2nSZej4lsLzzNfADIORZhhxO7PED0fXpg4FjXiHuJ/lMyUg+YFF5q8x9HPZH3Gl6N+NOM8QZjItNgGKg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/send": { "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", @@ -7709,6 +7720,11 @@ "node": ">=4" } }, + "node_modules/request-ip": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/request-ip/-/request-ip-3.3.0.tgz", + "integrity": "sha512-cA6Xh6e0fDBBBwH77SLJaJPBmD3nWVAcF9/XAcsrIHdjhFzFiB5aNQFytdjCGPezU3ROwrR11IddKAM08vohxA==" + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", diff --git a/package.json b/package.json index ee4ed910..ae82d47c 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,7 @@ "node-fetch": "^2.6.12", "nodemailer": "^6.7.8", "normalize-mongoose": "^1.0.0", + "request-ip": "^3.3.0", "ts-node-dev": "^2.0.0", "tslog": "^4.9.2", "ws": "^8.11.0", @@ -99,6 +100,7 @@ "@types/node": "^13.13.52", "@types/node-fetch": "^2.6.4", "@types/nodemailer": "^6.4.6", + "@types/request-ip": "^0.0.41", "@types/ws": "^8.5.10", "@types/xlsx": "^0.0.35", "@typescript-eslint/eslint-plugin": "^4.0.1", diff --git a/src/context.ts b/src/context.ts index 2c15d436..f426451c 100644 --- a/src/context.ts +++ b/src/context.ts @@ -2,6 +2,7 @@ import { GraphQLError } from 'graphql' import 'dotenv/config' import { Request } from 'express' import * as jwt from 'jsonwebtoken' +import requestIp from 'request-ip' const SECRET = process.env.SECRET || 'test_secret' @@ -34,6 +35,7 @@ export function decodeAuthHeader(authHeader: string): AuthTokenPayload { export interface Context { userId?: string role?: string + clientIpAdress?: string } export const context = async ({ req }: { req: Request }): Promise => { @@ -41,16 +43,20 @@ export const context = async ({ req }: { req: Request }): Promise => { req && req.headers.authorization ? decodeAuthHeader(req.headers.authorization) : null + + //get Ip + const clientIpAdress = requestIp.getClientIp(req) || undefined if ( !token && !req.body.variables.organisationInput && !req.body.variables.loginInput ) { - return {} + return { clientIpAdress } } else { return { userId: token?.userId, role: token?.role, + clientIpAdress, } } } diff --git a/src/resolvers/userResolver.ts b/src/resolvers/userResolver.ts index c3bfeb67..eee3d413 100644 --- a/src/resolvers/userResolver.ts +++ b/src/resolvers/userResolver.ts @@ -46,11 +46,11 @@ enum Status { rejected = 'rejected', } -async function logGeoActivity(user: any) { - const ipResponse = await fetch('https://api.ipify.org?format=json') - const { ip: realIp } = await ipResponse.json() +async function logGeoActivity(user: any, clientIpAdress: string) { + // const ipResponse = await fetch('https://api.ipify.org?format=json') + // const { ip: realIp } = await ipResponse.json() - const response = await fetch(`https://ipapi.co/${realIp}/json/`) + const response = await fetch(`https://ipapi.co/${clientIpAdress}/json/`) const geoData = await response.json() const profile = await Profile.findOne({ user: user._id }) @@ -62,7 +62,7 @@ async function logGeoActivity(user: any) { profile.activity.push({ country_code: geoData.country_code, country_name: geoData.country_name, - IPv4: realIp, + IPv4: clientIpAdress, city: geoData.city, state: geoData.region, postal: geoData.postal, @@ -334,8 +334,13 @@ const resolvers: any = { async loginUser( _: any, - { loginInput: { email, password, orgToken } }: any + { loginInput: { email, password, orgToken } }: any, + context: any ) { + const { clientIpAdress } = context + + console.log('clientIpAdress: ', clientIpAdress) + // get the organization if someone logs in const org: InstanceType = await checkLoggedInOrganization(orgToken) @@ -392,7 +397,7 @@ const resolvers: any = { if (await isAssigned(org?.name, user._id)) { const token = generateToken(user._id, user._doc?.role || 'user') - const geoData = await logGeoActivity(user) + const geoData = await logGeoActivity(user, clientIpAdress) const data = { token: token, @@ -412,7 +417,7 @@ const resolvers: any = { if (user.cohort && user.team) { const token = generateToken(user._id, user._doc?.role || 'user') - const geoData = await logGeoActivity(user) + const geoData = await logGeoActivity(user, clientIpAdress) const data = { token: token, @@ -433,7 +438,7 @@ const resolvers: any = { if (user?.organizations?.includes(org?.name)) { const token = generateToken(user._id, user._doc?.role || 'user') - const geoData = await logGeoActivity(user) + const geoData = await logGeoActivity(user, clientIpAdress) const data = { token: token, @@ -465,7 +470,7 @@ const resolvers: any = { user._doc?.role || 'user' ) - const geoData = await logGeoActivity(user) + const geoData = await logGeoActivity(user, clientIpAdress) const managerData = { token: managerToken, @@ -503,7 +508,7 @@ const resolvers: any = { user._doc?.role || 'user' ) - const geoData = await logGeoActivity(user) + const geoData = await logGeoActivity(user, clientIpAdress) const coordinatorData = { token: coordinatorToken, @@ -520,12 +525,12 @@ const resolvers: any = { user._doc?.role || 'user' ) - const geoData = await logGeoActivity(user) + // const geoData = await logGeoActivity(user, clientIpAdress) const superAdminData = { token: superAdminToken, user: user.toJSON(), - geoData, + // geoData, } return superAdminData } else {