Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions semana21/futuretube/backend-futuretube/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
node_modules/
build/
.env
8 changes: 8 additions & 0 deletions semana21/futuretube/backend-futuretube/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
roots: ["<rootDir>/tests"],
transform: {
"^.+\\.tsx?$": "ts-jest"
},
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$",
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"]
};
Binary file added semana21/futuretube/backend-futuretube/lambda.zip
Binary file not shown.
6,371 changes: 6,371 additions & 0 deletions semana21/futuretube/backend-futuretube/package-lock.json

Large diffs are not rendered by default.

49 changes: 49 additions & 0 deletions semana21/futuretube/backend-futuretube/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "oop",
"version": "1.0.0",
"module": "system",
"description": "",
"main": "index.js",
"scripts": {
"start:dev": "ts-node-dev ./src/presentation/local/index.ts",
"start": "tsc && node ./build/presentation/local/index.js",
"test": "node ./node_modules/jest/bin/jest.js",
"ziplambda": "bestzip ../lambda.zip ./*",
"build": "rm -rf build && tsc",
"postbuild": "cp ./package.json build && cd build && yarn && npm run ziplambda"
},
"author": "",
"license": "ISC",
"dependencies": {
"@types/bcrypt": "^3.0.0",
"@types/express": "4.17.2",
"@types/jest": "^24.0.25",
"@types/jsonwebtoken": "^8.3.5",
"@types/md5": "^2.1.33",
"@types/node": "^12.12.14",
"@types/nodemailer": "^6.4.0",
"@types/randomstring": "^1.1.6",
"@types/uuid": "^3.4.6",
"bcrypt": "^3.0.7",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "4.17.1",
"jest": "^24.9.0",
"jsonwebtoken": "^8.5.1",
"knex": "^0.20.7",
"md5": "^2.2.1",
"mysql": "^2.17.1",
"nodemailer": "^6.4.2",
"randomstring": "^1.1.5",
"reverse-md5": "^0.0.4",
"ts-jest": "^24.2.0",
"ts-node": "^8.5.4",
"ts-node-dev": "^1.0.0-pre.44",
"typescript": "3.7.3",
"url-pattern": "^1.0.3",
"uuid": "^3.3.3"
},
"devDependencies": {
"bestzip": "^2.1.5"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import * as bcrypt from 'bcrypt'
import * as jwt from 'jsonwebtoken'

export default class User {
constructor(
private id: string,
private name: string,
private email: string,
private password: string,
private birthDate: Date,
private photo: string
) { }
getId = () => this.id
getName = () => this.name
getEmail = () => this.email
getPassword = () => this.password
getbirthDate = () => this.birthDate
getPhoto = () => this.photo
static generateToken(id: string) {
const jwtKey = process.env.JWT_KEY as string
const token = jwt.sign(
{ id },
jwtKey,
{ expiresIn: "24h" }
)
return token
}
static getTokenData(token: string) {
const jwtKey = process.env.JWT_KEY as string
const tokenData = jwt.verify(token, jwtKey) as { id: string }
return tokenData
}
static encryptPassword(password: string) {
const jwtKey = process.env.JWT_KEY as string
const token = jwt.sign(
{ password },
jwtKey,
{ expiresIn: "2400000000000000000000000000000h" }
)
return token
}
static checkPassword(password: string, hashPassword: string) {
const jwtKey = process.env.JWT_KEY as string
const tokenData = jwt.verify(hashPassword, jwtKey) as { password: string }
return (tokenData.password === password)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export default class Video {
constructor(
private id: string,
private title: string,
private description: string,
private url: string,
private userId: string
) { }

getId = () => this.id
getTitle = () => this.title
getDescription = () => this.description
getUrl = () => this.url
getUserId = () => this.userId
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export default class VideoDetails {
constructor(
private id: string,
private title: string,
private description: string,
private url: string,
private userId: string,
private name: string,
private photo: string,
) { }

getId = () => this.id
getTitle = () => this.title
getDescription = () => this.description
getUrl = () => this.url
getUserId = () => this.userId
getUserName = () => this.name
getUserPhoto = () => this.photo
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import VideoDetails from "../entities/videoDetails";

export default interface VideoDetailsGateway {
getVideoDetails(id: string): Promise<VideoDetails[]>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Video from "../entities/video";

export default interface VideoGateway {
getAllVideos(page: number): Promise<Video[]>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import UserDB from "../../../data/UserDataBase";
import User from "../../entities/user";

interface LoginUCInput {
email: string,
password: string
}

export class LoginUC {
constructor(private dataBase: UserDB) { }

async execute(input: LoginUCInput) {
const user = await this.dataBase.getUserByEmail(input.email)
const token = User.generateToken(user.id)
const passwordIsCorrect = User.checkPassword(input.password, user.password)

if (!user) throw new Error("Usuário ou senha incorretos")

if (!passwordIsCorrect) throw new Error("Usuário ou senha incorretos")

return {
token,
user: {
id: user.id,
name: user.name,
photo: user.photo
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import UserDB from "../../../data/UserDataBase";
import { v4 } from "uuid";
import * as bcrypt from 'bcrypt';
import User from "../../entities/user";

interface SignupInput {
name: string
email: string
password: string
birthDate: Date
photo: string
}

export default class SignupUC {
constructor(private database: UserDB) { }

async execute(input: SignupInput) {
const id = v4()
const hash = User.encryptPassword(input.password)
const newUser = new User(id, input.name, input.email, hash, input.birthDate, input.photo)
const token = User.generateToken(newUser.getId())

await this.database.signUp(newUser)

return{
message: "User successfully created",
token: token
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import VideoGateway from "../../gateways/videoGateway";

export class GetAllVideosUC {
constructor(private dataBase: VideoGateway) {}

async execute(page: number){
const videos = await this.dataBase.getAllVideos(page)

return {videos}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import VideoDetailsGateway from "../../gateways/videoDetailsGateway";

export class GetVideoDetailsUC {
constructor(private dataBase: VideoDetailsGateway) {}

async execute(id: string){
const details = await this.dataBase.getVideoDetails(id)

return {details}
}
}
13 changes: 13 additions & 0 deletions semana21/futuretube/backend-futuretube/src/data/MainDatabase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import knex from 'knex'

export default class MainDB {
protected connection = knex({
client: 'mysql',
connection: {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
}
})
}
29 changes: 29 additions & 0 deletions semana21/futuretube/backend-futuretube/src/data/UserDataBase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import MainDB from "./MainDatabase";
import User from "../business/entities/user";

export default class UserDB extends MainDB {
async getUserByEmail(email: string) {
const result = await this.connection.raw(`
SELECT * FROM futuretube_USERS
WHERE email="${email}"
`)
return result[0][0]
}

async signUp(user: User) {
try {
await this.connection.raw(`
INSERT INTO futuretube_USERS (id, name, email, password, birthdate, photo) values (
"${user.getId()}",
"${user.getName()}",
"${user.getEmail()}",
"${user.getPassword()}",
"${user.getbirthDate()}",
"${user.getPhoto()}"
);
`)
} catch (error) {
throw new Error(error.sqlMessage)
}
}
}
38 changes: 38 additions & 0 deletions semana21/futuretube/backend-futuretube/src/data/VideosDataBase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import MainDB from "./MainDatabase";
import VideoGateway from "../business/gateways/videoGateway"

export default class VideoDB extends MainDB implements VideoGateway {
async getAllVideos(page: number = 0) {

try {
const offset = (page - 1) * 10

const result = await this.connection.raw(`
SELECT id, title, url
FROM futuretube_videos
LIMIT 10
OFFSET ${offset};
`)

return result[0]
}
catch (err) {
throw new Error (err.sqlMessage)
}
}

async getVideoDetails(id: string) {
try {
const result = await this.connection.raw(`
SELECT futuretube_videos.*, name, photo
FROM futuretube_videos
JOIN futuretube_USERS on userId = futuretube_USERS.id
WHERE futuretube_videos.id = '${id}';
`)
return result[0][0]
}
catch (err) {
throw new Error (err.sqlMessage)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Response, Request } from "express";
import UserDB from "../../../data/UserDataBase";
import { LoginUC } from "../../../business/usecases/users/loginUseCase";

export async function loginEndpoint(req: Request, res: Response) {
try {
const dataBase = new UserDB()
const useCase = new LoginUC(dataBase)
const data = await useCase.execute({
email: req.body.email,
password: req.body.password
})
res.send(data)
} catch (err) {
res.status(err.code || 400).send(err.message)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Response, Request } from "express";
import UserDB from "../../../data/UserDataBase";
import SignupUC from "../../../business/usecases/users/signupUseCase";

export default async function signupEndpoint(req: Request, res: Response) {
try {
const dataBase = new UserDB()
const useCase = new SignupUC(dataBase)
await useCase.execute({
name: req.body.name,
email: req.body.email,
password: req.body.password,
birthDate: req.body.birthdate,
photo: req.body.photo
})
res.send("Usuário cadastrado com sucesso!")
} catch (err) {
res.status(err.code || 400).send(err.message)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Response, Request } from "express";
import VideoDB from "../../../data/VideosDataBase";
import { GetAllVideosUC } from "../../../business/usecases/videos/getAllVideosUseCase";

export async function getAllVideosEndpoint(req: Request, res: Response) {
try {
const dataBase = new VideoDB()
const useCase = new GetAllVideosUC(dataBase)
const data = await useCase.execute(Number(req.query.page))
res.send(data)
} catch (err) {
res.status(err.code || 400).send(err.message)
}
}
Loading