From 24da5964b36e9b104d78e97e871b5072c2bc639e Mon Sep 17 00:00:00 2001 From: varun Date: Thu, 4 Jul 2024 04:26:37 -0400 Subject: [PATCH] store signup and login --- src/controllers/storeController.js | 189 ++++++++++++++++++++++++++++- src/customAuthJwt.js | 5 + src/index.js | 101 +++++++++++++++ src/models/store.js | 79 +++++++++++- src/routes/storeRoute.js | 48 ++++++++ 5 files changed, 418 insertions(+), 4 deletions(-) diff --git a/src/controllers/storeController.js b/src/controllers/storeController.js index a626373f..b12e13be 100644 --- a/src/controllers/storeController.js +++ b/src/controllers/storeController.js @@ -1,7 +1,7 @@ const boom = require("boom"); const bcrypt = require('bcrypt'); const jwt = require('jsonwebtoken'); - +const customJwtAuth = require("../customAuthJwt"); const fastify = require("fastify")({ logger: true, //disableRequestLogging: true, @@ -9,9 +9,10 @@ const fastify = require("fastify")({ // you get access to the req here if you need it - must be a synchronous function return uuidv4(); }, -});const { Install, ProfilePictureInstall, generateinstallationId } = require("../models/store"); +}); +const { Install, ProfilePictureInstall, generateinstallationId,Store} = require("../models/store"); + -const supplierController = require("../controllers/supplierController") @@ -316,3 +317,185 @@ exports.installSignUp = async (request, reply) => { throw boom.boomify(err); } }; + + + const generateStoreId = async () => { + const result = await Counter.findOneAndUpdate( + { _id: 'store_id' }, + { $inc: { seq: 1 } }, + { upsert: true, new: true } + ); + return result.seq; + }; + + + exports.addStore = async (req, reply) => { + try { + var s_id = await generateStoreId(); + var building = ((req.body.storename).slice(0, 3)).toUpperCase(); + var store_id = `AWSST${building}${s_id}`; + + s_data = { + storeId: store_id, + storename: req.body.storename, + emails: req.body.emails, + password: req.body.password, + phone: req.body.phone, + description: req.body.description, + profile: { + firstName: req.body.firstName, + lastName: req.body.lastName, + contactNumber: req.body.phone, + alternativeContactNumber: req.body.alternativeContactNumber, + office_address: req.body.office_address, + country: req.body.country, + state: req.body.state, + city: req.body.city, + zip: req.body.zip, + }, + latitude: req.body.latitude, + longitude: req.body.longitude, + fcmId: req.body.fcmId, + }; + + var store = new Store(s_data); + storepass = req.body.password; + + // Store hash in your password DB. + hash = await bcryptPassword(storepass); + + if (hash) { + store.services.password.bcrypt = hash; + if (req.body.role) { + store.profile.role = req.body.role; + } else { + role = ["store"]; + store.profile.role = role; + } + + insertedStore = await store.save(); + if (insertedStore) { + var retStore = { + armintatankdata: { + storename: insertedStore.storename, + phone: insertedStore.phone, + storeId: insertedStore.storeId, + office_address: insertedStore.profile.office_address, + emails: [ + { + email: insertedStore.emails[0].email, + }, + ], + profile: insertedStore.profile, + latitude: insertedStore.latitude, + longitude: insertedStore.longitude, + fcmId: insertedStore.fcmId, + description: insertedStore.description, + }, + status_code: 200, + }; + + return retStore; + } + } + } catch (err) { + throw boom.boomify(err); + } + }; + + + + + + // exports.loginStore = async (request, reply) => { + // try { + // let store = await Store.findOne({ phone: request.body.phone }); + // if (!store) { + // return reply.code(400).send({ + // simplydata: { + // error: true, + // code: 400, + // message: "Invalid Phone or Password", + // }, + // }); + // } + + // const isMatch = await bcrypt.compare(request.body.password, store.services.password.bcrypt); + // if (!isMatch) { + // return reply.code(400).send({ + // simplydata: { + // error: true, + // code: 400, + // message: "Invalid Phone or Password", + // }, + // }); + // } + + // const token = request.jwt.sign( + // { + // storename: store.storename, + // storeId: store._id, + // roles: store.profile.role, + // }, + // { expiresIn: "30d" } + // ); + + // var profilePicture = await profilePictureStore.findOne({ storeId: store.storeId }); + + // if (!profilePicture) { + // reply.send({ + // simplydata: { + // error: false, + // apiversion: fastify.config.APIVERSION, + // access_token: token, + // email: store.emails, + // phone: store.phone, + // storeId: store.storeId, + // storename: store.storename, + // office_address: store.profile.office_address, + // phoneVerified: store.phoneVerified, + // oneTimePasswordSetFlag: store.oneTimePasswordSetFlag, + // latitude: store.latitude, + // longitude: store.longitude, + // description: store.description, + // type: store.profile.role, + // typeasobj: JSON.stringify(Object.assign({}, store.profile.role)), + // }, + // }); + // } else { + // reply.send({ + // simplydata: { + // error: false, + // apiversion: fastify.config.APIVERSION, + // access_token: token, + // picture: profilePicture.picture, + // email: store.emails, + // phone: store.phone, + // storeId: store.storeId, + // storename: store.storename, + // office_address: store.profile.office_address, + // phoneVerified: store.phoneVerified, + // oneTimePasswordSetFlag: store.oneTimePasswordSetFlag, + // latitude: store.latitude, + // longitude: store.longitude, + // description: store.description, + // type: store.profile.role, + // typeasobj: JSON.stringify(Object.assign({}, store.profile.role)), + // }, + // }); + // } + // } catch (err) { + // reply.send({ + // simplydata: { + // error: true, + // code: 500, + // message: err.message, + // }, + // }); + // } + // }; + + + + + \ No newline at end of file diff --git a/src/customAuthJwt.js b/src/customAuthJwt.js index 63d8509a..d8bd4a7f 100644 --- a/src/customAuthJwt.js +++ b/src/customAuthJwt.js @@ -46,6 +46,11 @@ async function customJwtAuth(fastify, opts, next) { reply.send(err); } }); + next() } + + + + module.exports = fp(customJwtAuth, { fastify: ">=1.0.0" }); diff --git a/src/index.js b/src/index.js index caf1bf82..d4f8f58e 100644 --- a/src/index.js +++ b/src/index.js @@ -7,6 +7,7 @@ const createConnectionController = require("./controllers/createConnectionContro const storeController = require("./controllers/storeController.js") const boom = require("boom"); const bcrypt = require('bcrypt'); +const { ProfilePictureStore,generateinstallationId,Store} = require("./models/store"); const cors = require("cors"); @@ -416,6 +417,106 @@ console.log(user) }); +fastify.post("/api/storelogin", { + schema: { + description: "This is for Store Login", + tags: ["Store-Data"], + summary: "This is for Store Login", + body: { + type: "object", + required: ["phone", "password"], + properties: { + phone: { type: "string" }, + password: { type: "string" }, + }, + }, + }, + async handler(request, reply) { + try { + let store = await Store.findOne({ phone: request.body.phone }); + if (!store) { + return reply.code(400).send({ + simplydata: { + error: true, + code: 400, + message: "Invalid Phone or Password", + }, + }); + } + + const isMatch = await bcrypt.compare(request.body.password, store.services.password.bcrypt); + if (!isMatch) { + return reply.code(400).send({ + simplydata: { + error: true, + code: 400, + message: "Invalid Phone or Password", + }, + }); + } + + + + const token = fastify.jwt.sign( + { + storename: store.storename, + storeId: store._id, + roles: store.profile.role, + }, + { expiresIn: "30d" } + ); + + + var profilePicture = await ProfilePictureStore.findOne({ storeId: store.storeId }); + + if (!profilePicture) { + reply.send({ + simplydata: { + error: false, + apiversion: fastify.config.APIVERSION, + access_token: token, + email: store.emails, + phone: store.phone, + storeId: store.storeId, + storename: store.storename, + office_address: store.profile.office_address, + phoneVerified: store.phoneVerified, + oneTimePasswordSetFlag: store.oneTimePasswordSetFlag, + latitude: store.latitude, + longitude: store.longitude, + description: store.description, + type: store.profile.role, + typeasobj: JSON.stringify(Object.assign({}, store.profile.role)), + }, + }); + } else { + reply.send({ + simplydata: { + error: false, + apiversion: fastify.config.APIVERSION, + access_token: token, + picture: profilePicture.picture, + email: store.emails, + phone: store.phone, + storeId: store.storeId, + storename: store.storename, + office_address: store.profile.office_address, + phoneVerified: store.phoneVerified, + oneTimePasswordSetFlag: store.oneTimePasswordSetFlag, + latitude: store.latitude, + longitude: store.longitude, + description: store.description, + type: store.profile.role, + typeasobj: JSON.stringify(Object.assign({}, store.profile.role)), + }, + }); + } + } catch (err) { + throw boom.boomify(err); + } + }, +}); + fastify.get("/api/reset_token/:customerId", { schema: { diff --git a/src/models/store.js b/src/models/store.js index f0e5c692..b6d7109e 100644 --- a/src/models/store.js +++ b/src/models/store.js @@ -2,6 +2,7 @@ const mongoose = require('mongoose') const Schema = mongoose.Schema; const ObjectId = Schema.Types.ObjectId; const { Counter} = require('../models/User') +const code = Math.floor(100000 + Math.random() * 900000); const generateinstallationId = async () => { @@ -80,9 +81,85 @@ const installationschema = new mongoose.Schema({ } }); + const profilePictureStoreSchema = new Schema({ + storeId: { + type: String, + unique: true, + required: true + }, + picture: { + type: String, // Change the type to String + required: true, + validate: { + validator: function (value) { + const supportedFormats = ['jpg', 'jpeg', 'png']; + const fileExtension = value.split('.').pop().toLowerCase(); + return supportedFormats.includes(fileExtension); + }, + message: 'Picture must be a JPEG, PNG, or JPG image' + } + } + }); + + const storeSchema = new mongoose.Schema({ + storename: { type: String }, + phone: { type: String, unique: true, trim: true }, + storeId: { type: String, default: null }, + phoneVerified: { type: Boolean, default: false }, + phoneVerificationCode: { type: Number, default: 11111 }, + passwordResetCode: { type: Number, default: code }, + oneTimePasswordSetFlag: { type: Boolean, default: false }, + emails: [{ email: String, verified: { type: Boolean, default: false } }], + services: { password: { bcrypt: String } }, + description: { type: String, default: null }, + startingPrice: { type: String, default: 0.0 }, + profile: { + role: [{ type: String, default: "store" }], + firstName: { type: String, default: null }, + lastName: { type: String, default: null }, + contactNumber: { type: String, default: null }, + alternativeContactNumber: { type: String, default: null }, + office_address: { type: String, default: null }, + city: { type: String, default: null }, + state: { type: String, default: null }, + country: { type: String, default: null }, + zip: { type: String, default: null }, + }, + status: { + type: String, + enum: ['inactive', 'active'], + default: 'active' + }, + longitude: { type: Number, default: 0.0 }, + latitude: { type: Number, default: 0.0 }, + isActive: Boolean, + tenantId: ObjectId, + fcmId: { type: String, default: null }, + createdAt: { + type: Date, + default: function () { + return Date.now(); + }, + }, + createdBy: ObjectId, + updatedAt: { + type: Date, + default: function () { + return Date.now(); + }, + }, + updatedBy: ObjectId, + }, { versionKey: false }); + + + + + const Store = mongoose.model("Store", storeSchema); + + const ProfilePictureStore = mongoose.model('ProfilePictureStore', profilePictureStoreSchema); const ProfilePictureInstall = mongoose.model('ProfilePictureInstall', profilePictureInstallSchema); const Install = mongoose.model("Install", installationschema); - module.exports = { Install, ProfilePictureInstall, generateinstallationId}; + module.exports = { Install, ProfilePictureInstall, generateinstallationId,Store,ProfilePictureStore}; diff --git a/src/routes/storeRoute.js b/src/routes/storeRoute.js index 6fc5a910..de77f6de 100644 --- a/src/routes/storeRoute.js +++ b/src/routes/storeRoute.js @@ -1,5 +1,8 @@ const fastify = require("fastify"); const storeController = require('../controllers/storeController') +const customJwtAuth = require('../customAuthJwt'); +const fastifyJwt = require('fastify-jwt'); + module.exports = function (fastify, opts, next) { @@ -88,5 +91,50 @@ module.exports = function (fastify, opts, next) { // }); +fastify.post('/api/stores', { + schema: { + description: "This is for Create New Store", + tags: ["Store-Data"], + summary: "This is for Create New Store.", + body: { + type: "object", + properties: { + storename: { type: "string" }, + phone: { type: "string" }, + alternativeContactNumber: { type: "string" }, + password: { type: "string" }, + emails: { + type: "array", + maxItems: 2, + items: { + type: "object", + properties: { + email: { type: "string", default: null }, + }, + }, + }, + office_address: { type: "string", default: null }, + city: { type: "string", default: null }, + state: { type: "string", default: null }, + zip: { type: "string", default: null }, + country: { type: "string", default: null }, + latitude: { type: 'number', default: 0.0 }, + longitude: { type: 'number', default: 0.0 }, + fcmId: { type: "string", default: null }, + description: { type: "string", default: null }, + }, + }, + security: [{ basicAuth: [] }], + }, + // preHandler: [ + // validationHandler.fieldCheck, + // validationHandler.verifyStore, + // validationHandler.validateEmailFormat, + // ], + handler: storeController.addStore, +}); + + + next(); };