Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
leeozaka committed Dec 21, 2024
0 parents commit 37942bb
Show file tree
Hide file tree
Showing 44 changed files with 7,238 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
npm-debug.log
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules

.env
dist
.DS_Store
7 changes: 7 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"semi": true,
"trailingComma": "all",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2
}
20 changes: 20 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"<node_internals>/**"
],
"program": "${workspaceFolder}/src/middlewares/auth.js",
"outFiles": [
"${workspaceFolder}/**/*.js"
]
}
]
}
21 changes: 21 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM --platform=linux/amd64 node:18-slim

WORKDIR /usr/src/app

COPY package.json yarn.lock ./

RUN yarn install

COPY prisma ./prisma/
COPY src/prisma ./src/prisma/

RUN npx prisma generate

COPY . .

RUN apt-get update && apt install -y openssl

EXPOSE 3344
EXPOSE 5555

CMD [ "yarn", "dev" ]
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
### Em progresso
4 changes: 4 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const presets = [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-typescript',
];
45 changes: 45 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
version: '3.8'

services:
db:
container_name: db
image: postgres:15
restart: always
expose:
- 5432
ports:
- 5432:5432
networks:
- cachorrinho_network
environment:
- POSTGRES_DB=cachorrinhodb
- POSTGRES_USER=salvacao
- POSTGRES_PASSWORD=salvacao123

web:
container_name: web
build:
context: .
dockerfile: Dockerfile
command: yarn dev
volumes:
- .:/usr/src/app
- /usr/src/app/node_modules
ports:
- 3344:3344
- 5556:5555
networks:
- cachorrinho_network
links:
- db
env_file:
- .env.example
platform: 'linux/amd64'
depends_on:
- db
expose:
- 5555

networks:
cachorrinho_network:
driver: bridge
20 changes: 20 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";


/** @type {import('eslint').Linter.Config[]} */
export default [
{files: ["**/*.{js,mjs,cjs,ts}"]},
{languageOptions: { globals: globals.browser }},
{
files: ["tests/**/*", "**/*.test.ts", "**/*.spec.ts"],
languageOptions: {
globals: {
...globals.jest
}
}
},
pluginJs.configs.recommended,
...tseslint.configs.recommended,
];
10 changes: 10 additions & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Config } from 'jest';

const config: Config = {
verbose: true,
testEnvironment: 'node',
testMatch: ['**/*.test.ts'],
moduleNameMapper: { '^@/(.*)$': '<rootDir>/src/$1' }
};

export default config;
53 changes: 53 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"name": "cachorrinho-express",
"version": "0.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"start": "prisma migrate deploy && ts-node-dev --poll -r tsconfig-paths/register --respawn src/index.ts",
"dev": "prisma migrate deploy && ts-node-dev --poll -r tsconfig-paths/register --exit-child --respawn --transpile-only src/index.ts",
"lint": "eslint .",
"lint:fix": "eslint . -c .ts --fix",
"format": "prettier --write \"src/**/*.ts\"",
"test": "jest"
},
"dependencies": {
"@nestjs-modules/mailer": "^1.11.2",
"@prisma/client": "^5.10.2",
"bcrypt": "^5.1.1",
"bcryptjs": "^2.4.3",
"cors": "^2.8.5",
"date-fns": "^3.6.0",
"dotenv": "^16.4.5",
"http-status-codes": "^2.3.0",
"jsonwebtoken": "^9.0.2",
"moment": "^2.30.1",
"nodemailer": "^6.9.13",
"swagger-ui-express": "^5.0.0"
},
"devDependencies": {
"@babel/preset-env": "^7.26.0",
"@babel/preset-typescript": "^7.26.0",
"@eslint/js": "^9.17.0",
"@jest/globals": "^29.7.0",
"@types/bcrypt": "^5.0.2",
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/jsonwebtoken": "^9.0.7",
"@types/luxon": "^3.4.2",
"@types/node": "^20.11.24",
"@typescript-eslint/eslint-plugin": "^8.18.1",
"@typescript-eslint/parser": "^8.18.1",
"babel-jest": "^29.7.0",
"eslint": "^9.17.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
"globals": "^15.14.0",
"jest": "^29.7.0",
"prettier": "^3.4.2",
"prisma": "^5.10.2",
"ts-node-dev": "^2.0.0",
"typescript": "^5.3.3",
"typescript-eslint": "^8.18.1"
}
}
11 changes: 11 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
11 changes: 11 additions & 0 deletions src/@types/ActivableEntityType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { DateTime } from 'luxon';

/**
* Type for entities that implement IActivableEntity
*/
export type ActivableEntityType = {
isActive: boolean;
isDeleted: boolean;
lastModified: DateTime;
createdAt: DateTime;
};
9 changes: 9 additions & 0 deletions src/@types/express.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { User } from 'dtos/UserDTO';

declare global {
namespace Express {
export interface Request {
user: User;
}
}
}
64 changes: 64 additions & 0 deletions src/controllers/LoginController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Request, Response } from 'express';
import { compareSync } from 'bcrypt';
import * as jwt from 'jsonwebtoken';
import { prismaClient } from '../index';
import { JWT_SECRET } from '../secret';
import { StatusCodes } from 'http-status-codes';
import { LoginRequest, LoginResponse } from '../interfaces/LoginInterface';
import ErrorHandler from '../helpers/ErrorHandler';
import { EntityAttribute, EntityType } from '../enums/ErrorTypes';

/**
* Controller responsible for handling user authentication
* @class LoginController
*/
export class LoginController {
private static errorHandler = new ErrorHandler();

/**
* Authenticates a user and generates JWT token
* @param {Request} req - Express request object
* @param {Response} res - Express response object
* @returns {Promise<Response>} Login response with user id and token
*/
public static async authenticate(
req: Request<object, object, LoginRequest>,
res: Response,
): Promise<Response<LoginResponse>> {
try {
const { cpf, password } = req.body;

const cleanCpf = cpf.replace(/\D/g, '');

const user = await prismaClient.user.findUnique({
where: { cpf: cleanCpf },
});

if (!user || !compareSync(password, user.password)) {
throw this.errorHandler.addError(
EntityType.USER,
EntityAttribute.CREDENTIALS,
StatusCodes.UNAUTHORIZED,
'Invalid credentials',
);
}

const token = jwt.sign({ userId: user.id }, JWT_SECRET, { expiresIn: '8h' });

return res.status(StatusCodes.OK).json({
user: user.id,
token,
});
} catch (error) {
if (error instanceof ErrorHandler) {
return res.status(error.getErrors()[0].statusCode).json({
errors: error.getErrors(),
});
}

return res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
message: 'Internal server error',
});
}
}
}
Loading

0 comments on commit 37942bb

Please sign in to comment.