register otp and verify otp

This commit is contained in:
pawan-dot 2024-06-25 15:18:07 +05:30
parent 0f2200fd25
commit f49468d00e
8 changed files with 325 additions and 17 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"editor.formatOnSave": true
}

View File

@ -11,22 +11,12 @@ const transporter = createTransport({
}, },
}); });
// const mailOptions = {
// from: process.env.SMPT_MAIL,
// to: options.email,
// subject: options.subject,
// text: options.message,
// };
const sendEmail = async (options) => { const sendEmail = async (options) => {
// console.log(options);
await transporter.sendMail(options, function (error, info) { await transporter.sendMail(options, function (error, info) {
if (error) { if (error) {
console.log(error); console.log(error);
} }
// else {
// console.log("Email sent: " + info?.response);
// }
}); });
}; };
export default sendEmail; export default sendEmail;
@ -39,3 +29,29 @@ export default sendEmail;
// } // }
// export default sendEmail // export default sendEmail
// from message bird send mail------------------------------------
// messageSender.js
// import messagebird from "messagebird";
// const apiKey = "7oOgyzfNuwBnqMc2oK6aGfczs";
// const messagebirdClient = messagebird(apiKey);
import { initClient } from "messagebird";
const messagebird = initClient("e7HGr3kMl6su4c79DKjNAwlLQ");
export const sendOtp = (recipient, message) => {
const params = {
originator: "TestMessage",
recipients: `+918874747774`,
body: "hi how are you",
};
messagebird.messages.create(params, (err, response) => {
if (err) {
console.error("Error sending message:", err);
return;
}
console.log("Message sent successfully:", response);
console.log("Message rrrrrrrrrrrrrrrr:", response?.recipients?.items);
});
};

6
app.js
View File

@ -137,6 +137,8 @@ import StateRouter from "./resources/setting/state/state_routes.js";
import LanguageRoute from "./resources/setting/Language/language_routes.js"; import LanguageRoute from "./resources/setting/Language/language_routes.js";
//purpose //purpose
import PurposeRoute from "./resources/setting/Purpose/Purpose_routes.js"; import PurposeRoute from "./resources/setting/Purpose/Purpose_routes.js";
//Patient Routes
import PatientRoute from './resources/Patients/PatientRoute.js'
// category Route // category Route
import categoryRoute from "./resources/Category/categoryRoutes.js"; import categoryRoute from "./resources/Category/categoryRoutes.js";
@ -193,6 +195,10 @@ app.use("/api/content", ContentRoute);
// User Address // User Address
app.use("/api/user-address", UserAddressRoute); app.use("/api/user-address", UserAddressRoute);
app.use("/api/shipping/address", ShippingAddressRoute); app.use("/api/shipping/address", ShippingAddressRoute);
//Patient Routes
app.use("/api/patient", PatientRoute);
//Order //Order
app.use("/api/order", orderRoute); app.use("/api/order", orderRoute);
//Departure //Departure

56
package-lock.json generated
View File

@ -21,6 +21,7 @@
"express-fileupload": "^1.4.0", "express-fileupload": "^1.4.0",
"generate-password": "^1.7.0", "generate-password": "^1.7.0",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"messagebird": "^4.0.1",
"micro": "^10.0.1", "micro": "^10.0.1",
"mongoose": "^6.3.5", "mongoose": "^6.3.5",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",
@ -2326,6 +2327,14 @@
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
}, },
"node_modules/jose": {
"version": "4.15.7",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.7.tgz",
"integrity": "sha512-L7ioP+JAuZe8v+T5+zVI9Tx8LtU8BL7NxkyDFVMv+Qr3JW0jSoYDedLtodaXwfqMpeCyx4WXFNyu9tJt4WvC1A==",
"funding": {
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/js-git": { "node_modules/js-git": {
"version": "0.7.8", "version": "0.7.8",
"resolved": "https://registry.npmjs.org/js-git/-/js-git-0.7.8.tgz", "resolved": "https://registry.npmjs.org/js-git/-/js-git-0.7.8.tgz",
@ -2527,6 +2536,19 @@
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
}, },
"node_modules/messagebird": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/messagebird/-/messagebird-4.0.1.tgz",
"integrity": "sha512-Abn0aoH1Dzsq5KMeI3LNanVETwu4+HvNXZrhWRGzRIJ9ea88sefsVfy98Qj4NDmxGuXLFmT8Lhgw1kStzu7F0g==",
"dependencies": {
"jose": "^4.9.2",
"safe-buffer": "^5.2.1",
"scmp": "^2.1.0"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/methods": { "node_modules/methods": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@ -3789,6 +3811,11 @@
"resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz",
"integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA=="
}, },
"node_modules/scmp": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/scmp/-/scmp-2.1.0.tgz",
"integrity": "sha512-o/mRQGk9Rcer/jEEw/yw4mwo3EU/NvYvp577/Btqrym9Qy5/MdWGBqipbALgd2lrdWTJ5/gqDusxfnQBxOxT2Q=="
},
"node_modules/secure-random": { "node_modules/secure-random": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/secure-random/-/secure-random-1.1.2.tgz", "resolved": "https://registry.npmjs.org/secure-random/-/secure-random-1.1.2.tgz",
@ -5417,8 +5444,7 @@
"cloudinary-core": { "cloudinary-core": {
"version": "2.12.3", "version": "2.12.3",
"resolved": "https://registry.npmjs.org/cloudinary-core/-/cloudinary-core-2.12.3.tgz", "resolved": "https://registry.npmjs.org/cloudinary-core/-/cloudinary-core-2.12.3.tgz",
"integrity": "sha512-Ll4eDzcrIVn4zCttMh3Mdi+KNz07p5EEjBT2PQSRx8Eok1lKPt3uBBenOk/w88RKK3B8SFIWcEe/mN4BHQ0p8A==", "integrity": "sha512-Ll4eDzcrIVn4zCttMh3Mdi+KNz07p5EEjBT2PQSRx8Eok1lKPt3uBBenOk/w88RKK3B8SFIWcEe/mN4BHQ0p8A=="
"requires": {}
}, },
"color-convert": { "color-convert": {
"version": "2.0.1", "version": "2.0.1",
@ -6276,6 +6302,11 @@
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
}, },
"jose": {
"version": "4.15.7",
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.7.tgz",
"integrity": "sha512-L7ioP+JAuZe8v+T5+zVI9Tx8LtU8BL7NxkyDFVMv+Qr3JW0jSoYDedLtodaXwfqMpeCyx4WXFNyu9tJt4WvC1A=="
},
"js-git": { "js-git": {
"version": "0.7.8", "version": "0.7.8",
"resolved": "https://registry.npmjs.org/js-git/-/js-git-0.7.8.tgz", "resolved": "https://registry.npmjs.org/js-git/-/js-git-0.7.8.tgz",
@ -6460,6 +6491,16 @@
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="
}, },
"messagebird": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/messagebird/-/messagebird-4.0.1.tgz",
"integrity": "sha512-Abn0aoH1Dzsq5KMeI3LNanVETwu4+HvNXZrhWRGzRIJ9ea88sefsVfy98Qj4NDmxGuXLFmT8Lhgw1kStzu7F0g==",
"requires": {
"jose": "^4.9.2",
"safe-buffer": "^5.2.1",
"scmp": "^2.1.0"
}
},
"methods": { "methods": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@ -6661,8 +6702,7 @@
"multer-storage-cloudinary": { "multer-storage-cloudinary": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/multer-storage-cloudinary/-/multer-storage-cloudinary-4.0.0.tgz", "resolved": "https://registry.npmjs.org/multer-storage-cloudinary/-/multer-storage-cloudinary-4.0.0.tgz",
"integrity": "sha512-25lm9R6o5dWrHLqLvygNX+kBOxprzpmZdnVKH4+r68WcfCt8XV6xfQaMuAg+kUE5Xmr8mJNA4gE0AcBj9FJyWA==", "integrity": "sha512-25lm9R6o5dWrHLqLvygNX+kBOxprzpmZdnVKH4+r68WcfCt8XV6xfQaMuAg+kUE5Xmr8mJNA4gE0AcBj9FJyWA=="
"requires": {}
}, },
"mute-stream": { "mute-stream": {
"version": "0.0.8", "version": "0.0.8",
@ -7397,6 +7437,11 @@
"resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz",
"integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA=="
}, },
"scmp": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/scmp/-/scmp-2.1.0.tgz",
"integrity": "sha512-o/mRQGk9Rcer/jEEw/yw4mwo3EU/NvYvp577/Btqrym9Qy5/MdWGBqipbALgd2lrdWTJ5/gqDusxfnQBxOxT2Q=="
},
"secure-random": { "secure-random": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/secure-random/-/secure-random-1.1.2.tgz", "resolved": "https://registry.npmjs.org/secure-random/-/secure-random-1.1.2.tgz",
@ -7895,8 +7940,7 @@
"ws": { "ws": {
"version": "7.4.6", "version": "7.4.6",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A=="
"requires": {}
}, },
"xregexp": { "xregexp": {
"version": "2.0.0", "version": "2.0.0",

View File

@ -23,6 +23,7 @@
"express-fileupload": "^1.4.0", "express-fileupload": "^1.4.0",
"generate-password": "^1.7.0", "generate-password": "^1.7.0",
"jsonwebtoken": "^8.5.1", "jsonwebtoken": "^8.5.1",
"messagebird": "^4.0.1",
"micro": "^10.0.1", "micro": "^10.0.1",
"mongoose": "^6.3.5", "mongoose": "^6.3.5",
"multer": "^1.4.5-lts.1", "multer": "^1.4.5-lts.1",

View File

@ -0,0 +1,112 @@
// import hashPassword from '../utils/hashPassword';
import crypto from 'crypto';
import Patient from './PatientModel.js'
export const register = async (req, res) => {
const { name, mobileNumber } = req.body;
try {
let patient = await Patient.findOne({ mobileNumber });
if (patient && patient.isVerified) {
return res.status(400).json({ message: 'Patient already registered and verified for This Mobile No.' });
}
const otp = crypto.randomInt(100000, 1000000).toString();
// const otp ="123456";
const otpExpires = Date.now() + 10 * 60 * 1000; // 10 minutes
if (patient) {
patient.otp = otp;
patient.otpExpires = otpExpires;
} else {
patient = new Patient({ name, mobileNumber, otp, otpExpires });
}
await patient.save();
// await sendOtp(mobileNumber, otp);
res.status(200).json({patient, message: `OTP ${otp} sent to your mobile number successfully` });
} catch (error) {
res.status(500).json({
message: error.message ? error.message : "Server error!",
});
}
};
export const verifyOtp = async (req, res) => {
const { mobileNumber, otp } = req.body;
try {
const patient = await Patient.findOne({ mobileNumber });
if (!patient) {
return res.status(400).json({ message: 'Invalid mobile number or OTP' });
}
if (patient.otp !== otp || patient.otpExpires < Date.now()) {
return res.status(400).json({ message: 'Invalid or expired OTP' });
}
patient.isVerified = true;
patient.otp = undefined;
patient.otpExpires = undefined;
await patient.save();
res.status(200).json({patient, message: 'Mobile number verified successfully' });
} catch (error) {
res.status(500).json({
message: error.message ? error.message : "Server error!",
}); }
};
export const completeRegistration = async (req, res) => {
const {
mobileNumber,
email,
password,
confirmPassword,
gender,
weight,
height,
age,
commonHealthComplaints,
familyHistory,
personalHistory,
dailyRoutine,
} = req.body;
if (password !== confirmPassword) {
return res.status(400).json({ message: 'Password and confirm password do not match' });
}
try {
const patient = await Patient.findOne({ mobileNumber });
if (!patient || !patient.isVerified) {
return res.status(400).json({ message: 'Patient not found or not verified' });
}
// const hashedPassword = await hashPassword(password);
patient.email = email;
patient.password = hashedPassword;
patient.gender = gender;
patient.weight = weight;
patient.height = height;
patient.age = age;
patient.commonHealthComplaints = commonHealthComplaints;
patient.familyHistory = familyHistory;
patient.personalHistory = personalHistory;
patient.dailyRoutine = dailyRoutine;
await patient.save();
res.status(200).json({ message: 'Registration details updated successfully' });
} catch (error) {
res.status(500).json({
message: error.message ? error.message : "Server error!",
});
}
};

View File

@ -0,0 +1,114 @@
import dotenv from "dotenv";
dotenv.config();
import mongoose from "mongoose";
import validator from "validator";
import bcrypt from "bcryptjs";
import jwt from "jsonwebtoken";
import crypto from "crypto";
const patientSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
},
mobileNumber: {
type: String,
required: true,
unique: true,
},
otp: {
type: String,
required: false,
},
otpExpires: {
type: Date,
},
isVerified: {
type: Boolean,
default: false,
},
deviceAdded: {
type: Boolean,
default: false,
},
email: String,
password: {
type: String,
minLength: [6, "Password should be greater than 6 characters"],
select: false, //find not got passpord
},
avatar: {
public_id: {
type: String,
// required: true,
},
url: {
type: String,
// required: true,
},
},
gender: {
type: String,
enum: ['Male', 'Female'],
},
weight: {
type: String,
enum: ['Kilos', 'Lbs'],
},
height: {
type: String,
enum: ['Feet', 'Cms'],
},
age: Number,
commonHealthComplaints: String,
familyHistory: String,
personalHistory: String,
dailyRoutine: String,
resetPasswordToken: String,
resetPasswordExpire: Date,
},
{ timestamps: true }
);
patientSchema.pre("save", async function (next) {
if (!this.isModified("password")) {
next();
}
this.password = await bcrypt.hash(this.password, 10);
});
// JWT TOKEN
patientSchema.methods.getJWTToken = function () {
return jwt.sign({ id: this._id }, process.env.JWT_SECRET);
};
// Compare Password
patientSchema.methods.comparePassword = async function (password) {
return await bcrypt.compare(password, this.password);
};
// Generating Reset Token
patientSchema.methods.getResetPasswordToken = function () {
// Generating Token
const resetToken = crypto.randomBytes(20).toString("hex");
// Hashing and adding reset PasswordToken to patientSchema
this.resetPasswordToken = crypto
.createHash("sha256")
.update(resetToken)
.digest("hex");
//expire password time
// console.log(this.resetPasswordToken)
this.resetPasswordExpire = Date.now() + 15 * 60 * 1000; //15 minut
return resetToken;
};
const Patient = mongoose.model("Patient", patientSchema);
export default Patient;

View File

@ -0,0 +1,12 @@
import express from "express";
const router = express.Router();
// import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js";
import { completeRegistration, register, verifyOtp } from "./PatientController.js";
router.post('/register', register);
router.post('/verify-otp', verifyOtp);
router.post('/complete-registration', completeRegistration);
export default router;