From 7febf7bf6a65a791ed3af37264225dac75c5a82f Mon Sep 17 00:00:00 2001 From: Gabriel Lopes Date: Sat, 24 Apr 2021 15:23:56 -0300 Subject: [PATCH 1/5] fix(authentication): create missing findByEmail method in userRepository and fix JWTEncrypter --- .gitignore | 1 + src/app/builds/controllers/add-user.ts | 12 +++++++++++- src/infra/database/repositories/access-token.ts | 8 ++++++++ src/infra/database/repositories/user-repository.ts | 5 +++++ src/infra/utils/jwt-encrypter.ts | 7 ++----- src/presentation/controllers/add-user.ts | 9 +++++---- src/usecases/implementation/auth-user.ts | 2 +- src/usecases/ports/access-token-repository.ts | 2 +- src/usecases/ports/user-repository.ts | 2 +- 9 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 src/infra/database/repositories/access-token.ts diff --git a/.gitignore b/.gitignore index 14a3da86..4de21f95 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ #custom *.pem +*.key* # Logs logs diff --git a/src/app/builds/controllers/add-user.ts b/src/app/builds/controllers/add-user.ts index 47590817..93685c02 100644 --- a/src/app/builds/controllers/add-user.ts +++ b/src/app/builds/controllers/add-user.ts @@ -6,6 +6,11 @@ import { DbAddUser } from '@/usecases/implementation/add-user' import { hashGenerator, idGenerator, userRepository } from '../infra' import { AddUserController } from '@/presentation/controllers/add-user' +import { UserAuthenticator } from '@/usecases/implementation/auth-user' +import { BcryptHasher } from '@/infra/utils/bcrypt-hasher' +import { TokenRepository } from '@/infra/database/repositories/access-token' +import { JWTEncrypter } from '@/infra/utils/jwt-encrypter' +import { TOKEN_DURATION, TOKEN_PRIVATE_KEY } from '@/config/env' const requiredFieldsValidation = new RequiredFieldValidation(['name', 'email', 'password']) const userValidator = new UserValidator() @@ -13,4 +18,9 @@ const validator = new ValidatorCompositor([requiredFieldsValidation, userValidat const dbAddUser = new DbAddUser(userRepository, idGenerator, hashGenerator) -export const addUserController = new AddUserController(validator, dbAddUser) +const hasher = new BcryptHasher() +const jwtEncrypter = new JWTEncrypter(TOKEN_PRIVATE_KEY, TOKEN_DURATION) +const repo = new TokenRepository() +export const authenticator = new UserAuthenticator(userRepository, hasher, jwtEncrypter, repo) + +export const addUserController = new AddUserController(validator, dbAddUser, authenticator) diff --git a/src/infra/database/repositories/access-token.ts b/src/infra/database/repositories/access-token.ts new file mode 100644 index 00000000..5bbe2eb7 --- /dev/null +++ b/src/infra/database/repositories/access-token.ts @@ -0,0 +1,8 @@ +import { AccessTokenRepository } from '@/usecases/ports/access-token-repository' +import fs from 'fs' + +export class TokenRepository implements AccessTokenRepository { + async add(token: string, userEmail: string): Promise { + fs.appendFileSync('./db.txt', `${token}-${userEmail},`) + } +} diff --git a/src/infra/database/repositories/user-repository.ts b/src/infra/database/repositories/user-repository.ts index 468c5a19..70035423 100644 --- a/src/infra/database/repositories/user-repository.ts +++ b/src/infra/database/repositories/user-repository.ts @@ -18,4 +18,9 @@ export class PsqlUserRepository extends Repository implements UserRep const user = await this.findOne({ email }) return !!user } + + public async findByEmail(email: string): Promise { + const user = await this.findOne({ email }) + return user + } } diff --git a/src/infra/utils/jwt-encrypter.ts b/src/infra/utils/jwt-encrypter.ts index c9efcea8..1b8b8f62 100644 --- a/src/infra/utils/jwt-encrypter.ts +++ b/src/infra/utils/jwt-encrypter.ts @@ -2,13 +2,10 @@ import { Encrypter } from '@/usecases/ports/encrypter' import { sign } from 'jsonwebtoken' export class JWTEncrypter implements Encrypter { - constructor(private readonly privateKey: string, private readonly tokenExpiration: string) {} + constructor(private readonly secretKey: string, private readonly tokenExpiration: string) {} async encrypt(payload: Object): Promise { - const token = sign(payload, this.privateKey, { - algorithm: 'RS256', - expiresIn: this.tokenExpiration - }) + const token = sign({ ...payload }, this.secretKey, { expiresIn: 60 * 15 }) return token } } diff --git a/src/presentation/controllers/add-user.ts b/src/presentation/controllers/add-user.ts index 7a326c06..f67e29e6 100644 --- a/src/presentation/controllers/add-user.ts +++ b/src/presentation/controllers/add-user.ts @@ -11,7 +11,7 @@ export interface AddUserResponse { name: string email: string } - token: string + accessToken: string } export class AddUserController implements Controller { @@ -29,12 +29,13 @@ export class AddUserController implements Controller { const result = await this.addUser.add(params) if (result instanceof Error) return conflict(result) - const { id, name, email, password } = result + const { id, name, email } = result - const token = (await this.authenticator.auth({ email, password })) as string + const token = (await this.authenticator.auth({ email, password: params.password })) as string - return ok({ user: { id, name, email }, token }) + return ok({ user: { id, name, email }, accessToken: token }) } catch (error) { + console.log(error) return serverError(error) } } diff --git a/src/usecases/implementation/auth-user.ts b/src/usecases/implementation/auth-user.ts index fa34fec6..790b4fd3 100644 --- a/src/usecases/implementation/auth-user.ts +++ b/src/usecases/implementation/auth-user.ts @@ -16,7 +16,7 @@ export class UserAuthenticator implements AuthUser { async auth(data: AuthParams): Promise { const { email, password } = data - const existingUser = await this.userRepository.findOne(email) + const existingUser = await this.userRepository.findByEmail(email) if (!existingUser) return new UnregisteredEmailError(email) const matchedPassword = await this.hashComparer.compare(password, existingUser.password) diff --git a/src/usecases/ports/access-token-repository.ts b/src/usecases/ports/access-token-repository.ts index 352722c3..c6b61387 100644 --- a/src/usecases/ports/access-token-repository.ts +++ b/src/usecases/ports/access-token-repository.ts @@ -1,3 +1,3 @@ export interface AccessTokenRepository { - add(token: string, userEmail: string): Promise + add(token: string, userEmail: string): Promise } diff --git a/src/usecases/ports/user-repository.ts b/src/usecases/ports/user-repository.ts index 2e21c078..4a8a13bb 100644 --- a/src/usecases/ports/user-repository.ts +++ b/src/usecases/ports/user-repository.ts @@ -3,5 +3,5 @@ import { User } from '@/domain/entities/user' export interface UserRepository { add(data: User): Promise exists(email: string): Promise - findOne(email: string): Promise + findByEmail(email: string): Promise } From 8d5ef748d6806f980835cd773bcc904e723ee2f3 Mon Sep 17 00:00:00 2001 From: MatheusFC2 Date: Sat, 24 Apr 2021 21:11:19 -0300 Subject: [PATCH 2/5] add img flag-brasil, turn lenguage --- .github/assets/flag-brasil.png | Bin 0 -> 3442 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .github/assets/flag-brasil.png diff --git a/.github/assets/flag-brasil.png b/.github/assets/flag-brasil.png new file mode 100644 index 0000000000000000000000000000000000000000..88c164383fae3e7e21119868217b49545880433c GIT binary patch literal 3442 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 literal 0 HcmV?d00001 From c92febca9a0d83ac4f1a030ee2f9e5e4d3496278 Mon Sep 17 00:00:00 2001 From: MatheusFC2 Date: Sat, 24 Apr 2021 21:12:15 -0300 Subject: [PATCH 3/5] add img flag-eua, turn lenguage --- .github/assets/flag-eua.jpg | Bin 0 -> 45640 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .github/assets/flag-eua.jpg diff --git a/.github/assets/flag-eua.jpg b/.github/assets/flag-eua.jpg new file mode 100644 index 0000000000000000000000000000000000000000..86b8e0051602b9708e4b940e2b54ba54a20e8589 GIT binary patch literal 45640 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 literal 0 HcmV?d00001 From ca9b24a32e5df0107512c86df951c807a35e743f Mon Sep 17 00:00:00 2001 From: MatheusFC2 Date: Sat, 24 Apr 2021 21:13:37 -0300 Subject: [PATCH 4/5] readme in portuguese, and contributors --- README-pt.md | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 README-pt.md diff --git a/README-pt.md b/README-pt.md new file mode 100644 index 00000000..0b7de535 --- /dev/null +++ b/README-pt.md @@ -0,0 +1,156 @@ +

+

Feedback.io

+ +#### Muda de Língua +

+ + flag-eua + +

+ +###### Uma API construída com + +

+ typescript + nodejs + graphql + socket.io + docker + postgresql + eslint + jest + heroku + typeorm +

+ +##### Aplicativo hospedado em: _[heroku](https://www.heroku.com/)_. + +##### Url da API: _https://api-feedbackio.herokuapp.com_. + +

Sobre Feedback.io 📚

+ +

+ Feedback.io está sendo construído para oferecer uma plataforma completa para que todos tenham um melhor controle sobre seus serviços e a opinião de seus clientes sobre eles. Aqui você pode se cadastrar na plataforma e criar serviços, que poderão receber feedbacks e taxas de seus clientes. Isso permitirá que você entre em contato com os feedbacks dos clientes, que podem ser PROBLEMAS, IDÉIAS ou OUTROS, e calcule o NPS de seus serviços, sabendo como seus clientes estão avaliando seus serviços. Este é um aplicativo de código aberto, que é construído usando Nodejs, incluindo muitos outros conceitos e novas tecnologias, como Typescript, princípios SOLID, Clean Architecture, DDD, TDD, Docker, PostgreSQL ... +

+ +## Estrutura da API + +![Clean Architecture Schema](.github/assets/clean-architecture.jpg) + +Esta estrutura de projeto é inspirada na estrutura de código de arquitetura limpa, [by Uncle Bob](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html). O principal objetivo da arquitetura limpa é criar uma estrutura de projeto forte, dividindo todo o aplicativo em camadas. As melhores vantagens de utilizá-lo, é criar uma aplicação independente de qualquer framework, ferramenta, banco de dados ou tecnologia, sendo fácil manipular o código, criar novas funcionalidades, corrigir qualquer problema, ou alterar algum framework, graças aos adaptadores e portas. + +#### Pastas 📚 + +``` +root +├── .github - Github setup files +│ └── assets +│ └── workflow +├── assets - Project assets (images, logos...) +├── src - Application main code +│ │── app - Composition layer, entry point code +│ │ └── routes - routes files +│ │ └── setup - server config (middlewares, cors, body-parser) +│ │ └── builds - classes instances +│ │ └── adapters - components adapters +│ ├── config - Some global config files (.env, path alias, logger) +│ ├── domain - Business rules definition +│ │ └── entities +│ │ └── usecases +│ ├── infra - External frameworks and libs implementation +│ ├── presentation - External api communication layer (controllers, presenters, validators) +│ └── useCases - Usecases implementation +└─── tests - Components tests + └── e2e + └── unit +``` + +## Construindo e contribuindo 🛠 + +Para executar este projeto localmente, você terá que instalar o Nodejs e o PostgreSQL na máquina ou executar tudo com o Docker. Depois de executar o projeto, vá para o arquivo **_.Env.example_**, na raiz do projeto, e renomeie-o para **_.Env_**, preenchendo todas as propriedades do arquivo com suas informações. + + + +###### Clona Repositório + +```git +git clone https://github.com/gabriellopes00/feedbackio-api.git +or +git clone git@github.com:gabriellopes00/feedbackio-api.git +``` + +###### Rodar no Docker + +```docker +docker-compose up +``` + +###### Executando localmente + +```bash +npm install +npm run build +npm run start +``` + +###### Testes (jest) 🧪 + +- _**All**_ ❯ `yarn test` +- _**Coverage**_ ❯ `yarn test:ci` +- _**Unit**(.spec)_ ❯ `yarn test:unit` +- _**e2e**(.test)_ ❯ `yarn test:e2e` + +###### Linting (eslint and prettier) 🎭 + +- _**Lint**(eslint)_ ❯ `yarn lint` +- _**Style**(prettier)_ ❯ `yarn style` + +###### Estatísticas dos tipos de commits 📊📈 + +Seguindo o padrão do [Conventional Commits](https://www.conventionalcommits.org/). + +- _**feature** commits(amount)_ ❯ `git shortlog -s --grep feat` +- _**test** commits(amount)_ ❯ `git shortlog -s --grep test` +- _**refactor** commits(amount)_ ❯ `git shortlog -s --grep refactor` +- _**chore** commits(amount)_ ❯ `git shortlog -s --grep chore` +- _**docs** commits(amount)_ ❯ `git shortlog -s --grep docs` +- _**build** commits(amount)_ ❯ `git shortlog -s --grep build` + +## 🤝 Colaboradores + +Agradecemos às seguintes pessoas que contribuíram para este projeto: + + + + + + +
+ + Foto do Gabriel Lopes no GitHub
+ + Gabriel Lopes + +
+
+ + Foto do Matheus Campos
+ + Matheus Campos + +
+
+ +## Licença ✒ + +Este projeto usa a licença [Apache 2](https://github.com/gabriellopes00/feedbackio-api/blob/main/LICENSE.md), leia para saber mais sobre permissões e direitos autorais. + +## Contato 📱 + +[![Github Badge](https://img.shields.io/badge/-Github-000?style=flat-square&logo=Github&logoColor=white&link=https://github.com/gabriellopes00)](https://github.com/gabriellopes00) +[![Linkedin Badge](https://img.shields.io/badge/-LinkedIn-blue?style=flat-square&logo=Linkedin&logoColor=white&link=https://www.linkedin.com/in/gabriel-lopes-6625631b0/)](https://www.linkedin.com/in/gabriel-lopes-6625631b0/) +[![Twitter Badge](https://img.shields.io/badge/-Twitter-1ca0f1?style=flat-square&labelColor=1ca0f1&logo=twitter&logoColor=white&link=https://twitter.com/_gabrielllopes_)](https://twitter.com/_gabrielllopes_) +[![Gmail Badge](https://img.shields.io/badge/-Gmail-D14836?&style=flat-square&logo=Gmail&logoColor=white&link=mailto:gabrielluislopes00@gmail.com)](mailto:gabrielluislopes00@gmail.com) +[![Facebook Badge](https://img.shields.io/badge/facebook-%231877F2.svg?&style=flat-square&logo=facebook&logoColor=white)](https://www.facebook.com/profile.php?id=100034920821684) +[![Instagram Badge](https://img.shields.io/badge/instagram-%23E4405F.svg?&style=flat-square&logo=instagram&logoColor=white)](https://www.instagram.com/_.gabriellopes/?hl=pt-br) +[![StackOverflow Badge](https://img.shields.io/badge/stack%20overflow-FE7A16?logo=stack-overflow&logoColor=white&style=flat-square)](https://stackoverflow.com/users/14099025/gabriel-lopes?tab=profile) From bd4616d14b3811da20005f69d801f089b1c5d4b2 Mon Sep 17 00:00:00 2001 From: MatheusFC2 Date: Sat, 24 Apr 2021 21:14:37 -0300 Subject: [PATCH 5/5] readme in english, turn lenguage and contributors --- README.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 96f8f992..f44c2b8f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,13 @@

Feedback.io

+#### Turn Language +

+ + flag-brasil + +

+ ###### An API built with

@@ -107,7 +114,32 @@ Following the standard of the [Conventional Commits](https://www.conventionalcom - _**docs** commits(amount)_ ❯ `git shortlog -s --grep docs` - _**build** commits(amount)_ ❯ `git shortlog -s --grep build` -## License ✒ +## 🤝 Contributors + +We thank the following people who contributed to this project: + + + + + + +
+ + Photo of Gabriel Lopes no GitHub
+ + Gabriel Lopes + +
+
+ + Photo of Matheus Campos
+ + Matheus Campos + +
+
+ +## License ⚖ This project uses [Apache 2](https://github.com/gabriellopes00/feedbackio-api/blob/main/LICENSE.md) license, read to know more about permissions and copyright.