Skip to content

Commit

Permalink
Forget password done in the backend
Browse files Browse the repository at this point in the history
  • Loading branch information
Mister-Mario committed Apr 27, 2024
1 parent b1289a4 commit 9e3addd
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 10 deletions.
91 changes: 88 additions & 3 deletions gatewayservice/gateway-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,26 @@ const fs = require("fs")
const YAML = require('yaml')
const jwt = require('jsonwebtoken');
const app = express();
const port = 8000;
const port = 8010;
//Setting up the email
const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: "[email protected]",
pass: "akskfqgakjvcswyg ",
},
});

const authServiceUrl = process.env.AUTH_SERVICE_URL || 'http://localhost:8002';
const userServiceUrl = process.env.USER_SERVICE_URL || 'http://localhost:8001';
const userServiceUrl = process.env.USER_SERVICE_URL || 'http://localhost:8011';
const questionServiceUrl = process.env.QUESTION_SERVICE_URL || 'http://localhost:8003';
const recordServiceUrl = process.env.RECORD_SERVICE_URL || 'http://localhost:8004';


var forgetPasswords = new Map()

app.use(cors());
app.use(express.json());

Expand All @@ -41,7 +54,50 @@ app.post('/adduser', async (req, res) => {
try {
// Forward the add user request to the user service
const userResponse = await axios.post(userServiceUrl+'/adduser', req.body);
console.log(userResponse)
res.json(userResponse.data);
} catch (error) {
manageError(res, error);

}
});

app.post('/forgetPassword', async (req, res) => {
try {
// Forward the forget password request to the user service
const userResponse = await axios.post(userServiceUrl+'/forgetPassword', req.body);

let sixNumbers = getRandomSixDigitNumber();
while(forgetPasswords.has(sixNumbers))
sixNumbers = getRandomSixDigitNumber();

forgetPasswords.set(sixNumbers, userResponse.data.token)
await sendEmail(res, userResponse.data.email, userResponse.data.username, sixNumbers)
} catch (error) {
manageError(res, error);

}
});

app.get('/tokenFromCode/:code', async (req, res) => {
try {
var code = parseInt(req.params.code);
if(forgetPasswords.has(code)){
var token = forgetPasswords.get(code)
forgetPasswords.delete(code)
res.json({token: token});
}
else
res.status(400).json({ error : "Invalid code" });
} catch (error) {
manageError(res, error);

}
});

app.post('/changePassword', verifyToken, async (req, res) => {
try {
// Forward the forget password request to the user service
const userResponse = await axios.post(userServiceUrl+'/changePassword', req.body);
res.json(userResponse.data);
} catch (error) {
manageError(res, error);
Expand Down Expand Up @@ -229,10 +285,39 @@ function validateUser(user){
}

function manageError(res, error){
console.log(error)
if(error.response) //Some microservice responded with an error
res.status(error.response.status).json({ error: error.response.data.error });
else //Some other error
res.status(500).json({error : "Internal server error"})
}

function getRandomSixDigitNumber() {
const now = Date.now(); // Gets the current timestamp
const lastSixDigits = now.toString().slice(-6); // Gets the last 6 digits as a string
return parseInt(lastSixDigits, 10); // Converts it back to an integer
}

async function sendEmail(res, email, username, numbers) {
console.log(numbers)
// Configuración del correo
const mailOptions = {
from: process.env.EMAIL_USER, // Remitente
to: email, // Destinatario
subject: 'Hello ' + username + ' this is the wiqen1b team', // Asunto
text: 'We see that you have requested a password change.\n' +
'Please introduce the code: ' + numbers + '. You have around 10 minutes to change your password \n' +
'In case you have not requested a password change forget this email existance',
};

try {
// Envía el correo
await transporter.sendMail(mailOptions);
res.send('Email sent successfully');
} catch (error) {
console.error('Error sending email:', error);
res.status(500).send('Error sending email');
}
}

module.exports = server
9 changes: 9 additions & 0 deletions gatewayservice/package-lock.json

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

3 changes: 2 additions & 1 deletion gatewayservice/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
"cors": "^2.8.5",
"express": "^4.18.2",
"express-openapi": "^12.1.3",
"jsonwebtoken": "^9.0.2",
"express-prom-bundle": "^7.0.0",
"jsonwebtoken": "^9.0.2",
"nodemailer": "^6.9.13",
"swagger-ui-express": "^5.0.0",
"yaml": "^2.4.1"
},
Expand Down
79 changes: 73 additions & 6 deletions users/userservice/user-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const jwt = require('jsonwebtoken');
const User = require('./user-model')

const app = express();
const port = 8001;
const port = 8011;

// Middleware to parse JSON in request body
app.use(bodyParser.json());
Expand All @@ -31,10 +31,11 @@ function validateRequiredFields(req, requiredFields) {
}
}

let email = req.body.email.toString();
let username = req.body.username.toString();
let password = req.body.password.toString();
let repeatPassword = req.body.repeatPassword.toString();
//If there are not here is because they dont need to be, it has being check before which need to be here
let email = req.body.email ? req.body.email.toString() : "[email protected]";
let username = req.body.username ? req.body.username.toString() : "example";
let password = req.body.password ? req.body.password.toString() : "123456789";
let repeatPassword = req.body.repeatPassword ? req.body.repeatPassword.toString() : "123456789";

if(!validateEmail(email)){
//User put a wrong format email
Expand Down Expand Up @@ -106,7 +107,73 @@ app.post('/adduser', async (req, res) => {
res.json({ token: token, username: savedUser.username, email: savedUser.email});
} catch (error) {
res.status(400).json({ error: error.message });
}});
}}
);

app.post('/forgetPassword', async (req, res) => {
try {
// Check if required fields are present in the request body
try{
validateRequiredFields(req, ['email', 'username']);
}
catch(error){
res.status(400).json({ error : error.message });
return
}
//Check there is a user with that name
const userUsername = await User.findOne({username: req.body.username.toString()});

if(!userUsername || userUsername.email !== req.body.email)
return res.status(400).json({error : "No user found, review credentials"})


const token = jwt.sign({ userId: userUsername._id }, (process.env.JWT_KEY??'my-key'), { expiresIn: '15m' });

res.json({ token: token, username: userUsername.username, email: userUsername.email});
} catch (error) {
res.status(400).json({ error: error.message });
}}
);

app.post('/changePassword', async (req, res) => {
try {
// Check if required fields are present in the request body
try{
validateRequiredFields(req, ['email', 'username', 'password', 'repeatPassword']);
}
catch(error){
res.status(400).json({ error : error.message });
console.log(res)
return
}


//Check there is a user with that name
const userUsername = await User.findOne({username: req.body.username.toString()});

if(!userUsername || userUsername.email !== req.body.email)
return res.status(400).json({error : "No user found, review credentials"})

// Encrypt the password before saving it
const hashedPassword = await bcrypt.hash(req.body.password, 10);

const result = await User.updateOne(
{ _id: userUsername._id },
{ $set: { password: hashedPassword } }
);

if (result.nModified === 0) {
res.status(404).send('User not found or no change');
} else {
const token = jwt.sign({ userId: userUsername._id }, (process.env.JWT_KEY??'my-key'), { expiresIn: '1h' });
res.json({ token: token, username: userUsername.username, email: userUsername.email});
}


} catch (error) {
res.status(400).json({ error: error.message });
}}
);

const server = app.listen(port, () => {
console.log(`User Service listening at http://localhost:${port}`);
Expand Down

0 comments on commit 9e3addd

Please sign in to comment.