You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
640 lines
19 KiB
640 lines
19 KiB
// 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,
|
|
fcmId: req.body.fcmId
|
|
};
|
|
|
|
|
|
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
|
|
user.fcmId = usertobeInserted.fcmId
|
|
}
|
|
|
|
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,
|
|
fcmId: insertedUser.fcmId
|
|
},
|
|
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);
|
|
}
|
|
};
|
|
|
|
|