// const fastify = require("fastify")({ // logger: true, // }); const axios = require('axios'); const bcrypt = require("bcrypt"); const saltRounds = 10; const libphonenumberjs = require("libphonenumber-js"); // External Dependancies // offers http-friendly error objects. const boom = require("boom"); // Get Data Models const { Supplier, generateSupplierId, FriendRequest,DeliveryBoy} = require("../models/supplier") const { User,Counter, generateBookingId,resetCounter,generateCustomerId,ProfilePicture} = require('../models/User') //const User = require("../models/User"); const customJwtAuth = require("../customAuthJwt"); const fastify = require("fastify")({ logger: true, }); //function to encrypt password. //used bcrypt module. async function bcryptPassword(password) { encryptedPwd = bcrypt.hash(password, saltRounds); return encryptedPwd; } //function to decrypt password return user object . //used bcrypt module. async function bcryptComparePassword(pwd, encpassword) { isSame = bcrypt.compare(pwd, encpassword); return isSame; } // Get current users exports.getCurrentUser = async (req, reply) => { try { const users = await User.findOne({ customerId: req.body.customerId }); return users; } catch (err) { throw boom.boomify(err); } }; // Get all users exports.getUsers = async (req, reply) => { const limit = parseInt(req.query.limit) || 100; const page = parseInt(req.query.page) || 1; const startindex = (page - 1) * limit; try { await User.find() .limit(limit) .skip(startindex) .exec() .then((docs) => { reply.send({ status_code: 200, data: docs, count: docs.length }); }) .catch((err) => { console.log(err); reply.send({ error: err }); }); } catch (err) { throw boom.boomify(err); } }; // Get single user by ID exports.getSingleUser = async (req, reply) => { try { const customerId = req.params.customerId; const user = await User.findOne({ customerId: customerId }); return user; } catch (err) { throw boom.boomify(err); } }; // Edit user info by userId exports.editUserInfo = async (req, body) => { try { const { userId } = req.params; console.log(customerId) const userInfo = await User.findById(userId); const updateData = req.body; console.log(updateData.firstName); if (updateData.firstName) userInfo.profile.firstName = updateData.firstName; if (updateData.lastName) userInfo.profile.lastName = updateData.lastName; if (updateData.phone) userInfo.profile.contactNumber = updateData.phone; if (updateData.address1) userInfo.profile.address1 = updateData.address1; if (updateData.address2) userInfo.profile.address2 = updateData.address2; if (updateData.city) userInfo.profile.city = updateData.city; if (updateData.state) userInfo.profile.state = updateData.state; if (updateData.country) userInfo.profile.country = updateData.country; if (updateData.zip) userInfo.profile.zip = updateData.zip; if (updateData.phone) userInfo.phone = updateData.phone; if (updateData.email) userInfo.emails[0].email = updateData.email; if (updateData.role) userInfo.profile.role = updateData.role; const user = await userInfo.save(); return user; } catch (err) { throw boom.boomify(err); } }; exports.editCuurentUserInfo = async (req, reply) => { try { const { customerId } = req.params; const userInfo = await User.findOne({ customerId: customerId.toString() }); const updateData = req.body; if (updateData.firstName) userInfo.profile.firstName = updateData.firstName; if (updateData.lastName) userInfo.profile.lastName = updateData.lastName; if (updateData.username) userInfo.username = updateData.username; if (updateData.phone) userInfo.profile.contactNumber = updateData.phone; if (updateData.address1) userInfo.profile.address1 = updateData.address1; if (updateData.address2) userInfo.profile.address2 = updateData.address2; if (updateData.city) userInfo.profile.city = updateData.city; if (updateData.state) userInfo.profile.state = updateData.state; if (updateData.country) userInfo.profile.country = updateData.country; if (updateData.zip) userInfo.profile.zip = updateData.zip; if (updateData.phone) userInfo.phone = updateData.phone; if (updateData.emails) userInfo.emails = updateData.emails; console.log(userInfo.emails[0].email) if (updateData.role) userInfo.profile.role = updateData.role; if (updateData.phone) { const phoneNumber = updateData.phone //libphonenumberjs.parsePhoneNumber(updateData.phone); if (phoneNumber) { // access returned collection if (!phoneNumber) { //if (!phoneNumber.isValid()) { error = { armintatankdata: { error: true, code: 10002, message: "10002 - Phone # " + updateData.phone + " is not a valid phone number", }, }; req.body.regError = error; reply.status(406).send(error); } } } if (userInfo.phone == updateData.phone) { console.log("IF++++++++++++++="); userInfo.phone = updateData.phone; userInfo.phoneVerified = true; } else { console.log("Ilse++++++++++++++="); userInfo.phone = updateData.phone; userInfo.phoneVerified = false; } const user = await userInfo.save(); return user; } catch (err) { throw boom.boomify(err); } }; // Add a new user // Function accepts username, password , encrypts password and saves it in the database. exports.addUser = async (req, reply) => { try { // await resetCounter();//to set customer id back to 0 var c_id = await generateCustomerId() var building= ((req.body.buildingName).slice(0, 3)).toUpperCase(); var customer_id = `AWSU${building}${c_id}` // console.log("This is the reply in the handler after the validations", reply); userData = { customerId: customer_id, username: req.body.username, emails: req.body.emails, password: req.body.password, phone: req.body.phone, buildingName: req.body.buildingName, inchargeName: req.body.inchargeName, profile: { firstName: req.body.firstName, lastName: req.body.lastName, contactNumber: req.body.phone, country: req.body.country, state: req.body.state, city: req.body.city, address1: req.body.address1, address2: req.body.address2, zip: req.body.zip, notes: req.body.notes, }, longitude: req.body.longitude, latitude:req.body.latitude, }; var user = new User(userData); //password is not at the top level in the collection. userpass = req.body.password; // If fields are sent via form encoding , capture the fields and assign them to the user Object. checkFormEncoding = isUserFormUrlEncoded(req); if (checkFormEncoding.isUserFormUrlEncoded) { usertobeInserted = checkFormEncoding.user; console.log("thsi true url string"); user.username = usertobeInserted.username; user.firstName = usertobeInserted.firstName; user.lastName = usertobeInserted.lastName; user.phone = usertobeInserted.phone; user.emails = usertobeInserted.emails; user.passsword = usertobeInserted.password; user.buildingName = usertobeInserted.buildingName; user.inchargeName = usertobeInserted.inchargeName; user.customerId = usertobeInserted.customer_id; user.latitude = usertobeInserted.latitude; user.longitude = usertobeInserted.longitude } console.log("---------checkurl ecnoded string-----------------------"); // Store hash in your password DB. hash = await bcryptPassword(userpass); if (hash) { user.services.password.bcrypt = hash; if (req.body.role) { user.profile.role = req.body.role; console.log("******************************************************"); console.log(user); } else { // override and make the user role as "user" by default role = ["user"]; user.profile.role = role; } insertedUser = await user.save(); console.log(insertedUser); if (insertedUser) { // Prepare user object and wrap it inside the armintatankdata var retUser = { armintatankdata: { username: insertedUser.username, phone: insertedUser.phone, customerId: insertedUser.customerId, inchargeName: insertedUser.inchargeName, buildingName: insertedUser.buildingName, emails: [ { email: insertedUser.emails[0].email, }, ], profile: insertedUser.profile, longitude: insertedUser.longitude, latitude:insertedUser.latitude, }, status_code: 200, }; return retUser; } } } catch (err) { throw boom.boomify(err); } }; // Login a user // Accepts a user , password , and checks in the system to see if user exists , and password is valid // returns a user object so that jwt token can be created and sent back to the client exports.loginUser = async (req) => { try { const phone = req.body.phone; const password = req.body.password; const user = await User.findOne({ phone: phone }); // compare users password with what is supplied if (user) { isSame = await bcryptComparePassword( password, user.services.password.bcrypt ); // if password supplied matches return object if (isSame) { return { same: true, user: user }; } else { return { same: false }; } } else { return { same: false }; } } catch (err) { throw boom.boomify(err); } }; // Update an existing user exports.updateUser = async (req, reply) => { try { const id = req.params.id; const user = req.body; const { ...updateData } = user; const update = await User.findByIdAndUpdate(id, updateData, { new: true }); return update; } catch (err) { throw boom.boomify(err); } }; // Delete a user exports.deleteUser = async (req, reply) => { try { const id = req.params.id; const user = await User.findByIdAndRemove(id); return user; } catch (err) { throw boom.boomify(err); } }; //Added the getphone user and delphone user apis for testing purposes exports.getPhoneUser = async (req, reply) => { try { console.log(" requesting the api getPhoneUser , and passing the phone "); const phone = req.body.phone; const user = await User.findOne({ phone: phone }); return user; } catch (err) { throw boom.boomify(err); } }; exports.delPhoneUser = async (req, reply) => { try { const phone = req.body.phone; console.log("deleting users wiht the phone ....", phone); const user = await User.deleteOne({ phone: phone }); return user; } catch (err) { throw boom.boomify(err); } }; exports.uploadProfilePicture = async (req, reply) => { try { const customerId = req.params.customerId; const picture = req.body.picture; let profilePicture = await ProfilePicture.findOne({ customerId }); if (!profilePicture) { profilePicture = new ProfilePicture({ customerId, picture, }); } else { profilePicture. picture = picture; } await profilePicture.save(); reply.send({ message: 'Profile picture uploaded successfully' }); } catch (error) { reply.status(500).send({ error: error.message }); } }; exports.logout = async (request, reply) => { const invalidatedTokens = {}; const accessToken = request.headers.authorization && request.body.access_token; invalidatedTokens[accessToken] = true; reply.send({ message: 'Logout successful' }) } // controller.js const http = require('https'); exports.sendSms = async (request, reply) => { const code = Math.floor(100000 + Math.random() * 900000); const username = 'Arminta'; const apiKey = '2068323bea61494d315b'; const senderId = 'ARMNTA'; const mobile = request.body.mobileNumbers//'8341426949'; const message = `Welcome to Arminta !!! your OTP is ${code} please use it for login.`//`Welcome to Arminta !!! your OTP is ${code} please use it for login.`; const user = await User.findOne({phone: mobile}) const supplier = await Supplier.findOne({phone: mobile}) const deliveryBoy = await DeliveryBoy.findOne( { phone : mobile}) if(user){ await User.findOneAndUpdate({phone: mobile}, { $set: {'phoneVerificationCode': code } }) } if(supplier){ await Supplier.findOneAndUpdate({phone: mobile}, { $set: {'phoneVerificationCode': code } }) } if(deliveryBoy){ await DeliveryBoy.findOneAndUpdate({phone: mobile}, { $set: {'phoneVerificationCode': code } }) } const apiUrl = `https://smslogin.co/v3/api.php?username=${username}&apikey=${apiKey}&senderid=${senderId}&mobile=${mobile}&message=${encodeURIComponent(message)}`; const options = { method: 'GET', headers: { 'Content-Type': 'application/json' } }; const req = http.request(apiUrl, options, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { reply.send(data); }); }); req.on('error', (error) => { console.error(error); reply.send({ error: 'Failed to send SMS' }); }); req.end(); } exports.forgotPassword = async (req, reply) => { try { // Create a new User object from the request body var user = new User(req.body); // Check if the request body is URL encoded checkFormEncoding = isUserFormUrlEncoded(req); if (checkFormEncoding.isUserFormUrlEncoded) { // Extract user information from the request body usertobeInserted = checkFormEncoding.user; user.username = usertobeInserted.username; user.firstName = usertobeInserted.firstName; user.lastName = usertobeInserted.lastName; user.phone = usertobeInserted.phone; user.emails = usertobeInserted.emails; } // Find a user with the given phone number in the database userExists = await User.findOne({ phone: user.phone, }); if (userExists) { // Generate a random password reset code const code = Math.floor(100000 + Math.random() * 900000); // Convert the code to a string and hash it using bcrypt codestr = ""; codestr = code.toString(); hash = await bcryptPassword(codestr); // Update the user's password reset code and password hash in the database const filter = { phone: userExists.phone, }; const update = { $set: { passwordResetCode: code, "services.password.bcrypt": hash, oneTimePasswordSetFlag: true, }, }; const doc = await User.updateOne(filter, update); // Find the updated user in the database updatedUser = await User.findOne({ phone: userExists.phone }); if (updatedUser.oneTimePasswordSetFlag) { // Send an SMS with the password reset code const request = { body: { mobileNumbers: userExists.phone, }, }; const response = { send: (data) => { console.log(data); // Optional: Log the response from the SMS provider // Send a success response with the password reset code req.body.passwordResetCode = code; reply.send('{"armintatankdata":{"error":false,"forgotPassword": true}}'); }, }; await exports.sendSms(request, response); } else { // Send an error response if the password reset code was not set error = { armintatankdata: { error: true, code: 10007, message: "10007 - Unable to reset password", }, }; req.body.regError = error; reply.send(error); } } else { // Send an error response if no user was found with the given phone number error = { armintatankdata: { error: true, code: 10006, message: "10006 - Please check the phone number you entered..", }, }; req.body.regError = error; reply.send(error); } } catch (err) { // Handle any errors that occur during the API request throw boom.boomify(err); } }; exports.forgotPasswordSupplier = async (req, reply) => { try { // Create a new Supplier object from the request body var supplier = new Supplier(req.body); // Check if the request body is URL encoded checkFormEncoding = isSupplierFormUrlEncoded(req); if (checkFormEncoding.isSupplierFormUrlEncoded) { // Extract supplier information from the request body suppliertobeInserted = checkFormEncoding.supplier; supplier.username = suppliertobeInserted.username; supplier.firstName = suppliertobeInserted.firstName; supplier.lastName = suppliertobeInserted.lastName; supplier.phone = suppliertobeInserted.phone; supplier.emails = suppliertobeInserted.emails; } // Find a supplier with the given phone number in the database supplierExists = await Supplier.findOne({ phone: supplier.phone, }); if (supplierExists) { // Generate a random password reset code const code = Math.floor(100000 + Math.random() * 900000); // Convert the code to a string and hash it using bcrypt codestr = ""; codestr = code.toString(); hash = await bcryptPassword(codestr); // Update the supplier's password reset code and password hash in the database const filter = { phone: supplierExists.phone, }; const update = { $set: { passwordResetCode: code, "services.password.bcrypt": hash, oneTimePasswordSetFlag: true, }, }; const doc = await Supplier.updateOne(filter, update); // Find the updated supplier in the database updatedSupplier = await Supplier.findOne({ phone: supplierExists.phone }); if (updatedSupplier.oneTimePasswordSetFlag) { // Send an SMS with the password reset code const request = { body: { mobileNumbers: supplierExists.phone, }, }; const response = { send: (data) => { console.log(data); // Optional: Log the response from the SMS provider // Send a success response with the password reset code req.body.passwordResetCode = code; reply.send('{"armintatankdata":{"error":false,"forgotPassword": true}}'); }, }; await exports.sendSms(request, response); } else { // Send an error response if the password reset code was not set error = { armintatankdata: { error: true, code: 10007, message: "10007 - Unable to reset password", }, }; req.body.regError = error; reply.send(error); } } else { // Send an error response if no supplier was found with the given phone number error = { armintatankdata: { error: true, code: 10006, message: "10006 - Please check the phone number you entered..", }, }; req.body.regError = error; reply.send(error); } } catch (err) { // Handle any errors that occur during the API request throw boom.boomify(err); } };