Your IP : 216.73.216.91


Current Path : /var/node/inatote/Inatote-Backend/users/
Upload File :
Current File : /var/node/inatote/Inatote-Backend/users/users-endpoint.js

import {
    UniqueConstraintError,
    InvalidPropertyError,
    RequiredParameterError,
    ApiTokenError,
    AuthorizationTokenError
} from '../helpers/errors.js'
import makeHttpError from '../helpers/http-error.js'
import makeUser from './user.js'
import jwt from 'jsonwebtoken'
import requiredParam from '../helpers/required-param.js'
import isValidEmail from '../helpers/is-valid-email.js'
import bycrypt from 'bcrypt'
import validateHeaders from '../helpers/validate-headers.js'
import config from '../config.js'
import FCM_Send from '../helpers/fcm_helper.js'
import sendSms from '../helpers/twilio-helper.js';
import { createCustomer, retrieveCustomer, createCustomerCard } from "../services/square.js";
import sendEmail from '../helpers/twilio-send_grid.js';
import fetch from 'node-fetch';
import logger from "../services/logService.js";
import date from "date-and-time";
const squareApplicationId = "sandbox-sq0idb-9k1xPDEQmzB-2-E75HXEcg";

export default function makeUsersEndpointHandler({ userList }) {
    return async function handle(httpRequest) {
        try {

            switch (httpRequest.method) {
                case 'POST':
                    return postuser(httpRequest)
                case 'GET':
                    return getUsers(httpRequest)

                case 'DELETE':
                    return deleteUser(httpRequest, httpRequest.user)

                case 'PUT':
                    return updateUser(httpRequest)

                case 'PATCH':
                    return replaceUser(httpRequest)

                default:
                    return makeHttpError({
                        statusCode: 405,
                        errorMessage: `${httpRequest.method} method not allowed.`
                    })
            }
        } catch (e) {
            console.log(e);
            return makeHttpError({
                errorMessage: e.message,
                statusCode: e instanceof ApiTokenError ||
                    e instanceof AuthorizationTokenError
                    ? 403
                    : 503
            })
        }
    }


    // todo
    async function updateKYCStatus(userInfo , httpRequest) {
        console.log("CALL");
        const { userId } = httpRequest.body || {}
        try {
            let query = {
                userId,
                user: httpRequest.body,
            }
            const result = await userList.update(query);
            console.log("RESULT" , result);
            if(result.user && result.user.KYCStatus == 'Verified' || result.user.KYCStatus == 'Rejected' ){
                FCM_Send({ notificationTitle: "KYC Status", notificationBody: `hi ${result.user.firstName}, Your KYC status has been ${result.user.KYCStatus} by Admin`, token: result.user.pushId, payload: {  }, type: "Rider" });
               
            }
            return {
                headers: {
                    'Content-Type': 'application/json'
                },

                statusCode: 200,
                data: JSON.stringify(result)
            }

        }
        catch (err) {
            console.log("errs", err);
            return {
                headers: {
                    'Content-Type': 'application/json'
                },
                statusCode: 400,
                data: JSON.stringify(err)
            }
        }

    }

    async function updateUser(httpRequest) {
        const { id } = httpRequest.pathParams || {}
        //console.log("httpRequest", httpRequest.file);
        try {
            let query = {
                userId: id,
                user: httpRequest.body,
            }
            if(httpRequest && httpRequest.file){
                query["image"] = httpRequest.file
            }
            const result = await userList.update(query);
            if(result.user && result.user)
            return {
                headers: {
                    'Content-Type': 'application/json'
                },

                statusCode: 200,
                data: JSON.stringify(result)
            }

        }
        catch (err) {
            //console.log("errs", err);
            return {
                headers: {
                    'Content-Type': 'application/json'
                },
                statusCode: 400,
                data: JSON.stringify(err)
            }
        }

    }


    // todo
    async function replaceUser() { }

    async function getUsers(httpRequest) {
        const { id } = httpRequest.pathParams || {}
        const { max, page, companyId, card, KYCStatus } = httpRequest.queryParams || {};


        const result = id
            ? await userList.findById({ userId: id })
            : await userList.getItems({ max, page, companyId, KYCStatus })

        let response = {};
        if (id && result && result.customer_id && card) {
            let userData = await retrieveCustomer(result.customer_id);
            let cards = userData.customer.cards
            response = { cards: cards ? cards : [], default: cards && cards.length > 0 ? cards.filter(f => f.id == result.cardId) : [], application_id: squareApplicationId }

        }
        else if (id && !result.customer_id && card) {
            let userObj = {
                "givenName": result.firstName,
                familyName: result.lastName,
                emailAddress: result.emailAddress,
                phoneNumber: result.mobileNumber,
                companyName: "Inatote",
                // idempotencyKey : id
            }
            let squareUser = await createCustomer(userObj);
            //console.log("square User", squareUser);
            const updatedResult = await userList.update({ userId: id, user: { customer_id: squareUser.customer.id } });

            response = { cards: [], default: [], application_id: squareApplicationId }

        }
        return {
            headers: {
                'Content-Type': 'application/json'
            },
            statusCode: 200,
            data: JSON.stringify(card ? response : result, (key, value) =>
                typeof value === "bigint" ? value.toString() + "n" : value
            )
        }
    }


    async function deleteUser(httpRequest, userSession) {
        const { id } = httpRequest.pathParams || {}
        const { address } = httpRequest.queryParams || {}
        //console.log(userSession);
        if (!(userSession.userType == "Admin" || userSession.userType == "Vendor")) {
            return makeHttpError({
                statusCode: 403,
                errorMessage: `Access not granted.`
            })
        }

        const result = await userList.remove({ userId: id })

        return {
            headers: {
                'Content-Type': 'application/json'
            },
            statusCode: 200,
            data: JSON.stringify(result)
        }
    }

    async function postuser(httpRequest) {
        let userInfo = httpRequest.body
        // //console.log("userinfo", httpRequest);
        if (!userInfo) {
            return makeHttpError({
                statusCode: 401,
                errorMessage: 'Bad request. No POST body.'
            })
        }

        if (typeof httpRequest.body === 'string') {
            try {
                userInfo = JSON.parse(userInfo)
            } catch {
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: 'Bad request. POST body must be valid JSON.'
                })
            }
        }
        console.log("http", httpRequest.path);
        try {
            switch (httpRequest.path) {
                case '/users/updateKYCStatus':
                    return  updateKYCStatus(userInfo ,httpRequest )
                case '/users':
                    return addUser(userInfo, httpRequest.user, httpRequest.file)
                case '/users/login':
                    return login(userInfo , httpRequest)
                case '/users/register':
                    return registerUser(userInfo, httpRequest.file)
                case '/users/registerAdmin':
                    return registerAdmin(userInfo)
                case '/users/verifyUser':
                    return verifyUser(userInfo)
                case '/users/verifyRiderLicense':
                    return verifyRiderLicense(httpRequest, userInfo)
                case '/users/updateProfilePicture':
                    return updateProfilePicture(httpRequest, userInfo);
                case '/users/card':
                    return createSquareUserCard(httpRequest, userInfo);
                case '/users/sendCode':
                    return sendCode(httpRequest, userInfo);
                case '/users/changePassword':
                    return changePassword(httpRequest, userInfo);
                case '/users/forgotPassword':
                    return forgotPassword(httpRequest, userInfo);
                case '/users/updatePassword':
                    return updatePassword(httpRequest , userInfo)
                case '/users/createCardHolder':
                    return createCardHolder(httpRequest , userInfo)
                case '/users/berkleyCards':
                    return berkleyCards(httpRequest , userInfo)
                case '/users/activateCard':
                    return activateCard(httpRequest , userInfo)
                case '/users/updateCard':
                    return updateCard(httpRequest , userInfo)
                case '/users/validateOTP':
                    return loginAsCode(userInfo ,httpRequest )
                
                                            
    
                default:
                    return makeHttpError({
                        statusCode: 404,
                        errorMessage: `${httpRequest.path} not found.`
                    })

            }
        } catch (e) {
            return makeHttpError({
                errorMessage: e.message,
                statusCode: e instanceof ApiTokenError ||
                    e instanceof AuthorizationTokenError
                    ? 403
                    : 500
            })
        }


    }


    async function createCardHolder(httpRequest , userInfo){
        try{
            let user = await userList.findByEmailAndUserType({_id : httpRequest.body.userId });
            console.log("user" , user );
            if(!user.address){
                throw 'user address details are missing'
            }
            var b_date = user && user.DOB ? new Date(user.DOB) : new Date();
            console.log("DATE", b_date);
            let data_body = {
                "program_id": 273,
                "external_tag": "inatote1",
                "first_name": user.firstName,
                "last_name": user.lastName,
                "email": user.emailAddress,
                "phone": user.mobileNumber.startsWith("+")? user.mobileNumber.slice(1 , (user.mobileNumber.length) -2 ) : user.mobileNumber,
                "postal_code": user.address && user.address.postalCode || '12345',
                "city": user.address && user.address.city || 'abc',
                "state": user.address && user.address.stateCode || "NY",
                "address1": user.address &&  user.address.unitNumber || "dummy address",
                "address": user.address &&  user.address.street || "dummy address",
                "shipping_method":"3",
                "country":"840" ,
                "date_of_birth": date.format(b_date , 'DD-MM-YYYY') 
            }
            console.log("cardholders" , data_body);
            
            const response = await fetch(`${config.app.berkleyURL}/card_issuing/cardholders`, {
                method: 'POST',
                body: JSON.stringify(data_body),
                headers: {'Content-Type': 'application/json' ,
                         'Authorization': 'Bearer 0VIbHArxZBWKp5y6PT3eCjFkDJuGz7sqcMLO1oavt4ilmUfw2EX',
                         'Accept': 'application/json'    }
            });
            const data = await response.json();
            console.log("data", data);
            if(data.error){
                throw data.error.field_errors
            }
            else{

            
            const accResponse = await fetch(`${config.app.berkleyURL}/card_issuing/accounts?processor_reference=${data.data.primary_processor_reference}`, {
                method: 'GET',
                headers: {'Content-Type': 'application/json' ,
                         'Authorization': 'Bearer 0VIbHArxZBWKp5y6PT3eCjFkDJuGz7sqcMLO1oavt4ilmUfw2EX',
                         'Accept': 'application/json'    }
            });
            const accData = await accResponse.json();
            console.log("accData" , accData.data);
            let updatedUser = {...user}
            updatedUser.berkleyCardHolderId = accData.data.cardholder_id;
            updatedUser.berkleyAccountId = accData.data.id;
            updatedUser.address = updatedUser.address._id;
            
            
            console.log("updatedUser" , updatedUser);
            let updateUser = await userList.update({userId: updatedUser.userId,user: updatedUser});
            console.log("updateUser" , updateUser);
            

            return {
                headers: {
                    'Content-Type': 'application/json'
                },
                statusCode: 201,
                data: data
            }
        }

        }   
        catch(e){
            console.log("e" , e);
            return makeHttpError({
                errorMessage: e && e.message || e || "Something went wrong",
                statusCode: e instanceof ApiTokenError ||
                    e instanceof AuthorizationTokenError
                    ? 403
                    : 500
            })
        }
    } 

    async function changePassword(httpRequest , userInfo){
        try{

        let user = await userList.findById({userId : httpRequest.body.userId });
        let checkOldPassword = await bycrypt.compareSync(httpRequest.body.oldPassword, user.password);
        if(checkOldPassword){
            let genPassword = await bycrypt.hash(httpRequest.body.newPassword, 10);
            let updateuser = await userList.update({userId:httpRequest.body.userId , user : {password : genPassword} });
            // console.log("updateuser" , updateuser);
        }else{
            throw 'old password is wrong'
        }
        return {
            headers: {
                'Content-Type': 'application/json'
            },
            statusCode: 201,
            data: {msg:"Updated successfully"}
        }
        }
        catch(e){
            console.log(e);
            return makeHttpError({
                errorMessage: e.message? e.message : e,
                statusCode: e instanceof ApiTokenError ||
                    e instanceof AuthorizationTokenError
                    ? 403
                    : 500
            })
        }
        

    }

    async function updatePassword(httpRequest , userInfo){
        try{

        let user = await userList.findByCode({forgotPasswordCode : httpRequest.body.code });
        console.log("USER" , user , httpRequest.body);
        // let checkOldPassword = await bycrypt.compareSync(httpRequest.body.oldPassword, user.password);
        if(user){
            let genPassword = await bycrypt.hash(httpRequest.body.password, 10);
            let updateuser = await userList.update({userId:user.userId , user : {password : genPassword , forgotPasswordCode: null  } });
            // console.log("updateuser" , updateuser);
        }else{
            throw 'Code is incorrect'
        }
        return {
            headers: {
                'Content-Type': 'application/json'
            },
            statusCode: 201,
            data: {msg:"Updated successfully"}
        }
        }
        catch(e){
            console.log(e);
            return makeHttpError({
                errorMessage: e.message? e.message : e,
                statusCode: e instanceof ApiTokenError ||
                    e instanceof AuthorizationTokenError
                    ? 403
                    : 500
            })
        }
        

    }

    async function sendCode(httpRequest, userInfo) {
        try {
            let smsCode = Math.floor(100000 + Math.random() * 900000);
            let emailCode = Math.floor(100000 + Math.random() * 900000);
            let MFType = httpRequest.body.MFType ? httpRequest.body.MFType : "Both" ;

            let data = {};
            if(MFType == "Email") data = {emailCode}; 
            if(MFType == "Phone") data = {smsCode}
            if( MFType == "Both") data = {emailCode, smsCode}
            
            let updateUser = await userList.update({ userId: httpRequest.body.userId, user: {...data ,MFType } });
            let user = await userList.findById({ userId: httpRequest.body.userId });
            
            if (user && user.mobileNumber && (MFType == "Phone" || MFType == "Both")) {
                console.log("smsCode====", smsCode);
                await sendSms({ toNumber: user.mobileNumber, message: `Welcome to Inatote Family \n please use this code ${smsCode} to verify your account` });
            }
            if(user && user.emailAddress && (MFType == "Email" || MFType == "Both")){
                await sendEmail({ senderMail: user.emailAddress, text:`Welcome to Inatote Family \n please use this code ${emailCode} to verify your account`  });
                console.log("emailCode====" , emailCode);
            }
            
            return {
                headers: {
                    'Content-Type': 'application/json'
                },
                statusCode: 200,
                data: JSON.stringify({ msg: "code has been successfully sended" })
                // JSON.stringify(createCard)
            }
        }
        catch (err) {

            console.log("err", err);
            return makeHttpError({
                statusCode: 400,
                errorMessage: err.message
            })
        }
    }

    async function registerUser(userInfo, filePath) {
        //console.log("usrer", userInfo);
        try {
            if (!(userInfo.userType == "Client" || userInfo.userType == "Rider")) {
                return makeHttpError({
                    statusCode: 403,
                    errorMessage: `Access not granted.`
                })
            }

            if (userInfo.userType == "Rider" && (userInfo.postalCode == "")) {
                return makeHttpError({
                    statusCode: 503,
                    errorMessage: `Postal code is required for rider registration`
                })
            }

            let query = {
                emailAddress: userInfo.emailAddress,
                userType: userInfo.userType
            }
            let check_user = await userList.findByEmailAndUserType(query);
            console.log("check_user", check_user);
            if(check_user && !check_user.emailVerified ){
                const del_user = await userList.remove({ userId: check_user.userId }) ;
                console.log("dlet_user", del_user);  
            }
            if (check_user && check_user.emailVerified) {
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: "Email Already exsists"
                })
            }
            let query_for_mobile = {
                mobileNumber: userInfo.mobileNumber,
                userType: userInfo.userType
            }
            let check_user_mobile = await userList.findByMobile(query_for_mobile);
            console.log("check_user_mobile", check_user_mobile);
            if(check_user_mobile && !check_user_mobile.mobileVerified  ){
                const del_user_2 = await userList.remove({ userId: check_user_mobile.userId }) ;
                console.log("del_user", del_user_2);  
                
            }
            if (check_user_mobile && check_user_mobile.mobileVerified) {
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: "Mobile Number Already exsists"
                })
            }



            userInfo.password = await bycrypt.hash(userInfo.password, 10);
            // userInfo.mobileNumber = "+92" + userInfo.mobileNumber;

            userInfo['imageURL'] = filePath === undefined ? "" : filePath.path;
            userInfo['emailVerified'] = false;
            userInfo['mobileVerified'] = false;


            if (userInfo.userType == "Rider") {
                userInfo["KYCStatus"] = "Not Started";
            }

            //console.log("code", userInfo["smsCode"], userInfo["emailCode"]);

            const user = makeUser(userInfo)
            const result = await userList.add(user);
            //console.log("userdeerr", user);
            var token = jwt.sign({
                data: {
                    userId: result.userId,
                    userType: result.userType
                }
            }, 'secret', { expiresIn: '30d' });

            return {
                headers: {
                    'Content-Type': 'application/json'
                },
                statusCode: 201,
                data: JSON.stringify({...result , token})
            }
        } catch (e) {
            console.log("err", e);
            return makeHttpError({
                errorMessage: e.message,
                statusCode:
                    e instanceof UniqueConstraintError
                        ? 409
                        : e instanceof InvalidPropertyError ||
                            e instanceof RequiredParameterError
                            ? 400
                            : 500
            })
        }
    }


    async function registerAdmin(userInfo) {

        try {
            if (userInfo.userType != "Admin") {
                return makeHttpError({
                    statusCode: 503,
                    errorMessage: `Access not granted.`
                })
            }

            let query = {
                emailAddress: userInfo.emailAddress,
                userType: userInfo.userType
            }
            let check_user = await userList.findByEmailAndUserType(query);
            
            if (check_user) {
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: "Email Already exsists"
                })
            }

            userInfo.password = await bycrypt.hash(userInfo.password, 10)
            const user = makeUser(userInfo)
            const result = await userList.add(user)


            return {
                headers: {
                    'Content-Type': 'application/json'
                },
                statusCode: 201,
                data: JSON.stringify(result)
            }
        } catch (e) {
            return makeHttpError({
                errorMessage: e.message,
                statusCode:
                    e instanceof UniqueConstraintError
                        ? 409
                        : e instanceof InvalidPropertyError ||
                            e instanceof RequiredParameterError
                            ? 400
                            : 503
            })
        }
    }


    async function verifyUser(userInfo) {

        try {
            if (userInfo.userId == "" || userInfo.code == "") {
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: `UserId and Code are required`
                })
            }


            let check_user = await userList.findById({ userId: userInfo.userId });
            
            let output = {}
            if(check_user && check_user.MFType == "Email") output = { emailValidation: check_user.emailVerified}
            if(check_user && check_user.MFType == "Phone") output = { mobileValidation: check_user.mobileVerified}
            if(check_user && check_user.MFType == "Email") output = { emailValidation: check_user.emailVerified , mobileValidation: check_user.mobileVerified}
            //console.log("check_user", output);
            output["MFType"] = check_user.MFType;

            if (userInfo.smsCode && !output.mobileValidation) {


                if (check_user && check_user.smsCode != userInfo.smsCode) {
                    return makeHttpError({
                        statusCode: 400,
                        errorMessage: "Wrong code"
                    })
                }

                var result = await userList.update({
                    userId: userInfo.userId, user: {
                        mobileVerified: true,
                        smsCode: null
                    }
                })
                output["mobileValidation"] = true
            }
            if (userInfo.emailCode && !output.emailValidation ) {
                if (check_user && check_user.emailCode != userInfo.emailCode) {
                    return makeHttpError({
                        statusCode: 400,
                        errorMessage: "Wrong code"
                    })
                }
                var result = await userList.update({
                    userId: userInfo.userId, user: {
                        emailVerified: true,
                        emailCode: null
                    }
                })

                output["emailValidation"] = true

            }

            return {
                headers: {
                    'Content-Type': 'application/json'
                },
                statusCode: 201,
                data: JSON.stringify(output)
            }
        } catch (e) {
            return makeHttpError({
                errorMessage: e.message,
                statusCode:
                    e instanceof UniqueConstraintError
                        ? 409
                        : e instanceof InvalidPropertyError ||
                            e instanceof RequiredParameterError
                            ? 400
                            : 503
            })
        }
    }


    async function login(userInfo, httpRequest) {
        try {
            if (userInfo.emailAddress == undefined || userInfo.password == undefined || userInfo.userType == undefined) {
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: `Bad request.`
                })
            }

            if (!isValidEmail(userInfo.emailAddress)) {
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: `Bad request Invalid Email.`
                })
            }
            
            //console.log("***********************************")
            const result = await userList.findByEmailAndUserType({ emailAddress: userInfo.emailAddress , userType: userInfo.userType })
            console.log("RES" , result);
            if (!result) {
                return makeHttpError({
                    statusCode: 404,
                    errorMessage: `User's credentials are invalid`
                })
            }

            var res = await bycrypt.compare(userInfo.password, result.password)


            if (!res) {
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: `Invalid credentials.`
                })
            }
            
            let MFType = "Both";
            if(result.userType == "Vendor"){
                MFType = "Email"
            }

            if (result && ((MFType == "Both" && (result.emailVerified == false || result.mobileVerified == false)) ||
            (MFType == "Email" && (result.emailVerified == false )))) {
                let codeResponse = await  sendCode({body:{...httpRequest.body , userId :result.userId , MFType }} , userInfo)
                if(codeResponse.statusCode == 200){
                    let responseObj = {
                        statusCode: 400,
                        errorMessage: MFType == "Both" ? `Email or mobile number is not verified`: MFType == "Email" ? "Email is not verified" : "Phone is not verified",
                        userId: result.userId
                    }
                    if(MFType == "Email"){
                        responseObj = {...responseObj ,emailVerified : result.emailVerified }
                    }
                    else if(MFType == "Both"){
                        responseObj = {...responseObj ,emailVerified : result.emailVerified ,mobileVerified : result.mobileVerified }
                    }
                    return  makeHttpError(responseObj);
                }
                else{
                    return  makeHttpError({
                        statusCode: 400,
                        errorMessage: JSON.parse(codeResponse.data).error
                    })
                }
                
            }
            if(result && !result.isEnabled){
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: `This user has been blocked`
                })
            }

            // if(result && ){
            //     return makeHttpError({
            //         statusCode: 400,
            //         errorMessage: `User mobile Number is not verified yet`
            //     })
            // }
            // result["pushId"] = userInfo.pushId
            let address = result.address ? result.address : {}

            let user = { ...result, pushId: userInfo.pushId, address: result.address && result.address._id ? result.address._id : null }
            //console.log("address", user);
            var token = jwt.sign({
                data: {
                    userId: user.userId,
                    userType: user.userType
                }
            }, 'secret', { expiresIn: '30d' });

            var updatedUser = await userList.update({ userId: user.userId, user: user });
            //console.log("updatedUser", updatedUser);

            var obj = Object.assign({}, updatedUser.user, user, { address: address, cardId: null });
            // logger.infologger.info(JSON.stringify({...obj , token: token}))
            infoLogs(httpRequest , {
                user: obj,
                token: token
            })
            // FCM_Send({ notificationTitle: "Login Successfully", notificationBody: "Thanks for logging in", token: obj.pushId, type: user.userType });

            return {
                headers: {
                    'Content-Type': 'application/json'
                },
                statusCode: 200,
                data: {
                    user: obj,
                    token: token
                }
            }
        } catch (err) {
            console.log("err", err);
            return makeHttpError({
                statusCode: 400,
                errorMessage: err
            })
        }

    }


    async function loginAsCode(userInfo, httpRequest) {
        try {
            
            if (userInfo.emailCode == undefined ) {
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: `Bad request.`
                })
            }

           
            console.log("***********************************" , userInfo)
            // const result = await userList.getByCode({ emailCode: parseInt(userInfo.emailCode) , smsCode : parseInt(userInfo.phoneCode)  })
            const result = await userList.getByCode({emailCode:parseInt(userInfo.emailCode) })
            
            console.log("RES" , result , userInfo);
            if (!result) {
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: `OTP is not valid`
                })
            }

            if (result ) {
            let address = result.address ? result.address : {}

            let user = { ...result, pushId: userInfo.pushId, address: result.address && result.address._id ? result.address._id : null }
            console.log("user" , user);
            var token = jwt.sign({
                data: {
                    userId: user._id,
                    userType: user.userType
                }
            }, 'secret', { expiresIn: '30d' });

            var updatedUser = await userList.update({ userId: user._id, user: {...user , emailVerified: true , mobileVerified: false} });
            var obj = Object.assign({}, updatedUser.user, user, { address: address, cardId: null });
            console.log("obj" ,obj);
            infoLogs(httpRequest , {
                user: obj,
                token: token
            })
            return {
                headers: {
                    'Content-Type': 'application/json'
                },
                statusCode: 200,
                data: {
                    user: obj,
                    token: token
                }
            }
        }
        } catch (err) {
            console.log("err", err);
            return makeHttpError({
                statusCode: 400,
                errorMessage: err,
                headers: {
                    'Content-Type': 'application/json'
                },
            })
        }

    }


    function infoLogs(req , res) {
        let msg = `\n*********${req.method}*${req.originalurl}********************************************************************************
        \n ${JSON.stringify(req.body)} \n ${JSON.stringify(res)}
        \n **********************************************************************************************************************************`;
        console.log("msg" , msg);
        logger.infologger.info(msg)
            
    }

    async function addUser(userInfo, userSession, filePath) {
        //console.log("userInfo", userInfo, userSession)
        try {
            if (!(userInfo.userType == "Admin" || userInfo.userType == "Vendor")) {
                //console.log(userSession)
                return makeHttpError({
                    statusCode: 403,
                    errorMessage: `Access not granted.`
                })
            }
            if (userSession.userType == "Vendor" && userInfo.userType != "Vendor") {
                return makeHttpError({
                    statusCode: 403,
                    errorMessage: `Access not granted.`
                })
            }

            if (userInfo.userType == "Vendor" && userInfo.companyId == undefined) {
                return makeHttpError({
                    statusCode: 403,
                    errorMessage: `Please provide complete information to add user in the system.`
                })
            }
            let query = {
                emailAddress: userInfo.emailAddress,
                userType: userInfo.userType
            }
            let check_user = await userList.findByEmailAndUserType(query)
            if (check_user) {
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: "Email Already exsists"
                })
            }

            userInfo.password = await bycrypt.hash(userInfo.password, 10)
            userInfo.emailVerified = false;
            userInfo.mobileVerified = false;
            
            //console.log("filepath", filePath);

            // imageURL field added from request.file
            userInfo['imageURL'] = filePath === undefined ? "" : filePath.path;

            const user = makeUser(userInfo)
            const result = await userList.add(user)

            return {
                headers: config.app.headers,
                statusCode: 201,
                data: JSON.stringify(result)
            }
        } catch (e) {
            return makeHttpError({
                errorMessage: e.message,
                statusCode:
                    e instanceof UniqueConstraintError
                        ? 409
                        : e instanceof InvalidPropertyError ||
                            e instanceof RequiredParameterError
                            ? 400
                            : 500
            })
        }
    }

    async function verifyRiderLicense(userInfo, userData) {
        try {

            let files = userData.files;
            if (!userData.userId || userData.userId == "") {
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: "userId is required"
                })
            }
            if (files && files.length != 3) {
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: "License front and back photographs are required with user image in series"
                })
            }
            else {
                let file_path = files;
                //console.log("httpRequest", file_path, files);
                let updateRider = {
                    licenseFront: file_path[0],
                    licenseBack: file_path[1],
                    imageURL: file_path[2],
                    KYCStatus: "Pending"
                }

                const result = await userList.update({ userId: userData.userId, user: updateRider });
                //console.log("res", result);
                

                return {
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    statusCode: 200,
                    data: { msg: "License has been uploaded successfully" }
                }

            }


        } catch (err) {
            //console.log(err);
            return makeHttpError({
                statusCode: 400,
                errorMessage: err
            })
        }
    }

    async function updateProfilePicture(httpRequest) {
        try {
            // //console.log(httpRequest);
            const result = await userList.update({ userId: httpRequest.user.userId, user: httpRequest.user, image: httpRequest.file })

            //console.log(result);

            return {
                headers: {
                    'Content-Type': 'application/json'
                },
                statusCode: 200,
                data: {
                    msg: "Profile picture updated successfully"
                }
            }
        } catch (error) {
            return makeHttpError({
                statusCode: 400,
                errorMessage: error
            })
        }
    }

    async function createSquareUserCard(httpRequest, userInfo) {
        try {
            //console.log("user", userInfo);

            if (!userInfo || !userInfo.userId) {
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: 'UserId is required'
                })
            }

            if (!userInfo.nonce) {
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: 'nonce is required'
                })
            }

            let user = await userList.findById({ userId: userInfo.userId })
            if (!user && !user.customer_id) {
                return makeHttpError({
                    statusCode: 400,
                    errorMessage: 'Create square usert first'
                })
            }
            //console.log(user.userId, userInfo.nonce);
            let createCard = await createCustomerCard(user.customer_id, userInfo.nonce);
            //console.log("create card", createCard);

            if (createCard.card && createCard.card.id) {
                let updateUser = await userList.update({ userId: user.userId, user: { cardId: createCard.card.id } });
            }

            return {
                headers: {
                    'Content-Type': 'application/json'
                },
                statusCode: 200,
                data: JSON.stringify(createCard, (key, value) =>
                    typeof value === "bigint" ? value.toString() + "n" : value
                )
                // JSON.stringify(createCard)
            }
        }
        catch (error) {
            //console.log("err", error);
            return makeHttpError({
                statusCode: 400,
                errorMessage: error
            })
        }
    }

    async function forgotPassword(httpRequest, userInfo) {
        try {
            let emailCode = Math.floor(100000 + Math.random() * 900000);

            let data = {
                forgotPasswordCode: emailCode
            }
            let user = await userList.findByEmail({ emailAddress: userInfo.emailAddress });
            if(!user){
                throw "emailAddress not found"
            }
            let updateUser = await userList.update({ userId: user.userId, user: data });
            
            if(user.emailAddress){
                try{
               var emailStatus =  await sendEmail({ senderMail: user.emailAddress, text:`Welcome to Inatote Family \n please use this code ${emailCode} to change password of your account`  });
            }
            catch(err){
                throw "emailAddress not found"
            }
            }
            // code for mail

            return {
                headers: {
                    'Content-Type': 'application/json'
                },
                statusCode: 200,
                data: JSON.stringify({ msg: "code has been successfully sended"   })
                // JSON.stringify(createCard)
            }
        }
        catch (err) {

            console.log("err", err);
            return makeHttpError({
                statusCode: 400,
                errorMessage: err
            })
        }
    }

    async function berkleyCards(httpRequest , userInfo){
        try{
            console.log("user",httpRequest.body.userId );
            let user = await userList.findByEmailAndUserType({_id : httpRequest.body.userId });
            console.log("USER" , user);
            if(user && !user.hasOwnProperty("berkleyCardHolderId") ){
                return {
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    statusCode: 201,
                    data: {}
                }
            }
            const CardResponse = await fetch(`${config.app.berkleyURL}/card_issuing/cardholders/${user.berkleyCardHolderId}`, {
                method: 'GET',
                headers: {'Content-Type': 'application/json' ,
                         'Authorization': 'Bearer 0VIbHArxZBWKp5y6PT3eCjFkDJuGz7sqcMLO1oavt4ilmUfw2EX',
                         'Accept': 'application/json'    }
            });
            const data = await CardResponse.json();

            return {
                headers: {
                    'Content-Type': 'application/json'
                },
                statusCode: 201,
                data: data.data &&  data.data.accounts  && data.data.accounts.length > 0 ? data.data.accounts[0] : {} 
            }
        }   
        catch(e){
            console.log("e" , e);
            return makeHttpError({
                errorMessage: e.message || e,
                statusCode: e instanceof ApiTokenError ||
                    e instanceof AuthorizationTokenError
                    ? 403
                    : 400
            })
        }
    }

    async function activateCard(httpRequest , userInfo){
        try{
            
            const CardResponse = await fetch(`${config.app.berkleyURL}/card_issuing/accounts/activate_card`, {
                method: 'POST',
                body: JSON.stringify(httpRequest.body),
                headers: {'Content-Type': 'application/json' ,
                         'Authorization': 'Bearer 0VIbHArxZBWKp5y6PT3eCjFkDJuGz7sqcMLO1oavt4ilmUfw2EX',
                         'Accept': 'application/json'    }
            });
            const data = await CardResponse.json();
            console.log("CardResponse" ,CardResponse);
            if(CardResponse.status != 201){
                throw  data.error   
            }
            return {
                headers: {
                    'Content-Type': 'application/json'
                },
                statusCode: 201,
                data: data
            }
        }   
        catch(e){
            console.log("e" , e);
            return makeHttpError({
                errorMessage: e.message || e,
                statusCode: e instanceof ApiTokenError ||
                    e instanceof AuthorizationTokenError
                    ? 403
                    : 400
            })
        }
    }

    async function updateCard(httpRequest , userInfo){
        try{
            
            const CardResponse = await fetch(`${config.app.berkleyURL}/card_issuing/accounts/${httpRequest.body.cardId}`, {
                method: 'POST',
                body: JSON.stringify(httpRequest.body),
                headers: {'Content-Type': 'application/json' ,
                         'Authorization': 'Bearer 0VIbHArxZBWKp5y6PT3eCjFkDJuGz7sqcMLO1oavt4ilmUfw2EX',
                         'Accept': 'application/json'    }
            });
            const data = await CardResponse.json();
            console.log("CardResponse" ,CardResponse);
            if(CardResponse.status != 201){
                throw  data.error   
            }
            return {
                headers: {
                    'Content-Type': 'application/json'
                },
                statusCode: 201,
                data: data
            }
        }   
        catch(e){
            console.log("e" , e);
            return makeHttpError({
                errorMessage:   e || e && e.message || 'something went wrong',
                statusCode: e instanceof ApiTokenError ||
                    e instanceof AuthorizationTokenError
                    ? 403
                    : 400
            })
        }
    }
}