front/controllers/user/index.js

/* ============================================================================ *\
|| ########################################################################## ||
|| # Auction Software Marketplace          Release: 0.6   Build 0.7         # ||
|| # ---------------------------------------------------------------------- # ||
|| # License # 35YAHCNR9344X6O666C123AB                                     # ||
|| # ---------------------------------------------------------------------- # ||
|| # Copyright ©2014–2021 Develop Scripts LLC. All Rights Reserved          # ||
|| # This file may not be redistributed in whole or significant part.       # ||
|| # ------------- AUCTION SOFTWARE IS NOT FREE SOFTWARE ------------------ # ||
|| # http://www.auctionsoftwaremarketplace.com|support@auctionsoftware.com  # ||
|| # ---------------------------------------------------------------------- # ||
|| ########################################################################## ||
\* ============================================================================ */

const md5 = require('md5')
const jwt = require('jsonwebtoken')
let config = require('config')
const userModule = require('../../modules/user').default
const cryptosFunction = require('../../../common/cryptos')
const commonFunction = require('../../../common/function').default
const sendgridModule = require('../../../common/thirdparty/sendgrid').default
const twilioModule = require('../../../common/thirdparty/twilio').default
const schemaModule = require('./schema').default

const kountCtrl = require('../kount')

config = config.get('JwtToken')

const { jsonResponse } = require('../logger')
/**
 * update profile function
 *
 * @memberOf frontend.user
 * @param {object} req request object
 */
const updateProfileFunction = async (req) => {
    await Promise.all([userModule.updateProfile(req, req.body)])
    if (global.configColumns.custom_users.enabled) {
        console.log('custom user', req.body)
        await Promise.all([userModule.updateCustomUsersProfile(req, req.body)])
    }
    return true
}
/**
 * send sms trigger
 *
 * @memberOf frontend.user
 * @param {object} req request object
 * @param {string} tosms mobile number to sms
 */
const sendsmstrigger = async (data, tosms) => {
    const accountSid = global.smstwo.sid
    const authToken = global.smstwo.token
    const twilioNumber = global.smstwo.from
    const client = require('twilio')(accountSid, authToken)
    client.messages.create(
        {
            body: data,
            to: tosms,
            from: twilioNumber,
        },
        async (err, message) => {
            return true
        },
    )
}
/**
 * update profile function
 *
 * @memberOf frontend.user
 * @param {string} itmes multiple address
 * @param {userModule.getMultipleAddress} module
 */
const attachMultipleAddress = async (items) => {
    const itemsChanged = []
    const attachAddress = async (item) => {
        const itemInside = item
        const [detail] = await Promise.all([userModule.getMultipleAddress(item.id || 0)])
        itemInside.address_details = detail
        itemsChanged.push(item)
        return true
    }
    await commonFunction.asyncForEach(items[0], async (element) => {
        await attachAddress(element)
    })
    return itemsChanged
}
/**
 * attachcard details
 *
 * @memberOf frontend.user
 * @param {string} items multiple address
 * @param {userModule.getCardDetails} module
 */
const attachCardDetails = async (items) => {
    const itemsChanged = []
    const attachCard = async (item) => {
        const itemInside = item
        const [detail] = await Promise.all([userModule.getCardDetails(item.id || 0)])
        itemInside.card_details = detail
        itemsChanged.push(item)
        return true
    }
    await commonFunction.asyncForEach(items[0], async (element) => {
        await attachCard(element)
    })
    return itemsChanged
}

module.exports = {
    /**
     * Login User
     *
     * @memberOf frontend.user
     * @param {userModule.updateLastLogin} modules
     * @param {userModule.userViews} modules
     * @param {userModule.checkEmailExisting} modules
     * @param {userModule.loginWithEmail} modules
     * @param {userModule.updateSocialID} modules
     */
    loginUser: async (req, res) => {
        try {
            await schemaModule.login().validateSync(req.body)

            const successLogin = async (row) => {
                await Promise.all([
                    userModule.updateLastLogin(row[0].id, req.sessionID),
                    userModule.userViews(req, row[0].id),
                ])
                const obj = {
                    id: row[0].id,
                }

                // const [userBidAverage, userCategory, userCondition] = await Promise.all([
                //     commonFunction.userAvgPrefDetails(row[0].id),
                //     commonFunction.userCategoryPrefDetails(row[0].id),
                //     commonFunction.userConditionPrefDetails(row[0].id),
                // ])
                // obj.averageBidAmount = userBidAverage[0].averageBidAmount
                // obj.averageCategoryType = userCategory
                // obj.averageConditionType = userCondition

                const token = jwt.sign(obj, config.get('secret'), {
                    expiresIn: '168h',
                })
                if (row[0].isemp === '1') {
                    jsonResponse(res, 'success', {
                        responseType: 6,
                        token,
                        message: 'Logged in successfully',
                    })
                } else {
                    jsonResponse(res, 'success', {
                        responseType: 3,
                        token,
                        message: 'Logged in successfully',
                    })
                }
            }
            const processObject = async (row) => {
                if (row.length > 0) {
                    if (row[0].status === 'moderate') {
                        jsonResponse(res, 'error', {
                            responseType: 2,
                            message: 'Account has not been approved by admin yet',
                        })
                    } else if (row[0].status === 'deleted') {
                        jsonResponse(res, 'error', {
                            responseType: 2,
                            message: 'Account has been suspended',
                        })
                    } else if (row[0].status === 'deactivate') {
                        jsonResponse(res, 'error', {
                            responseType: 2,
                            message: 'Account has been suspended',
                        })
                    } else if (row[0].status === 'email_unverified') {
                        jsonResponse(res, 'error', {
                            responseType: 2,
                            message: 'Verify email address to continue',
                        })
                    } else if (row[0].status === 'unverified') {
                        jsonResponse(res, 'error', {
                            responseType: 2,
                            message: 'Account is unverifed. Waiting for approval!',
                        })
                    } else if (row[0].status === 'active') {
                        successLogin(row)
                    } else {
                        jsonResponse(res, 'error', {
                            responseType: 2,
                            message: `Account has been ${row[0].status}`,
                        })
                    }
                } else if (req.body.google_id || req.body.facebook_id) {
                    req.body.email = req.body.email.toLowerCase()
                    const resultuser = await Promise.all([
                        userModule.checkEmailExisting(req.body.email),
                    ])
                    if (resultuser[0].length > 0) {
                        const [updateSocial, afterSuccess] = await Promise.all([
                            userModule.updateSocialID(req, resultuser[0][0].id),
                            userModule.loginWithEmail(req.body.email),
                        ])
                        if (afterSuccess.length > 0) {
                            if (afterSuccess[0].status === 'moderate') {
                                jsonResponse(res, 'error', {
                                    responseType: 2,
                                    message: 'Account has not been approved by admin yet',
                                })
                            } else if (afterSuccess[0].status === 'deleted') {
                                jsonResponse(res, 'error', {
                                    responseType: 2,
                                    message: 'Account has been suspended',
                                })
                            } else if (afterSuccess[0].status === 'deactivate') {
                                jsonResponse(res, 'error', {
                                    responseType: 2,
                                    message: 'Account has been suspended',
                                })
                            } else if (afterSuccess[0].status === 'unverified') {
                                jsonResponse(res, 'error', {
                                    responseType: 2,
                                    message: 'Account is unverifed. Waiting for approval!',
                                })
                            } else if (afterSuccess[0].status === 'active') {
                                successLogin(row)
                            } else {
                                jsonResponse(res, 'error', {
                                    responseType: 2,
                                    message: `Account has been ${row[0].status}`,
                                })
                            }
                        } else {
                            jsonResponse(res, 'error', {
                                responseType: 2,
                                message: 'Invalid Email/Password',
                            })
                        }
                    } else {
                        jsonResponse(res, 'error', {
                            responseType: 2,
                            message: 'Invalid Email/Password',
                        })
                    }
                } else {
                    jsonResponse(res, 'error', {
                        responseType: 2,
                        message: 'Invalid Email/Password',
                    })
                }
            }
            userModule.process(req, processObject)
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },

    /**
     * Register User
     *
     * @memberOf frontend.user
     * @param {userModule.checkEmailExisting} modules
     * @param {userModule.registerUser} modules
     * @param {userModule.registerUserCustom} modules
     * @param {userModule.insertEmailVerifyToken} modules
     * @param {userModule.manualInsertUsernotify} modules
     */
    registerUser: async (req, res) => {
        try {
            const successRegistration = (userID) => {
                const obj = {
                    id: userID,
                }

                const token = jwt.sign(obj, config.get('secret'), {
                    expiresIn: '168h',
                })

                jsonResponse(res, 'success', {
                    responseType: 1,
                    responseData: {
                        userID,
                        token,
                    },
                    message: 'Successfully registered!',
                })
            }
            await schemaModule.register().validateSync(req.body)
            req.body.email = req.body.email.toLowerCase()
            const resultuser = await Promise.all([userModule.checkEmailExisting(req.body.email)])
            if (resultuser[0].length > 0) {
                jsonResponse(res, 'error', {
                    responseType: 2,
                    message: 'Registration Failed! Email Already Exists.',
                })
            } else {
                let kountResponse = { status: 'success' }
                if (global.configFeatures.kount_register.enabled) {
                    ;[kountResponse] = await Promise.all([kountCtrl.getRegistrationValidation(req)])
                }

                if (kountResponse.status === 'success') {
                    // req.body.password = Math.random().toString(36).slice(2);
                    const firstname = req.body.first_name
                    const lastname = req.body.last_name

                    const results = await Promise.all([userModule.registerUser(req, req.body)])

                    if (global.configColumns.custom_users.enabled) {
                        await Promise.all([
                            userModule.registerUserCustom(req, req.body, results[0].insertId),
                        ])
                    }

                    await Promise.all([userModule.manualInsertUsernotify(results[0].insertId)])
                    req.body.token = cryptosFunction.encrypt(req.body.email.toLowerCase())
                    await Promise.all([
                        userModule.insertEmailVerifyToken(
                            results[0].insertId,
                            req.body.email,
                            req.body.token,
                        ),
                    ])
                    const verifyurl2 = `${global.react_url.front_end}/verify_email/${req.body.token}`
                    await Promise.all([
                        commonFunction.eventTriggerFuction(
                            {
                                username: `${firstname || ''} ${lastname || ''}`,
                                verifyurl: verifyurl2,
                            },
                            req.body.email,
                            req.body.phone,
                            'register_user',
                            1,
                            0,
                            results[0].insertId,
                        ),
                    ])
                    await Promise.all([
                        userModule.insertEmailVerifyToken(
                            results[0].insertId,
                            req.body.email,
                            req.body.token,
                        ),
                    ])

                    successRegistration(results[0].insertId)
                } else {
                    jsonResponse(res, 'error', {
                        responseType: kountResponse.responseType,
                        message: kountResponse.message,
                        responseData: kountResponse.responseData,
                    })
                }
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },

    /**
     * Verify Email
     *
     * @memberOf frontend.user
     * @param {userModule.getEmailVerifyToken} modules
     * @param {userModule.updateEmailVerified} modules
     * @param {userModule.updateEmailVerifiedToken} modules
     */
    verifyEmail: async (req, res) => {
        try {
            req.body.email = cryptosFunction.decrypt(req.body.user_token)
            console.log(req.body.email)
            const [userExist] = await Promise.all([
                userModule.getEmailVerifyToken(req.body.email, req.body.user_token),
            ])
            if (userExist.length > 0) {
                if (!userExist[0].mail_verified) {
                    if (req.body.status === 'active') {
                        const userExists = {}
                        userExists.id = userExist[0].id
                        userExists.status = req.body.status
                        const [results2] = await Promise.all([
                            userModule.updateEmailVerifiedAndApprove(userExists),
                            userModule.updateEmailVerifiedToken(userExist[0]),
                        ])
                    } else {
                        const [results2] = await Promise.all([
                            userModule.updateEmailVerified(userExist[0]),
                            userModule.updateEmailVerifiedToken(userExist[0]),
                        ])
                    }

                    const loginurl2 = `${global.react_url.front_end}/login`
                    await Promise.all([
                        commonFunction.eventTriggerFuction(
                            {
                                username: `${userExist[0].first_name || ''} ${
                                    userExist[0].last_name || ''
                                }`,
                                loginurl: loginurl2,
                            },
                            req.body.email,
                            '',
                            'email_verified',
                            1,
                            0,
                            userExist[0].id,
                        ),
                    ])

                    jsonResponse(res, 'success', {
                        responseType: 1,
                        message: 'Email verified successfully.',
                    })
                } else {
                    jsonResponse(res, 'success', {
                        responseType: 1,
                        message: 'Email already verified.',
                    })
                }
            } else {
                jsonResponse(res, 'success', {
                    responseType: 1,
                    message: 'Not a valid request!',
                })
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Not a valid request!',
            })
        }
    },

    /**
     * Check User Token
     *
     * @memberOf frontend.user
     * @param {commonFunction.userDetails} modules
     */
    checkTokenUser: async (req, res) => {
        try {
            const results = await Promise.all([commonFunction.userDetails(req.user.id)])
            if (
                global.configFeatures.multiple_address_for_users &&
                global.configFeatures.multiple_address_for_users.enabled
            ) {
                results[0] = await attachMultipleAddress(results)
            }
            if (
                global.configFeatures.show_card_details &&
                global.configFeatures.show_card_details.enabled
            ) {
                results[0] = await attachCardDetails(results)
            }
            if (results[0].length > 0) {
                jsonResponse(res, 'success', {
                    responseType: 1,
                    message: 'Details successfully retrieved!',
                    responseData: results[0][0],
                })
            } else {
                jsonResponse(res, 'error', {
                    responseType: 2,
                    message: 'User details not available!',
                })
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },

    /**
     * Check User Validation
     *
     * @memberOf frontend.user
     * @param {userModule.checkEmailExisting} modules
     */
    checkValidation: async (req, res) => {
        try {
            await schemaModule.checkValidation().validateSync(req.body)

            if (req.body.type === 'email') {
                req.body.text = req.body.text.toLowerCase()
                const resultuser = await Promise.all([userModule.checkEmailExisting(req.body.text)])
                if (resultuser[0].length > 0) {
                    jsonResponse(res, 'error', {
                        responseType: 2,
                        message: 'Email Already Exists!',
                    })
                } else {
                    jsonResponse(res, 'success', {
                        responseType: 1,
                        message: 'Email available!',
                    })
                }
            } else {
                jsonResponse(res, 'error', {
                    responseType: 4,
                    message: 'Unknown type!',
                })
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },

    /**
     * Update User Profile
     *
     * @memberOf frontend.user
     * @param {commonFunction.userDetails} modules
     * @param {userModule.updateProfile} modules
     * @param {userModule.updateCustomUsersProfile} modules
     */
    updateProfile: async (req, res) => {
        try {
            if (req.body.change_password) {
                const results = await Promise.all([commonFunction.userDetails(req.user.id)])
                if (results[0].length > 0) {
                    const currentUserPasswordSalt = results[0][0].password_salt
                    const encryptCurrentUserOldPassword = results[0][0].password_hash
                    req.body.password_hash = md5(
                        md5(req.body.new_password) + currentUserPasswordSalt,
                    )
                    const encryptOldPasswordFromRequest = md5(
                        md5(req.body.current_password) + currentUserPasswordSalt,
                    )
                    if (encryptOldPasswordFromRequest !== encryptCurrentUserOldPassword) {
                        jsonResponse(res, 'error', {
                            responseType: 2,
                            message: 'Current password not match!',
                        })
                    } else {
                        await Promise.all([updateProfileFunction(req)])
                        jsonResponse(res, 'success', {
                            responseType: 1,
                            message: 'Password changed successfully',
                        })
                    }
                } else {
                    jsonResponse(res, 'error', {
                        responseType: 2,
                        message: 'User details not available!',
                    })
                }
            } else {
                const [resultuser] = await Promise.all([
                    userModule.checkEmailExisting(req.body.email),
                ])
                if (resultuser.length && resultuser[0].id != req.user.id) {
                    jsonResponse(res, 'error', {
                        responseType: 2,
                        message: 'Email Already Exists',
                    })
                    return false
                }

                if (req.body.is_maxbid_requested && req.body.is_maxbid_requested === 1) {
                    req.body.max_bid = global.configurations.variables.max_bid_limit
                }

                // update profile
                await Promise.all([updateProfileFunction(req)])

                // mail trigger for maxbid
                if (req.body.is_maxbid_requested && req.body.is_maxbid_requested === 1) {
                    await Promise.all([
                        commonFunction.eventTriggerFuction(
                            {
                                username: `Admin`,
                                requestername: `${req.user.first_name || ''} ${
                                    req.user.last_name || ''
                                }`,
                                requesterid: req.user.id,
                                requestermail: req.user.email,
                            },
                            global.general.adminemail,
                            '',
                            'bidding_limit_request',
                            0,
                            0,
                            0,
                        ),
                    ])
                    // await Promise.all([
                    //     commonFunction.eventTriggerFuction(
                    //         {
                    //             username: `${req.user.first_name || ''} ${
                    //                 req.user.last_name || ''
                    //             }`,
                    //         },
                    //         req.user.email,
                    //         req.user.phone,
                    //         'aknowledge_bid_limit_request',
                    //         1,
                    //         0,
                    //         req.user.id,
                    //     ),
                    // ])
                }
                jsonResponse(res, 'success', {
                    responseType: 1,
                    message: 'Profile updated successfully',
                })
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },

    /**
     * Add to watchlist
     *
     * @memberOf frontend.user
     * @param {userModule.isinWatchlist} modules
     * @param {userModule.updateWatchlist} modules
     * @param {userModule.addWatchlist} modules
     */
    addWatchlist: async (req, res) => {
        try {
            const projectID = req.body.project_id
            const [watchexist] = await Promise.all([userModule.isinWatchlist(req, projectID)])
            if (watchexist.length > 0) {
                await Promise.all([userModule.updateWatchlist(req, projectID)])
            } else {
                await Promise.all([userModule.addWatchlist(req, projectID)])
            }
            const results3 = await Promise.all([
                commonFunction.commonselectparenttable(
                    'id,title,auctiontype,date_closed',
                    'id',
                    projectID,
                    global.configColumns.projects,
                ),
            ])
            console.log('add_watchlist')
            await Promise.all([
                commonFunction.eventTriggerFuction(
                    {
                        username: `${req.user.first_name || ''} ${req.user.last_name || ''}`,
                        title: results3[0][0].title,
                        date_closed: results3[0][0].date_closed,
                    },
                    req.user.email,
                    req.user.phone,
                    'watchlist_added',
                    1,
                    3,
                    req.user.id,
                    results3[0][0].auctiontype,
                ),
            ])
            const responseData = { project_id: projectID, status: 'added' }
            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Successfully added to watchlist!',
                responseData,
            })
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },

    /**
     * Remove from watchlist
     *
     * @memberOf frontend.user
     * @param {userModule.removeWatchlist} modules
     */
    removeWatchlist: async (req, res) => {
        try {
            const projectID = req.body.project_id
            await Promise.all([userModule.removeWatchlist(req, projectID)])
            const responseData = { project_id: projectID, status: 'removed' }
            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Successfully removed from watchlist!',
                responseData,
            })
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },

    /**
     * Add to SAved Search
     *
     * @memberOf frontend.user
     * @param {userModule.isInSavedSearchlist} modules
     * @param {userModule.tableFunction} modules
     */
    addSavedSearch: async (req, res) => {
        try {
            const searchText = req.body.search_text
            const baseTableUsed = global.configColumns.saved_search
            req.body.user_id = req.user.id
            const firstname = req.user.first_name
            const lastname = req.user.last_name
            const usermail = req.user.email.toLowerCase()
            const [savedExist] = await Promise.all([
                userModule.isInSavedSearchlist(req, searchText),
            ])
            if (savedExist.length === 0) {
                await Promise.all([
                    commonFunction.tableFunction(req, baseTableUsed, { enabled: 0 }, 1),
                ])
                await Promise.all([
                    commonFunction.eventTriggerFuction(
                        {
                            username: `${firstname || ''} ${lastname || ''}`,
                            title: searchText,
                        },
                        usermail,
                        '',
                        'saved_search_email',
                        1,
                        10,
                        req.user.id,
                    ),
                ])
                const responseData = { status: 'added' }
                jsonResponse(res, 'success', {
                    responseType: 1,
                    message: 'Successfully added to saved search!',
                    responseData,
                })
            } else {
                const responseData = { status: 'error' }
                jsonResponse(res, 'error', {
                    responseType: 2,
                    message: 'Already exists in saved list!',
                    responseData,
                })
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },

    /**
     * Remove from saved search
     *
     * @memberOf frontend.user
     * @param {userModule.removeSavedSearch} modules
     */
    removeSavedSearch: async (req, res) => {
        try {
            const { id } = req.body
            await Promise.all([userModule.removeSavedSearch(req, id)])
            const responseData = { status: 'removed' }
            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Successfully removed from saved search!',
                responseData,
            })
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },

    /**
     * Check User Token
     *
     * @memberOf frontend.user
     * @param {commonFunction.fetchFilteredDataFunction} modules
     */
    getSavedSearch: async (req, res) => {
        try {
            const baseTableUsed = global.configColumns.saved_search
            req.body.filters = req.body.filters ? req.body.filters : {}
            req.body.filters.user_id = { value: req.user.id, field: 'user_id', type: 'in' }
            const [records, totalRecords] = await Promise.all([
                commonFunction.fetchFilteredDataFunction(req, baseTableUsed, { enabled: 0 }, 1),
                commonFunction.fetchFilteredDataFunction(req, baseTableUsed, { enabled: 0 }, 0),
            ])
            const responseData = { records: records[0], totalRecords: totalRecords[0].length }
            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Details successfully retrieved!',
                responseData,
            })
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },

    /**
     * Forgot Password
     *
     * @memberOf frontend.user
     * @param {userModule.checkForgotUserExists} modules
     * @param {userModule.inserUserToken} modules
     */
    forgotPassword: async (req, res) => {
        try {
            const emailID = req.body.email
            const [userExist] = await Promise.all([userModule.checkForgotUserExists(emailID)])
            if (userExist.length > 0) {
                req.body.token = cryptosFunction.encrypt(req.body.email.toLowerCase())
                const verifyurl2 = `${global.react_url.front_end}/reset_password/${req.body.token}`
                const [results2] = await Promise.all([
                    userModule.inserUserToken(userExist[0], req.body.token),
                ])
                await Promise.all([
                    commonFunction.eventTriggerFuction(
                        {
                            username: `${userExist[0].first_name || ''} ${
                                userExist[0].last_name || ''
                            }`,
                            siteurl: global.url,
                            verifyurl: verifyurl2,
                            email: req.body.email,
                        },
                        req.body.email,
                        '',
                        'forgot_password',
                        1,
                        0,
                        userExist[0].id,
                    ),
                ])
                jsonResponse(res, 'success', {
                    responseType: 1,
                    message: 'Email sent out successfully',
                })
            } else {
                jsonResponse(res, 'error', {
                    responseType: 3,
                    message: 'Email did not match with record',
                })
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },

    /**
     * Reset Password
     *
     * @memberOf frontend.user
     * @param {userModule.getForgotUserToken} modules
     * @param {userModule.updateResetPassword} modules
     * @param {userModule.updateForgotUserToken} modules
     */
    resetPassword: async (req, res) => {
        try {
            await schemaModule.resetPassword().validateSync(req.body)
            req.body.email = cryptosFunction.decrypt(req.body.user_token)
            const [userExist] = await Promise.all([
                userModule.getForgotUserToken(req.body.email, req.body.user_token),
            ])
            if (userExist.length > 0) {
                console.log('<=====change-password=====>')
                const [results2] = await Promise.all([
                    commonFunction.mailtemps('password_changed'),
                    userModule.updateResetPassword(req.body.password, userExist[0]),
                    userModule.updateForgotUserToken(userExist[0]),
                ])
                if (results2.length > 0) {
                    let { template, subject } = results2[0]
                    template = template.replace(
                        '{{event.user}}',
                        `${userExist[0].first_name} ${userExist[0].last_name}`,
                    )
                    const loginurl = `${global.react_url.front_end}/login`
                    template = template.replace(/{{event.loginurl}}/g, loginurl)
                    template = template.replace('{{event.email}}', req.body.email)
                    sendgridModule.sendEmail(subject, req.body.email, template, 1, userExist[0].id)
                    jsonResponse(res, 'success', {
                        responseType: 1,
                        message: 'Password changed successfully.',
                    })
                } else {
                    jsonResponse(res, 'error', {
                        responseType: 1,
                        message: 'Email template does not exists',
                    })
                }
            } else {
                jsonResponse(res, 'success', {
                    responseType: 1,
                    message: 'Not a valid request!',
                })
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Not a valid request!',
            })
        }
    },

    /**
     * Send Phone Verification Code
     *
     * @memberOf frontend.user
     * @param {userModule.getPhoneVerifyToken} modules
     * @param {userModule.insertPhoneVerifyToken} modules
     * @param {userModule.updatePhoneVerifyExpiry} modules
     */
    sendPhoneVerifyCode: async (req, res) => {
        try {
            const [userExist] = await Promise.all([userModule.getPhoneVerifyToken(req.body.phone)])
            req.body.token = Math.floor(100000 + Math.random() * 900000)
            req.body.ip = typeof req.headers.ipaddress === 'undefined' ? '' : req.headers.ipaddress

            if (userExist.length > 0) {
                if (new Date() >= userExist[0].expires_at) {
                    await Promise.all([
                        userModule.insertPhoneVerifyToken(
                            req.body.phone,
                            req.body.token,
                            req.body.ip,
                        ),
                    ])
                    commonFunction.eventTriggerFuction(req.body, '', req.body.phone, 'verify_phone')
                    jsonResponse(res, 'success', {
                        responseType: 1,
                        message: 'SMS sent for verification!',
                    })
                } else {
                    await Promise.all([userModule.updatePhoneVerifyExpiry(userExist[0].id)])
                    commonFunction.eventTriggerFuction(req.body, '', req.body.phone, 'verify_phone')
                    jsonResponse(res, 'success', {
                        responseType: 1,
                        message: 'SMS resent for verification!',
                    })
                }
            } else {
                const [results2] = await Promise.all([
                    userModule.insertPhoneVerifyToken(req.body.phone, req.body.token, req.body.ip),
                ])
                commonFunction.eventTriggerFuction(req.body, '', req.body.phone, 'verify_phone')
                jsonResponse(res, 'success', {
                    responseType: 1,
                    message: 'SMS sent for verification!',
                })
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },

    /**
     * Verify Phone Verification Code
     *
     * @memberOf frontend.user
     * @param {userModule.getPhoneVerifyToken} modules
     * @param {userModule.updatePhoneVerified} modules
     */
    verifyPhoneVerifyCode: async (req, res) => {
        try {
            const [userExist] = await Promise.all([userModule.getPhoneVerifyToken(req.body.phone)])
            if (userExist.length > 0) {
                if (userExist[0].code !== req.body.verify_code) {
                    jsonResponse(res, 'error', {
                        responseType: 1,
                        message: 'Invalid verification code!',
                    })
                } else if (new Date() >= userExist[0].expires_at) {
                    jsonResponse(res, 'error', {
                        responseType: 1,
                        message: 'Code Expired! Try again',
                    })
                } else {
                    await Promise.all([userModule.updatePhoneVerified(userExist[0].id)])
                    jsonResponse(res, 'success', {
                        responseType: 1,
                        message: 'Phone number verified successfully',
                    })
                }
            } else {
                jsonResponse(res, 'error', {
                    responseType: 1,
                    message: 'No Code. Resent SMS Verification!',
                })
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },

    /**
     * Sending Email Verification Code
     *
     * @memberOf frontend.user
     * @param {userModule.getEmailVerifyTokenFromDb} modules
     */
    sendEmailVerifyLink: async (req, res) => {
        try {
            if (req.user.mail_verified) {
                jsonResponse(res, 'success', {
                    responseType: 1,
                    message: 'Email already verified!',
                })
            } else {
                const [userExist] = await Promise.all([
                    userModule.getEmailVerifyTokenFromDb(req.user.email),
                ])
                if (userExist.length > 0) {
                    const verifyurl = `${global.react_url.front_end}/verify_email/${userExist[0].token}`
                    await Promise.all([
                        commonFunction.eventTriggerFuction(
                            {
                                username: `${req.user.first_name || ''} ${
                                    req.user.last_name || ''
                                }`,
                                verifyurl,
                            },
                            req.user.email,
                            '',
                            'verify_email',
                        ),
                    ])
                    jsonResponse(res, 'success', {
                        responseType: 1,
                        message: 'Email sent for verification!',
                    })
                } else {
                    req.body.token = cryptosFunction.encrypt(req.user.email.toLowerCase())
                    await Promise.all([
                        userModule.insertEmailVerifyToken(
                            req.user.id,
                            req.user.email,
                            req.body.token,
                        ),
                    ])
                    const verifyurl = `${global.react_url.front_end}/verify_email/${req.body.token}`
                    await Promise.all([
                        commonFunction.eventTriggerFuction(
                            {
                                username: `${req.user.first_name || ''} ${
                                    req.user.last_name || ''
                                }`,
                                verifyurl,
                            },
                            req.user.email,
                            '',
                            'verify_email',
                        ),
                    ])
                    jsonResponse(res, 'success', {
                        responseType: 1,
                        message: 'Email sent for verification!',
                    })
                }
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },

    /**
     * Update User Preference
     *
     * @memberOf frontend.user
     * @param {userModule.selectUserPreference} req.modules
     * @param {userModule.updatePreference} req.modules
     * @param {userModule.insertPreference} req.modules
     */
    updatePreference: async (req, res) => {
        try {
            const [notificationExist] = await Promise.all([
                userModule.selectUserPreference(req.user.id),
            ])
            if (notificationExist.length > 0) {
                await Promise.all([userModule.updatePreference(req, notificationExist[0].id)])
                jsonResponse(res, 'success', {
                    responseType: 1,
                    message: 'Successfully updated notification preference!',
                })
            } else {
                await Promise.all([userModule.insertPreference(req)])
                jsonResponse(res, 'success', {
                    responseType: 1,
                    message: 'Successfully added notification preference!',
                })
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
    /**
     * otp verify
     *
     * @memberOf frontend.user
     * @param {userModule.getNotificationFlagdynamic} req.modules
     * @param {userModule.getparticulartabledetails} req.modules
     * @param {userModule.insertPreference} req.modules
     */
    otpVerify: async (req, res) => {
        try {
            req.body.phone = req.body.phone ? req.body.phone : ''
            if (req.body.phone === '') {
                jsonResponse(res, 'error', {
                    responseType: 3,
                    message: 'Invalid OTP please try again!',
                })
            } else {
                const results = await Promise.all([
                    userModule.getNotificationFlagdynamic('otp_sms'),
                ])
                if (results[0].length > 0) {
                    const results4 = await Promise.all([
                        userModule.getparticulartabledetails(
                            'title,subject,template',
                            'title',
                            results[0][0].type,
                            'templates',
                            1,
                        ),
                    ])
                    if (results4[0].length > 0) {
                        const dumpAuctionid = Math.floor(100000 + Math.random() * 900000)
                        const otpNumber = req.body.phone.replace(/[ !#@$%^&*()_+|~=`{}]/g, '-')
                        req.session[`${otpNumber}_largeotp`] = dumpAuctionid
                        let templateSms = results4[0][0].template
                        templateSms = templateSms.replace('{{username}}', req.body.username)
                        templateSms = templateSms.replace('{{event.otp}}', dumpAuctionid)
                        await sendsmstrigger(templateSms, req.body.phone)
                        jsonResponse(res, 'error', {
                            responseType: 1,
                            message: 'OTP successfully sent!',
                        })
                    } else {
                        jsonResponse(res, 'error', {
                            responseType: 3,
                            message: 'Invalid OTP please try again!',
                        })
                    }
                } else {
                    jsonResponse(res, 'error', {
                        responseType: 3,
                        message: 'Invalid OTP please try again!',
                    })
                }
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
    /**
     * otp verify check
     *
     * @memberOf frontend.user
     * @param {object} req request object
     * @param {object} res response object
     */
    otpVerifycheck: async (req, res) => {
        try {
            req.body.phone = req.body.phone ? req.body.phone : ''
            req.body.otp = req.body.otp ? req.body.otp : ''
            if (req.body.phone === '') {
                jsonResponse(res, 'error', {
                    responseType: 3,
                    message: 'Invalid OTP please try again!',
                })
            } else {
                const otpNumber = req.body.phone.replace(/[ !#@$%^&*()_+|~=`{}]/g, '-')
                const otpCheck = req.session[`${otpNumber}_largeotp`]
                if (otpCheck === req.body.otp) {
                    jsonResponse(res, 'error', {
                        responseType: 3,
                        message: 'Verification success!',
                    })
                } else {
                    jsonResponse(res, 'error', {
                        responseType: 3,
                        message: 'Invalid OTP please try againP!',
                    })
                }
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
    /**
     * otp verify check
     *
     * @memberOf frontend.user
     * @param {object} req request object
     * @param {object} res response object
     */
    getsingleuserdetails: async (req, res) => {
        try {
            const auctionobj = {}
            const [userlisting] = await Promise.all([
                userModule.commonselectparenttable(
                    '*',
                    'id',
                    req.body.id,
                    global.configColumns.users,
                ),
            ])
            const listofuser = userlisting
            auctionobj.user_list = listofuser

            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Details successfully retrieved!',
                auctionobj,
            })
        } catch (e) {
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
    /**
     * add invite user
     *
     * @memberOf frontend.user
     * @param {object} req request object
     * @param {object} res response object
     * @param {userModule.postalltypeoflisting} module
     */
    addInviteUser: async (req, res) => {
        try {
            const postinglist = await Promise.all([
                userModule.postalltypeoflisting(req, req.body, global.configColumns.inviteuser),
            ])
            if (global.configColumns.custom_inviteuser.enabled) {
                req.body.invite_id = postinglist[0].insertId
                await Promise.all([
                    userModule.postalltypeoflisting(
                        req,
                        req.body,
                        global.configColumns.custom_inviteuser,
                    ),
                ])
            }
            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Details successfully retrieved!',
            })
        } catch (e) {
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
    /**
     * submit contact us
     *
     * @memberOf frontend.user
     * @param {object} req request object
     * @param {object} res response object
     * @param {commonFunction.eventTriggerFuction} module
     * @param {commonFunction.getValidID} modules
     */
    submitContactUs: async (req, res) => {
        try {
            req.body.email = req.body.email && req.body.email.toLowerCase()

            const userContactAction = async () => {
                req.body.id = commonFunction.getValidID(req.body.id)

                const baseTableUsed = global.configColumns.contact_us
                const customTableUsed = { enabled: 0 }

                const [results] = await Promise.all([
                    commonFunction.tableFunction(req, baseTableUsed, customTableUsed, true),
                ])
                return true
            }

            await Promise.all([userContactAction(req)])

            if (typeof global.configFeatures.contact_user_email !== 'undefined') {
                if (parseInt(global.configFeatures.contact_user_email.enabled, 10) === 1) {
                    await Promise.all([
                        commonFunction.eventTriggerFuction(
                            req.body,
                            req.body.email,
                            '',
                            'contact_us_user',
                            0,
                        ),
                    ])
                }
            }
            if (typeof global.configFeatures.contact_admin_email !== 'undefined') {
                if (parseInt(global.configFeatures.contact_admin_email.enabled, 10) === 1) {
                    await Promise.all([
                        commonFunction.eventTriggerFuction(
                            req.body,
                            global.configurations.variables.admin_email,
                            '',
                            'contact_us_admin',
                            0,
                        ),
                    ])
                }
            }
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        } finally {
            const responseData = {}
            jsonResponse(res, 'success', {
                responseType: 1,
                message: 'Form submitted successfully!',
                responseData,
            })
        }
    },

    // shipping and other product detail handling

    /**
     * find user address
     *
     * @memberOf frontend.user
     * @param {object} item address
     * @param {userModule.getMultipleAddress} module
     * @param {commonFunction.userDetails} modules
     */
    async findUserAddress(item) {
        return new Promise(async (reslove) => {
            const itemValue = item
            itemValue.buyer_id = itemValue.buyer_id ? itemValue.buyer_id : itemValue.user_id
            const [deatils, userDetails] = await Promise.all([
                userModule.getMultipleAddress(itemValue.buyer_id || 0),
                commonFunction.userDetails(itemValue.buyer_id || 0),
            ])
            let primaryDetail = deatils.findIndex((e) => e.is_primary === 1)

            if (itemValue.invoice_address_id)
                primaryDetail = deatils.findIndex((e) => e.id === itemValue.invoice_address_id)

            const defaultAddress =
                deatils.length > 1 && primaryDetail > -1 ? deatils[primaryDetail] : deatils[0]
            reslove([defaultAddress, userDetails[0]])
        })
    },
    /**
     * user Address
     *
     * @memberOf frontend.user
     * @param {object} req request object
     * @param {object} res response object
     * @param {userModule.removeAddressPrimary} module
     * @param {commonFunction.tableFunction} modules
     */
    userAddress: async (req, res) => {
        try {
            const baseTableUsed = global.configColumns.user_address_details
            req.body.user_id = req.user.id
            if (req.body.is_primary) {
                await Promise.all([userModule.removeAddressPrimary(req)])
            }

            await Promise.all([commonFunction.tableFunction(req, baseTableUsed, { enabled: 0 }, 1)])
            const responseData = {}

            jsonResponse(res, 'success', {
                responseType: 1,
                message:
                    req.body.status == 'inactive'
                        ? 'Address successfully deleted!'
                        : req.body.id
                        ? 'Successfully updated address!'
                        : 'Successfully added address!',
                responseData,
            })
        } catch (e) {
            console.error(e)
            jsonResponse(res, 'error', {
                responseType: 3,
                message: 'Internal Server error!',
            })
        }
    },
}