//Get the data models const { Supplier } = require('../models/supplier'); const { ProfilePicture } = require('../models/User') const supplierController = require("../controllers/supplierController"); const customJwtAuth = require("../customAuthJwt"); const fastify = require("fastify")({ logger: true, //disableRequestLogging: true, genReqId(req) { // you get access to the req here if you need it - must be a synchronous function return uuidv4(); }, }); const fastifyEnv = require("fastify-env"); const boom = require("boom"); const emailValidator = require("email-validator"); const libphonenumberjs = require("libphonenumber-js"); fastify.register(customJwtAuth); const schema = { type: "object", required: ["PORT"], properties: { PORT: { type: "string", default: 3000, }, APIVERSION: { type: "string", default: "1.0.0", }, }, }; const options = { confKey: "config", // optional, default: 'config' schema: schema, // data: data // optional, default: process.env }; fastify.register(fastifyEnv, options).ready((err) => { if (err) console.error(err); console.log(fastify.config.PORT); // or fastify[options.confKey] // output: { PORT: 3000 } fastify.decorate("conf", { port: fastify.config.PORT, APIVERSION: fastify.config.APIVERSION, }); }); const apiversion = "1.0.0"; // fastify.register(require('fastify-cookie')) // fastify.register(require('fastify-session'), { // secret: 'my-secret-key', // cookie: { secure: true } // }); isSupplierFormUrlEncoded = (req) => { var isSupplierFormUrlEncoded = false; console.log("check is Supplier encoe url funtion"); // This iterates through the req headers object. // could not access req.headers.content-type due to the hyphen in the content-type key. // console.log(`${key}: ${value}`); for (const [key, value] of Object.entries(req.headers)) { if (`${key}` === "content-type") { if (`${value}` == "application/x-www-form-urlencoded") { // console.log( "data supplied is with content type," , `${value}`) // set isUserFormUrlEncoded value to true isSupplierFormUrlEncoded = true; // create user object with form variables . Password is used from the request object directly. s_data = { suppliername: req.body.suppliername, phone: req.body.phone, office_address: req.body.office_address, password: req.body.password, emails: [ { email: req.body.email, }, ], profile: { firstName: req.body.firstName, lastName: req.body.lastName, }, }; return { isSupplierFormUrlEncoded: isSupplierFormUrlEncoded, supplier: s_data }; } else { return { isSupplierFormUrlEncoded: false, s_data: "" }; } } } }; fastify.register((fastify, opts, done) => { fastify.addContentTypeParser( "application/json", { parseAs: "buffer" }, function (_req, body, done) { try { done(null, body) } catch (error) { error.statusCode = 400 done(error, undefined) } } ) done(null) }) //Login Supplier Handler exports.loginSupplier = async(request, reply) =>{ loginObject = await supplierController.loginSupplier(request); console.log("loginObject...",loginObject) if (loginObject.same) { const phoneVerified = loginObject.supplier.phoneVerified; const oneTimePasswordSetFlag = loginObject.supplier.oneTimePasswordSetFlag; console.log( "oneTimePasswordSetFlag is ......", oneTimePasswordSetFlag, typeof oneTimePasswordSetFlag, typeof phoneVerified ); if (!phoneVerified) { reply.send({ simplydata: { error: false, phoneVerified: false, phone: loginObject.supplier.phone, oneTimePasswordSetFlag: oneTimePasswordSetFlag, message: "Please Verify your phone number", }, }); } else if (oneTimePasswordSetFlag) { reply.send({ simplydata: { error: false, phoneVerified: phoneVerified, phone: loginObject.supplier.phone, oneTimePasswordSetFlag: true, message: "Password must be reset", }, }); } else { const token = fastify.jwt.sign( { suppliername: loginObject.supplier.suppliername, supplierId: loginObject.supplier._id, roles: loginObject.supplier.profile.role, }, //expiresIn: expressed in seconds or a string describing a time span zeit/ms. Eg: 60, "2 days", "10h", "7d". //A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (days, hours, etc), //otherwise milliseconds unit is used by default ("120" is equal to "120ms"). { expiresIn: "30d" } ); console.log(token, "..token") var arr = loginObject.supplier.profile.role; var arrayToString = JSON.stringify(Object.assign({}, arr)); // convert array to string var stringToJsonObject = JSON.parse(arrayToString); // convert string to json object var s_id = loginObject.supplier.supplierId console.log(s_id,"supplierId") var profilePicture = await ProfilePicture.findOne({ supplierId:s_id}); // request.session.set('supplierId', loginObject.supplier._id) if (!profilePicture) { reply.send({ simplydata: { error: false, apiversion: fastify.config.APIVERSION, access_token: token, email: loginObject.supplier.emails, phone: loginObject.supplier.phone, supplierId: loginObject.supplier.supplierId, suppliername: loginObject.supplier.suppliername, office_address: loginObject.supplier.profile.office_address, phoneVerified: loginObject.supplier.phoneVerified, oneTimePasswordSetFlag: loginObject.supplier.oneTimePasswordSetFlag, type: loginObject.supplier.profile.role, typeasobj: stringToJsonObject, }, }); }if (profilePicture) { reply.send({ simplydata: { error: false, apiversion: fastify.config.APIVERSION, access_token: token, picture:profilePicture.picture, email: loginObject.supplier.emails, phone: loginObject.supplier.phone, supplierId: loginObject.supplier.supplierId, suppliername: loginObject.supplier.suppliername, office_address: loginObject.supplier.profile.office_address, phoneVerified: loginObject.supplier.phoneVerified, oneTimePasswordSetFlag: loginObject.supplier.oneTimePasswordSetFlag, type: loginObject.supplier.profile.role, typeasobj: stringToJsonObject, }, }); } } } else { error = { simplydata: { error: true, code: 400, message: "Invalid SupplierId , Password supplied", }, }; reply.send(error); } } // Check if all the required fields are supplied by the user exports.fieldCheck = async (req, reply) => { try { s_Data = { suppliername: req.body.suppliername, emails: req.body.emails, password: req.body.password, services: { password: {bcrypt: req.body.password} }, phone: req.body.phone, profile: { firstName: req.body.firstName, lastName: req.body.lastName, contactNumber: req.body.phone, alternativeContactNumber: req.body.alternativeContactNumber, country: req.body.country, state: req.body.state, city: req.body.city, office_address: req.body.office_adress, zip: req.body.zip, }, }; var supplier = new Supplier(s_Data); console.log(supplier,"..supplier") //password is not at the top level in the collection. password = req.body.password; // capture fields if data is sent via form instead of json encoding checkFormEncoding = isSupplierFormUrlEncoded(req); if (checkFormEncoding.isSupplierFormUrlEncoded) { suppliertobeInserted = checkFormEncoding.supplier; supplier.suppliername = suppliertobeInserted.suppliername; supplier.phone = suppliertobeInserted.phone; supplier.emails = suppliertobeInserted.emails; password = suppliertobeInserted.password; } console.log("User to be inserted is ", supplier.suppliername,password,supplier.phone,supplier.profile); // check if all rerquired fields are passed. if ( !( supplier.suppliername && password && supplier.phone && // user.profile.firstName && // user.profile.lastName && // user.profile.address1 && supplier.emails[0].email ) ) { console.log( supplier.suppliername, password, supplier.phone, // user.profile.firstName, // user.profile.lastName, supplier.emails[0].email ); // Required Fields are missing suppliedvalues = supplier.suppliername + " ," + password + " ," + supplier.phone + " ," + supplier.firstName + " ," + supplier.lastName + " ," + supplier.emails[0].email; error = { armintatankdata: { error: true, code: 10004, message: "10004 - suppliername, password, phone , firstname , lastname email city country state address1 and zip are required fields. Supplied values are " + suppliedvalues, }, }; req.body.regError = error; reply.send(error); } } catch (err) { throw boom.boomify(err); } }; exports.validatePhoneFormat = async (req, reply) => { try { var supplier = new Supplier(req.body); // check if user supplied phone is of the right format. // Handle if the user data is supplied via a url encoded form // capture fields if data is sent via form instead of json encoding checkFormEncoding = isSupplierFormUrlEncoded(req); console.log(checkFormEncoding); if (checkFormEncoding.isSupplierFormUrlEncoded) { suppliertobeInserted = checkFormEncoding.supplier; supplier.suppliername = suppliertobeInserted.suppliername; supplierser.firstName = suppliertobeInserted.firstName; supplier.lastName = suppliertobeInserted.lastName; supplier.phone = suppliertobeInserted.phone; supplier.emails = suppliertobeInserted.emails; } if (supplier) { const phoneNumber = libphonenumberjs.parsePhoneNumber(supplier.phone); if (phoneNumber) { // access returned collection if (!phoneNumber.isValid()) { error = { armintatankdata: { error: true, code: 10002, message: "10002 - Phone # " + supplier.phone + " is not a valid phone number", }, }; req.body.regError = error; reply.status(406).send(error); } } } } catch (err) { throw boom.boomify(err); } }; exports.verifySupplier = async (req, reply) => { try { var supplier = new Supplier(req.body); // Handle if the user data is supplied via a url encoded form // capture fields if data is sent via form instead of json encoding checkFormEncoding = isSupplierFormUrlEncoded(req); if (checkFormEncoding.isSupplierFormUrlEncoded) { suppliertobeInserted = checkFormEncoding.supplier; supplier.suppliername = suppliertobeInserted.suppliername; supplier.firstName = suppliertobeInserted.firstName; supplier.lastName = suppliertobeInserted.lastName; supplierr.phone = suppliertobeInserted.phone; supplier.emails = suppliertobeInserted.emails; } phone = supplier.phone; supplierpass = req.body.password; // check if user exists in the system. If user exists , display message that // phone number is not available supplierExists = await Supplier.findOne({ phone: phone }); if (supplierExists) { // return user exists message error = { armintatankdata: { error: true, code: 10001, message: "10001 - Phone " + supplierExists.phone + " is not available. please use a different phone number", }, }; req.body.regError = error; reply.send(error); } } catch (err) { throw boom.boomify(err); } }; exports.validateEmailFormat = async (req, reply) => { try { var supplier = new Supplier(req.body); // Handle if the user data is supplied via a url encoded form // capture fields if data is sent via form instead of json encoding checkFormEncoding = isSupplierFormUrlEncoded(req); if (checkFormEncoding.isSupplierFormUrlEncoded) { suppliertobeInserted = checkFormEncoding.supplier; supplier.suppliername = suppliertobeInserted.suppliername; supplier.firstName = suppliertobeInserted.firstName; supplier.lastName = suppliertobeInserted.lastName; supplierr.phone = suppliertobeInserted.phone; supplier.emails = suppliertobeInserted.emails; } supplieremail = await supplier.emails[0].email; // check if user supplied email is of the right format. if (supplier) { const isValidEmail = emailValidator.validate(supplieremail.trim()); if (!isValidEmail) { // Return email invalid format message error = { armintatankdata: { error: true, code: 10003, message: "10003 - Email " + supplier.emails[0].email + " is not a valid email", }, }; req.body.regError = error; reply.send(error); } } } catch (err) { throw boom.boomify(err); } }; exports.logoutsupplier = async (request, reply) => { // request.session.delete(); // // send response to clear token // reply.send({ message: 'Successfully logged out' }) const invalidatedTokens = {}; const accessToken = request.headers.authorization && request.body.access_token; invalidatedTokens[accessToken] = true; // // localStorage.removeItem(invalidatedTokens[accessToken]) reply.send({ message: 'Logout successful' }) } exports.verifyPhone = async (req, reply) => { console.log("-------------------------------------------------"); try { phone = req.body.phone; phoneVerificationCode = req.body.phoneVerificationCode; // check if user exists in the system. If user exists , display message that // username is not available console.log( "this is the phone and verification code", phone, phoneVerificationCode ); supplierExists = await Supplier.findOne({ phone: phone, phoneVerified: false, phoneVerificationCode: phoneVerificationCode, }); console.log(supplierExists); if (supplierExists) { // update the phoneVerified flag to true. const filter = { phone: phone, phoneVerificationCode: phoneVerificationCode, }; const update = { phoneVerified: true }; const doc = await Supplier.findOneAndUpdate(filter, update); updatedSupplier = await Supplier.findOne({ phone: phone }); if (updatedSupplier.phoneVerified) { reply.send('{"armintatankdata":{"error":false,"verified": true}}'); } else { error = { armintatankdata: { error: true, code: 10005, message: "10005 - Verification code entered cannot be validated.", }, }; req.body.regError = error; reply.send(error); } } else { error = { armintatankdata: { error: true, code: 10005, message: "10005 - Verification code entered cannot be validated.", }, }; req.body.regError = error; reply.send(error); } } catch (err) { throw boom.boomify(err); } }; // Get current supplier exports.getCurrentSupplier = async (req, reply) => { try { const supplierId = req.body.supplierId; const suppliers = await Supplier.findOne({ supplierId: supplierId }); return suppliers; } catch (err) { throw boom.boomify(err); } }; // Get all users exports.getSuppliers = async (req, reply) => { const limit = parseInt(req.query.limit) || 100; const page = parseInt(req.query.page) || 1; const startindex = (page - 1) * limit; try { await Supplier.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.getSingleSupplier = async (req, reply) => { try { const supplierId = req.params.supplierId; const supplier = await Supplier.findOne({ supplierId: supplierId }); return supplier; } catch (err) { throw boom.boomify(err); } };