Commit b6dc4521 authored by Vitor Hugo Garcez's avatar Vitor Hugo Garcez Committed by Aléxia Dorneles
Browse files

[RECUPERAÇÃO DE SENHA] Rota patch para alterar senha

parent 60fe5deb
Pipeline #5734 passed with stages
in 4 minutes and 56 seconds
Showing with 173 additions and 16 deletions
+173 -16
PORT=numero da porta onde o servidor vai subir, exemplo: 3000
DB_CONNECTION=mongodb://localhost:<porta que o seu mongodb tá rodando>/idosomais?authMechanism=DEFAULT&authSource=idosomais
JWT_SECRET= segredo qualquer para gerar tokens JWT
SALT_VALUE= valor utilizado para criptografar senhas, exemplo: 10
\ No newline at end of file
SALT_VALUE= valor utilizado para criptografar senhas, exemplo: 10
NEW_PASSWORD_SIZE= valor utilizado para definir o tamanho da senha nova ao recupera-la, exemplo: 8
SENDGRID_API_KEY= chave da api do sendgrid
\ No newline at end of file
......@@ -15,6 +15,7 @@
"@nestjs/mongoose": "^9.2.0",
"@nestjs/passport": "^9.0.0",
"@nestjs/platform-express": "^9.0.0",
"@sendgrid/mail": "^7.7.0",
"bcrypt": "^5.0.1",
"class-transformer": "^0.5.1",
"class-validator": "^0.13.2",
......@@ -1837,6 +1838,41 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/@sendgrid/client": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-7.7.0.tgz",
"integrity": "sha512-SxH+y8jeAQSnDavrTD0uGDXYIIkFylCo+eDofVmZLQ0f862nnqbC3Vd1ej6b7Le7lboyzQF6F7Fodv02rYspuA==",
"dependencies": {
"@sendgrid/helpers": "^7.7.0",
"axios": "^0.26.0"
},
"engines": {
"node": "6.* || 8.* || >=10.*"
}
},
"node_modules/@sendgrid/helpers": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-7.7.0.tgz",
"integrity": "sha512-3AsAxfN3GDBcXoZ/y1mzAAbKzTtUZ5+ZrHOmWQ279AuaFXUNCh9bPnRpN504bgveTqoW+11IzPg3I0WVgDINpw==",
"dependencies": {
"deepmerge": "^4.2.2"
},
"engines": {
"node": ">= 6.0.0"
}
},
"node_modules/@sendgrid/mail": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-7.7.0.tgz",
"integrity": "sha512-5+nApPE9wINBvHSUxwOxkkQqM/IAAaBYoP9hw7WwgDNQPxraruVqHizeTitVtKGiqWCKm2mnjh4XGN3fvFLqaw==",
"dependencies": {
"@sendgrid/client": "^7.7.0",
"@sendgrid/helpers": "^7.7.0"
},
"engines": {
"node": "6.* || 8.* || >=10.*"
}
},
"node_modules/@sinclair/typebox": {
"version": "0.24.28",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.28.tgz",
......@@ -2766,6 +2802,14 @@
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"dev": true
},
"node_modules/axios": {
"version": "0.26.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
"integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
"dependencies": {
"follow-redirects": "^1.14.8"
}
},
"node_modules/babel-jest": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz",
......@@ -3556,7 +3600,6 @@
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
......@@ -4396,6 +4439,25 @@
"integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==",
"dev": true
},
"node_modules/follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/fork-ts-checker-webpack-plugin": {
"version": "7.2.11",
"resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.11.tgz",
......@@ -10323,6 +10385,32 @@
}
}
},
"@sendgrid/client": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-7.7.0.tgz",
"integrity": "sha512-SxH+y8jeAQSnDavrTD0uGDXYIIkFylCo+eDofVmZLQ0f862nnqbC3Vd1ej6b7Le7lboyzQF6F7Fodv02rYspuA==",
"requires": {
"@sendgrid/helpers": "^7.7.0",
"axios": "^0.26.0"
}
},
"@sendgrid/helpers": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-7.7.0.tgz",
"integrity": "sha512-3AsAxfN3GDBcXoZ/y1mzAAbKzTtUZ5+ZrHOmWQ279AuaFXUNCh9bPnRpN504bgveTqoW+11IzPg3I0WVgDINpw==",
"requires": {
"deepmerge": "^4.2.2"
}
},
"@sendgrid/mail": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-7.7.0.tgz",
"integrity": "sha512-5+nApPE9wINBvHSUxwOxkkQqM/IAAaBYoP9hw7WwgDNQPxraruVqHizeTitVtKGiqWCKm2mnjh4XGN3fvFLqaw==",
"requires": {
"@sendgrid/client": "^7.7.0",
"@sendgrid/helpers": "^7.7.0"
}
},
"@sinclair/typebox": {
"version": "0.24.28",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.28.tgz",
......@@ -11100,6 +11188,14 @@
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"dev": true
},
"axios": {
"version": "0.26.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
"integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
"requires": {
"follow-redirects": "^1.14.8"
}
},
"babel-jest": {
"version": "28.1.3",
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz",
......@@ -11690,8 +11786,7 @@
"deepmerge": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
"dev": true
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
},
"defaults": {
"version": "1.0.3",
......@@ -12339,6 +12434,11 @@
"integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==",
"dev": true
},
"follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
},
"fork-ts-checker-webpack-plugin": {
"version": "7.2.11",
"resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.11.tgz",
......
export interface UserEmail {
email: string;
}
......@@ -7,7 +7,7 @@ import { EncryptorService } from '../../security/encryptor.service';
import { UserFromJwt } from '../auth/models/user-auth';
import { HealthDataDto } from './health/health-data.dto';
import { UserController } from './user.controller';
import { UserCreateDto, UserUpdateDto } from './user.dto';
import { UserCreateDto } from './user.dto';
import { UserService } from './user.service';
const userDataMock: UserEntity = {
......@@ -156,26 +156,18 @@ describe('UserController', () => {
describe('update', () => {
it('deve atualizar usuário', async () => {
const dto: UserUpdateDto = {
contatoEmergencia: userDataMock.contatoEmergencia,
telefone: userDataMock.telefone,
};
findByIdAndUpdateMock.mockReturnValue({
select: jest.fn().mockResolvedValue(userDataMock),
});
/* const result = await userController.update(dto, userDataMock);
/* const result = await userController.update(dto, userDataMock);
expect(result.contatoEmergencia).toEqual(dto.contatoEmergencia); */
});
it('se id não existir deve lançar erro', async () => {
const dto: UserUpdateDto = {
contatoEmergencia: userDataMock.contatoEmergencia,
telefone: userDataMock.telefone,
};
findByIdAndUpdateMock.mockReturnValue({
select: jest.fn().mockRejectedValue(userDataMock),
});
/* expect(userController.update(dto, userDataMock)).rejects.toThrowError(
/* expect(userController.update(dto, userDataMock)).rejects.toThrowError(
NotFoundException,
); */
});
......
......@@ -17,6 +17,7 @@ import { UserCreateDto } from './user.dto';
import { UserService } from './user.service';
import { ContactDataDtoList } from './contacts/contact-data.dto';
import { UserUpdateDto } from './userUpdate.dto';
import { UserEmail } from './user-recovery';
@Controller('/user')
......@@ -29,6 +30,12 @@ export class UserController {
return this.userService.findAll();
}
@Patch('/password')
@IsPublic()
async recoveryPassword(@Body() userEmail: UserEmail): Promise<UserDocument>{
return await this.userService.recoveryPassword(userEmail.email);
}
@Get()
async getCurrent(@CurrentUser() user: UserFromJwt): Promise<UserDocument> {
return await this.userService.findById(user._id);
......
import {
BadRequestException,
Injectable,
InternalServerErrorException,
Logger,
NotFoundException,
} from '@nestjs/common';
......@@ -28,6 +29,57 @@ export class UserService {
private readonly encryptor: EncryptorService,
) {}
async recoveryPassword(email: string): Promise<UserDocument> {
const user = await this.findByEmailOrCpfOrTelefone(
email,
undefined,
undefined,
);
if (user) {
let newPassword = '';
const possibleCharacters = 'ABCDEFGHIJKLMNOPQRSTUVXYWZ';
const newPasswordSize = process.env
.NEW_PASSWORD_SIZE as unknown as number;
for (let i = 0; i < newPasswordSize; i++) {
newPassword += possibleCharacters.charAt(
Math.floor(Math.random() * 26),
);
}
user.password = await this.encryptor.encrypt(newPassword);
await this.userModel.updateOne({ _id: user._id }, user);
await this.sendUserMail(user.email, newPassword);
return user;
}
throw new NotFoundException('Email não está vinculado a um usuário.');
}
async sendUserMail(email: string, newPassword: string): Promise<void> {
if (process.env.SENDGRID_API_KEY) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const msg = {
to: email,
from: 'ages.idosomais@gmail.com',
subject: 'Idoso+ - Recuperação de Conta',
text: 'Sua nova senha é: ' + newPassword,
html: '<p>Sua nova senha é: ' + newPassword + '</p>',
};
await sgMail
.send(msg)
.then((response) => {
return response;
})
.catch((error) => {
throw new InternalServerErrorException(
'Email impossivel de ser enviado' + error,
);
});
}
}
async updateHealthData(
user: UserFromJwt,
healthDataDto: HealthDataDto,
......@@ -75,7 +127,7 @@ export class UserService {
return res;
},
(err) => {
throw new NotFoundException('Usuário Inexistente');
throw new NotFoundException('Usuário Inexistente' + err);
},
);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment