register otp and verify otp
This commit is contained in:
parent
0f2200fd25
commit
f49468d00e
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"editor.formatOnSave": true
|
||||
}
|
@ -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) => {
|
||||
// console.log(options);
|
||||
await transporter.sendMail(options, function (error, info) {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
}
|
||||
// else {
|
||||
// console.log("Email sent: " + info?.response);
|
||||
// }
|
||||
|
||||
});
|
||||
};
|
||||
export default sendEmail;
|
||||
@ -39,3 +29,29 @@ 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
6
app.js
@ -137,6 +137,8 @@ import StateRouter from "./resources/setting/state/state_routes.js";
|
||||
import LanguageRoute from "./resources/setting/Language/language_routes.js";
|
||||
//purpose
|
||||
import PurposeRoute from "./resources/setting/Purpose/Purpose_routes.js";
|
||||
//Patient Routes
|
||||
import PatientRoute from './resources/Patients/PatientRoute.js'
|
||||
|
||||
// category Route
|
||||
import categoryRoute from "./resources/Category/categoryRoutes.js";
|
||||
@ -193,6 +195,10 @@ app.use("/api/content", ContentRoute);
|
||||
// User Address
|
||||
app.use("/api/user-address", UserAddressRoute);
|
||||
app.use("/api/shipping/address", ShippingAddressRoute);
|
||||
//Patient Routes
|
||||
app.use("/api/patient", PatientRoute);
|
||||
|
||||
|
||||
//Order
|
||||
app.use("/api/order", orderRoute);
|
||||
//Departure
|
||||
|
56
package-lock.json
generated
56
package-lock.json
generated
@ -21,6 +21,7 @@
|
||||
"express-fileupload": "^1.4.0",
|
||||
"generate-password": "^1.7.0",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"messagebird": "^4.0.1",
|
||||
"micro": "^10.0.1",
|
||||
"mongoose": "^6.3.5",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
@ -2326,6 +2327,14 @@
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"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": {
|
||||
"version": "0.7.8",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "1.1.2",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/secure-random/-/secure-random-1.1.2.tgz",
|
||||
@ -5417,8 +5444,7 @@
|
||||
"cloudinary-core": {
|
||||
"version": "2.12.3",
|
||||
"resolved": "https://registry.npmjs.org/cloudinary-core/-/cloudinary-core-2.12.3.tgz",
|
||||
"integrity": "sha512-Ll4eDzcrIVn4zCttMh3Mdi+KNz07p5EEjBT2PQSRx8Eok1lKPt3uBBenOk/w88RKK3B8SFIWcEe/mN4BHQ0p8A==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-Ll4eDzcrIVn4zCttMh3Mdi+KNz07p5EEjBT2PQSRx8Eok1lKPt3uBBenOk/w88RKK3B8SFIWcEe/mN4BHQ0p8A=="
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
@ -6276,6 +6302,11 @@
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"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": {
|
||||
"version": "0.7.8",
|
||||
"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",
|
||||
"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": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
@ -6661,8 +6702,7 @@
|
||||
"multer-storage-cloudinary": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/multer-storage-cloudinary/-/multer-storage-cloudinary-4.0.0.tgz",
|
||||
"integrity": "sha512-25lm9R6o5dWrHLqLvygNX+kBOxprzpmZdnVKH4+r68WcfCt8XV6xfQaMuAg+kUE5Xmr8mJNA4gE0AcBj9FJyWA==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-25lm9R6o5dWrHLqLvygNX+kBOxprzpmZdnVKH4+r68WcfCt8XV6xfQaMuAg+kUE5Xmr8mJNA4gE0AcBj9FJyWA=="
|
||||
},
|
||||
"mute-stream": {
|
||||
"version": "0.0.8",
|
||||
@ -7397,6 +7437,11 @@
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz",
|
||||
"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": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/secure-random/-/secure-random-1.1.2.tgz",
|
||||
@ -7895,8 +7940,7 @@
|
||||
"ws": {
|
||||
"version": "7.4.6",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
|
||||
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
|
||||
"requires": {}
|
||||
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A=="
|
||||
},
|
||||
"xregexp": {
|
||||
"version": "2.0.0",
|
||||
|
@ -23,6 +23,7 @@
|
||||
"express-fileupload": "^1.4.0",
|
||||
"generate-password": "^1.7.0",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"messagebird": "^4.0.1",
|
||||
"micro": "^10.0.1",
|
||||
"mongoose": "^6.3.5",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
|
112
resources/Patients/PatientController.js
Normal file
112
resources/Patients/PatientController.js
Normal 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!",
|
||||
});
|
||||
|
||||
}
|
||||
};
|
114
resources/Patients/PatientModel.js
Normal file
114
resources/Patients/PatientModel.js
Normal 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;
|
||||
|
||||
|
||||
|
12
resources/Patients/PatientRoute.js
Normal file
12
resources/Patients/PatientRoute.js
Normal 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;
|
Loading…
Reference in New Issue
Block a user