Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
YehiaFarghaly committed Oct 14, 2023
2 parents 69522ec + 7d15a68 commit 3ed7d89
Show file tree
Hide file tree
Showing 10 changed files with 186 additions and 29 deletions.
2 changes: 2 additions & 0 deletions authentication/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import morgan from 'morgan';
import cookieParser from 'cookie-parser';
import dotenv from 'dotenv';
import { user } from './src/api/user.js';
import { resetPassword } from './src/api/resetPassword.js';
import { PORT } from './src/utils/Constants.js';
import cors from 'cors';

Expand Down Expand Up @@ -36,6 +37,7 @@ const connect = async () => {
await connect();

user(app);
resetPassword(app);

const port = PORT;

Expand Down
24 changes: 23 additions & 1 deletion authentication/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion authentication/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
"express": "^4.18.2",
"jsonwebtoken": "^9.0.2",
"mongoose": "^7.6.0",
"morgan": "^1.10.0"
"morgan": "^1.10.0",
"nodemailer": "^6.9.6",
"uuid": "^9.0.1"
},
"devDependencies": {
"eslint": "^8.51.0",
Expand Down
77 changes: 77 additions & 0 deletions authentication/src/api/resetPassword.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import ResetPasswordService from "../service/reset-password-service.js";
import UserService from "../service/user-service.js";
import nodemailer from 'nodemailer';
import { v4 as uuidv4 } from 'uuid';
import { BAD_REQUEST_CODE_400 } from "../utils/Constants.js";
export const resetPassword = (app) => {

const resetPassword = new ResetPasswordService();
const user = new UserService();

const generateUniqueToken = () => {
return uuidv4();
}

function generateRandom6DigitNumber() {
const min = 100000; // Minimum 6-digit number
const max = 999999; // Maximum 6-digit number

// Generate a random number in the range [min, max]
const randomNumber = Math.floor(Math.random() * (max - min + 1)) + min;

return randomNumber;
}

app.post('/reset-password', async (req, res) => {
const { email } = req.body;
const OTP = generateRandom6DigitNumber();

try {
const userRecord = await user.findUserByEmail(email);
console.log(userRecord);
if(!userRecord ){
throw new Error('invalid user');
} else if(!userRecord.email){
throw new Error('invalid Email');
}

// TODO: access the reset password database
await resetPassword.removeRecordByEmail(email);
await resetPassword.addRecord(email, OTP);

const transporter = nodemailer.createTransport({
service: 'Gmail',
host: "setup.gmail.com",
port: 587,
secure: false,
auth: {
user: process.env.RESETEMAIL,
pass: process.env.RESETPASSWORD,
},
});


const mailOptions = {
from: {
name:'acl lab',
address:`${process.env.RESETEMAIL}`},
to: [email],
subject: 'Password Reset',
text: `Click this link to reset your password: http://localhost:3000/reset-password/${OTP}`,
};

transporter.sendMail(mailOptions, (error, info) => {
if (error) {
console.log(error);
res.status(500).json({ message: 'Failed to send email' });
} else {
console.log(`Email sent: ${info.response}`);
res.json({ message: 'Email sent' });
}
});
} catch(err){
console.log(err);
res.status(BAD_REQUEST_CODE_400).send({ errMessage: err.message});
}
});
}
4 changes: 4 additions & 0 deletions authentication/src/api/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
import jwt from 'jsonwebtoken';
import axios from 'axios';


export const user = (app) => {
const user = new UserService();

Expand All @@ -27,6 +28,8 @@ export const user = (app) => {
});
};



app.post('/signup', async (req, res) => {
try {
const { type } = req.body;
Expand Down Expand Up @@ -169,6 +172,7 @@ export const user = (app) => {
}
});


app.get('/check-user', async (req, res) => {
const token = req.cookies.jwt;
if (token) {
Expand Down
21 changes: 21 additions & 0 deletions authentication/src/database/models/ResetPassword.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import mongoose from "mongoose";

const resetSchema = mongoose.Schema({
email: {
type:String,
required:true
},
OTP: {
type:String,
required:true
},
resetTokenExpiration: {
type:Date,
required:true,
default: new Date((new Date()).getTime() + 24 * 60 * 60 * 1000)
},
});

const ResetPassword = mongoose.model('ResetPassword', resetSchema);

export default ResetPassword;
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import ResetPassword from "../models/ResetPassword.js";

class ResetPasswordRepository{
async getRecordByEmail(email){
const user = await ResetPassword.findOne({email: email});
return user;
}

async removeRecordByEmail(email){
const user = await ResetPassword.deleteOne({email: email});
return user;
}

async addRecord(email, OTP){
const record = new ResetPassword({email, OTP});
await record.save();
}
}

export default ResetPasswordRepository;
26 changes: 26 additions & 0 deletions authentication/src/service/reset-password-service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import ResetPasswordRepository from "../database/repository/reset-password-repository.js";

class ResetPasswordService {
constructor() {
this.repository = new ResetPasswordRepository();

}

async getRecordByEmail(email){
const user = await this.repository.getRecordByEmail(email);
return user;
}

async removeRecordByEmail(email){
const user = await this.repository.removeRecordByEmail(email);
return user;
}

async addRecord(email, OTP){
const user = await this.repository.addRecord(email, OTP);
return user;
}

}

export default ResetPasswordService;
24 changes: 0 additions & 24 deletions client/src/pages/DoctorRequests.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,30 +55,6 @@ const DoctorRequests = () => {
console.error('Error accepting doctor request:', error);
});

doctorReq.type = 'doctor';
// Add the doctor to the users table
fetch('http://localhost:8004/doctors', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: doctorReq._id,
email: doctorReq.userData.email,
password: doctorReq.userData.password,
userName: doctorReq.userData.userName,
type: doctorReq.type,
}),
})
.then((response) => response.json())
.then(() => {
setDoctorRequests((prevDoctorRequests) =>
prevDoctorRequests.filter(
(doctorRequest) => doctorRequest._id !== doctorReq._id,
),
);
})
.catch((error) => {
console.error('Error accepting doctor request:', error);
});
};

const handleReject = (doctorReq) => {
Expand Down
13 changes: 10 additions & 3 deletions clinic/src/api/DoctorAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,17 @@ export const doctor = (app) => {
app.post('/doctors', async (req, res) => {
try {
const newDoctor = await service.createDoctor(req.body);
res.status(CREATED_STATUS_CODE).json({
message: 'Doctor created!',
newDoctor,
await axios.post(`${AUTH_BASE_URL}/doctors`, {
userId: newDoctor._id,
email: newDoctor.userData.email,
password: newDoctor.userData.password,
userName: newDoctor.userData.userName,
type: DOCTOR_ENUM,
});

res
.status(CREATED_STATUS_CODE)
.json({ message: 'Doctor created!', newDoctor });
} catch (err) {
res.status(ERROR_STATUS_CODE).json({ err: err.message });
}
Expand Down

0 comments on commit 3ed7d89

Please sign in to comment.