generated from Arquisoft/wiq_0
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #134 from Arquisoft/132-add-a-forget-password-func…
…tionality Forget password
- Loading branch information
Showing
41 changed files
with
1,186 additions
and
234 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -108,7 +108,7 @@ | |
depends_on: | ||
- gatewayservice | ||
ports: | ||
- "3000:3000" | ||
- "80:80" | ||
|
||
prometheus: | ||
image: prom/prometheus | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,12 +9,25 @@ const YAML = require('yaml') | |
const jwt = require('jsonwebtoken'); | ||
const app = express(); | ||
const port = 8000; | ||
//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 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()); | ||
|
||
|
@@ -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); | ||
|
@@ -235,4 +291,30 @@ function manageError(res, 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) { | ||
// Configuración del correo | ||
const mailOptions = { | ||
from: process.env.EMAIL_USER, | ||
to: email, | ||
subject: 'Hello ' + username + ' this is the wiqen1b team', | ||
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) { | ||
res.status(500).send('Error sending email'); | ||
} | ||
} | ||
|
||
module.exports = server |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ const request = require('supertest'); | |
const axios = require('axios'); | ||
const jwt = require('jsonwebtoken'); | ||
const app = require('./gateway-service'); | ||
const nodemailer = require('nodemailer'); | ||
|
||
afterAll(async () => { | ||
app.close(); | ||
|
@@ -12,8 +13,6 @@ jest.mock('jsonwebtoken'); | |
|
||
jest.mock('axios'); | ||
|
||
|
||
|
||
describe('Gateway Service with mocked micro services', () => { | ||
|
||
// Mock responses from external services | ||
|
@@ -24,6 +23,10 @@ describe('Gateway Service with mocked micro services', () => { | |
return Promise.resolve({ data: { username: 'newuser' } }); | ||
} else if(url.endsWith('/record')){ | ||
return Promise.resolve({data : {user:'testuser'}}) | ||
} else if(url.endsWith('/forgetPassword')){ | ||
return Promise.resolve({data : { token: 'mockedToken', username : 'testuser', email:"[email protected]"}}) | ||
} else if(url.endsWith('/changePassword')){ | ||
return Promise.resolve({data : {token: 'mockedToken', username : 'testuser', email:"[email protected]"}}) | ||
} | ||
}); | ||
|
||
|
@@ -60,6 +63,14 @@ describe('Gateway Service with mocked micro services', () => { | |
callback(null, "decoded"); | ||
}); | ||
|
||
|
||
//Mock nodemailer | ||
jest.mock('nodemailer', () => ({ | ||
createTransport: jest.fn().mockReturnValue({ | ||
sendMail: jest.fn(), | ||
}), | ||
})); | ||
|
||
// Test /login endpoint | ||
it('should forward login request to auth service', async () => { | ||
const response = await request(app) | ||
|
@@ -146,6 +157,42 @@ describe('Gateway Service with mocked micro services', () => { | |
|
||
}); | ||
|
||
//Test /forgetPassword | ||
it('should forward the request and send an email', async () => { | ||
const response = await request(app) | ||
.post('/forgetPassword') | ||
.send({ email: '[email protected]', username: 'testuser'}); | ||
expect(response.statusCode).toBe(200); | ||
expect(response.text).toBe('Email sent successfully'); | ||
}) | ||
|
||
//Test tokenFromCode/:code | ||
it('should find a token', async () => { | ||
//First generate the code:token | ||
|
||
const fixedTimestamp = 1683078000000; | ||
jest.spyOn(Date, 'now').mockReturnValue(fixedTimestamp); | ||
|
||
await request(app) | ||
.post('/forgetPassword') | ||
.send({ email: '[email protected]', username: 'testuser'}); | ||
const response = await request(app).get('/tokenFromCode/000000'); | ||
|
||
expect(response.statusCode).toBe(200); | ||
expect(response.body).toHaveProperty('token', "mockedToken"); | ||
}) | ||
|
||
//Test /changePassword | ||
it('should forward the request', async () => { | ||
const response = await request(app) | ||
.post('/changePassword') | ||
.send({ username: 'testuser', password: 'newpassword' }) | ||
.set('token', 'valorDelToken'); | ||
|
||
expect(response.statusCode).toBe(200); | ||
expect(response.body.username).toBe('testuser'); | ||
}) | ||
|
||
}); | ||
|
||
function checkRecord(response){ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -84,6 +84,153 @@ paths: | |
type: string | ||
description: Error information. | ||
example: Internal Server Error | ||
/forgetPassword: | ||
post: | ||
summary: Sends a forget password alert to the server | ||
operationId: forgetPassword | ||
requestBody: | ||
required: true | ||
content: | ||
application/json: | ||
schema: | ||
type: object | ||
properties: | ||
email: | ||
type: string | ||
description: User email | ||
example: [email protected] | ||
username: | ||
type: string | ||
description: User name | ||
example: student | ||
responses: | ||
'200': | ||
description: Email sent successfully | ||
content: | ||
application/json: | ||
schema: | ||
type: string | ||
example: "Email sent successfully" | ||
'400': | ||
description: Failed to find user | ||
content: | ||
application/json: | ||
schema: | ||
type: object | ||
properties: | ||
error: | ||
type: string | ||
description: Error information. | ||
example: No user found, review credentials | ||
'500': | ||
description: Internal server error. | ||
content: | ||
application/json: | ||
schema: | ||
type: object | ||
properties: | ||
error: | ||
type: string | ||
description: Error information. | ||
example: Internal Server Error | ||
/tokenFromCode{code}: | ||
get: | ||
summary: Get a token from a 6 digit code | ||
parameters: | ||
- name: code | ||
in: path | ||
required: true | ||
schema: | ||
type: string | ||
responses: | ||
'200': | ||
description: Code found returns token | ||
content: | ||
application/json: | ||
schema: | ||
type: object | ||
properties: | ||
token: | ||
type: string | ||
'400': | ||
description: Invalid code | ||
content: | ||
application/json: | ||
schema: | ||
type: string | ||
example: "Invalid code" | ||
'500': | ||
description: Internal server error. | ||
content: | ||
application/json: | ||
schema: | ||
type: object | ||
properties: | ||
error: | ||
type: string | ||
description: Error information. | ||
example: Internal Server Error | ||
/changePassword: | ||
post: | ||
summary: Changes the password of the authorized user | ||
parameters: | ||
- name: token | ||
in: header | ||
schema: | ||
type: string | ||
operationId: changePassword | ||
requestBody: | ||
required: true | ||
content: | ||
application/json: | ||
schema: | ||
type: object | ||
properties: | ||
email: | ||
type: string | ||
description: User email | ||
example: [email protected] | ||
username: | ||
type: string | ||
description: User name | ||
example: student | ||
password: | ||
type: string | ||
description: User password | ||
example: password123 | ||
repeatPassword: | ||
type: string | ||
description: Userpassword | ||
example: password123 | ||
responses: | ||
'200': | ||
description: Email sent successfully | ||
content: | ||
application/json: | ||
schema: | ||
$ref: '#/components/schemas/LoginResponse' | ||
'400': | ||
description: Failed to find user | ||
content: | ||
application/json: | ||
schema: | ||
type: object | ||
properties: | ||
error: | ||
type: string | ||
description: Error information. | ||
example: No user found, review credentials | ||
'500': | ||
description: Internal server error. | ||
content: | ||
application/json: | ||
schema: | ||
type: object | ||
properties: | ||
error: | ||
type: string | ||
description: Error information. | ||
example: Internal Server Error | ||
/login: | ||
post: | ||
summary: Log in to the system. | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.