Skip to content

Commit

Permalink
🌼 Update Version - v10.1.1
Browse files Browse the repository at this point in the history
### 🌼 Update Version - v10.1.1

#### 🐞 Fix Bug
- Fix database import bug
- Correct variable name in users.route.ts

#### πŸ›  Refactoring Code 
- Fix Database Connection
  • Loading branch information
ljlm0402 authored Sep 16, 2023
1 parent 5e94d67 commit 02c853c
Show file tree
Hide file tree
Showing 24 changed files with 279 additions and 221 deletions.
7 changes: 7 additions & 0 deletions lib/node-postgres/.env.development.local
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,10 @@ LOG_DIR = ../logs
# CORS
ORIGIN = *
CREDENTIALS = true

# DATABASE
POSTGRES_USER = root
POSTGRES_PASSWORD = password
POSTGRES_HOST = localhost
POSTGRES_PORT = 5432
POSTGRES_DB = dev
7 changes: 7 additions & 0 deletions lib/node-postgres/.env.production.local
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,10 @@ LOG_DIR = ../logs
# CORS
ORIGIN = your.domain.com
CREDENTIALS = true

# DATABASE
POSTGRES_USER = root
POSTGRES_PASSWORD = password
POSTGRES_HOST = pg
POSTGRES_PORT = 5432
POSTGRES_DB = dev
7 changes: 7 additions & 0 deletions lib/node-postgres/.env.test.local
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,10 @@ LOG_DIR = ../logs
# CORS
ORIGIN = *
CREDENTIALS = true

# DATABASE
POSTGRES_USER = root
POSTGRES_PASSWORD = password
POSTGRES_HOST = pg
POSTGRES_PORT = 5432
POSTGRES_DB = dev
1 change: 0 additions & 1 deletion lib/node-postgres/.swcrc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
"@exceptions/*": ["exceptions/*"],
"@interfaces/*": ["interfaces/*"],
"@middlewares/*": ["middlewares/*"],
"@models/*": ["models/*"],
"@services/*": ["services/*"],
"@utils/*": ["utils/*"]
}
Expand Down
6 changes: 0 additions & 6 deletions lib/node-postgres/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import morgan from 'morgan';
import swaggerJSDoc from 'swagger-jsdoc';
import swaggerUi from 'swagger-ui-express';
import { NODE_ENV, PORT, LOG_FORMAT, ORIGIN, CREDENTIALS } from '@config';
import { client } from '@database';
import { Routes } from '@interfaces/routes.interface';
import { ErrorMiddleware } from '@middlewares/error.middleware';
import { logger, stream } from '@utils/logger';
Expand All @@ -24,7 +23,6 @@ export class App {
this.env = NODE_ENV || 'development';
this.port = PORT || 3000;

this.connectToDatabase();
this.initializeMiddlewares();
this.initializeRoutes(routes);
this.initializeSwagger();
Expand All @@ -44,10 +42,6 @@ export class App {
return this.app;
}

private async connectToDatabase() {
await client.connect();
}

private initializeMiddlewares() {
this.app.use(morgan(LOG_FORMAT, { stream }));
this.app.use(cors({ origin: ORIGIN, credentials: CREDENTIALS }));
Expand Down
2 changes: 1 addition & 1 deletion lib/node-postgres/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ config({ path: `.env.${process.env.NODE_ENV || 'development'}.local` });

export const CREDENTIALS = process.env.CREDENTIALS === 'true';
export const { NODE_ENV, PORT, SECRET_KEY, LOG_FORMAT, LOG_DIR, ORIGIN } = process.env;
export const { DB_USER, DB_PASSWORD, DB_HOST, DB_PORT, DB_DATABASE } = process.env;
export const { POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DB } = process.env;
8 changes: 6 additions & 2 deletions lib/node-postgres/src/database/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { Client } from 'pg';
import { DB_USER, DB_PASSWORD, DB_HOST, DB_PORT, DB_DATABASE } from '@config';
import { POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DB } from '@config';

export const client = new Client({
connectionString: `postgres://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_DATABASE}`,
connectionString: `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}`,
});

client.connect();

export default client;
119 changes: 11 additions & 108 deletions lib/node-postgres/src/database/init.sql
Original file line number Diff line number Diff line change
@@ -1,110 +1,13 @@
-- TABLE μ‘΄μž¬ν•  경우 μ‚­μ œ
DROP TABLE IF EXISTS teachers cascade;
DROP TABLE IF EXISTS classes cascade;
DROP TABLE IF EXISTS students cascade;
DROP TABLE IF EXISTS classes_category cascade;
DROP TABLE IF EXISTS enrolment cascade;

-- ============
-- 강사 ν…Œμ΄λΈ”
-- ============
-- 강사 ν…Œμ΄λΈ” 생성
CREATE TABLE teachers(
"teacherId" SERIAL PRIMARY KEY,
-- 강사 ID
"teacherName" VARCHAR(32) NOT NULL,
-- 강사λͺ…
"teacherAbout" VARCHAR(48) -- 강사 정보
);
-- 강사 데이터 생성
INSERT INTO teachers(
"teacherId",
"teacherName",
"teacherAbout"
)
VALUES (1, 'μ‘°ν˜„μ˜', 'μ›Ή 개발 강사'),
(2, '개볡치개발자', 'μ•ˆλ“œλ‘œμ΄λ“œ μ½”ν‹€λ¦° 강사'),
(3, 'μ΄κ³ μž‰', 'μƒν™œμ½”λ”© μš΄μ˜μ§„ κ²Έ 강사'),
(4, 'κΉ€νƒœμ›', '파이썬 μ•Œκ³ λ¦¬μ¦˜ 강사'),
(5, 'μœ€μž¬μ„±', 'Kotiln 기반 μ•ˆλ“œλ‘œμ΄λ“œ 강사'),
(6, 'μ‘°ν›ˆ', 'μΏ λ²„λ„€ν‹°μŠ€ 강사'),
(7, 'Rookiss', '얼리언 엔진 μ „λ¬Έ 강사'),
(8, 'μœ μš©ν•œITν•™μŠ΅', 'SQLD 자격증 취득 강사'),
(9, 'κΉ€νƒœλ―Ό', 'μΏ λ²„λ„€ν‹°μŠ€ 강사'),
(10, '큰돌', 'μ•Œκ³ λ¦¬μ¦˜ 강사');
SELECT SETVAL(
'"teachers_teacherId_seq"',
(
SELECT max("teacherId")
FROM teachers
)
);
-- ===================
-- κ°•μ˜ μΉ΄ν…Œκ³ λ¦¬ ν…Œμ΄λΈ”
-- ===================
-- κ°•μ˜ μΉ΄ν…Œκ³ λ¦¬ ν…Œμ΄λΈ” 생성
CREATE TABLE classes_category(
"categoryId" SERIAL PRIMARY KEY,
-- μΉ΄ν…Œκ³ λ¦¬ ID
"categoryName" VARCHAR(32) UNIQUE NOT NULL -- μΉ΄ν…Œκ³ λ¦¬ λͺ…
);
-- κ°•μ˜ μΉ΄ν…Œκ³ λ¦¬ 데이터 생성
INSERT INTO classes_category("categoryId", "categoryName")
VALUES (1, 'μ›Ή'),
(2, 'μ•±'),
(3, 'κ²Œμž„'),
(4, 'μ•Œκ³ λ¦¬μ¦˜'),
(5, '인프라'),
(6, 'λ°μ΄ν„°λ² μ΄μŠ€');
SELECT SETVAL(
'"classes_category_categoryId_seq"',
(
SELECT max("categoryId")
FROM classes_category
)
);
-- ============
-- κ°•μ˜ ν…Œμ΄λΈ”
-- ============
-- κ°•μ˜ ν…Œμ΄λΈ” 생성
CREATE TABLE classes(
"classId" SERIAL PRIMARY KEY,
-- κ°•μ˜ ID
"className" VARCHAR(32) UNIQUE NOT NULL,
-- κ°•μ˜λͺ…
"classPrice" INTEGER NOT NULL DEFAULT 0,
-- 가격
"introduce" TEXT,
-- κ°•μ˜ μ†Œκ°œ
"active" BOOLEAN NOT NULL DEFAULT false,
-- κ°•μ˜ ν™œμ„±ν™” (true: 곡개, false, λΉ„κ³΅κ°œ)
-- If Exists Table Drop
DROP TABLE IF EXISTS users cascade;
-- ================
-- TABLE [users]
-- ================
-- create users table
CREATE TABLE users(
"id" SERIAL PRIMARY KEY,
"email" VARCHAR(32) UNIQUE NOT NULL,
"password" VARCHAR(48) NOT NULL,
"createdAt" TIMESTAMP WITHOUT TIME ZONE DEFAULT(NOW() AT TIME ZONE 'utc'),
-- κ°•μ˜ 생성 일자
"updatedAt" TIMESTAMP WITHOUT TIME ZONE,
-- κ°•μ˜ μˆ˜μ • 일자
"teacherId" INTEGER REFERENCES teachers("teacherId") ON DELETE CASCADE,
-- 강사 ID
"categoryId" INTEGER REFERENCES classes_category("categoryId") ON DELETE CASCADE -- 강사 ID
);
-- ==============
-- μˆ˜κ°•μƒ ν…Œμ΄λΈ”
-- ==============
-- μˆ˜κ°•μƒ ν…Œμ΄λΈ” 생성
CREATE TABLE students(
"studentId" SERIAL PRIMARY KEY,
-- μˆ˜κ°•μƒ ID
"email" VARCHAR(48) UNIQUE NOT NULL,
-- μˆ˜κ°•μƒ 이메일
"nickname" VARCHAR(32) NOT NULL -- μˆ˜κ°•μƒ λ‹‰λ„€μž„
);
-- ===============
-- μˆ˜κ°•μ‹ μ²­ ν…Œμ΄λΈ”
-- ===============
-- μˆ˜κ°•μ‹ μ²­ ν…Œμ΄λΈ” 생성
CREATE TABLE enrolment(
"classId" INTEGER REFERENCES classes("classId") ON DELETE CASCADE,
-- κ°•μ˜ ID
"studentId" INTEGER REFERENCES students("studentId") ON DELETE CASCADE,
-- μˆ˜κ°•μƒ ID
"applicationAt" TIMESTAMP WITHOUT TIME ZONE DEFAULT(NOW() AT TIME ZONE 'utc') -- μ‹ μ²­ 일자
"updatedAt" TIMESTAMP WITHOUT TIME ZONE
);
16 changes: 12 additions & 4 deletions lib/node-postgres/src/middlewares/auth.middleware.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { NextFunction, Response } from 'express';
import { verify } from 'jsonwebtoken';
import { SECRET_KEY } from '@config';
import pg from '@database';
import { HttpException } from '@exceptions/httpException';
import { DataStoredInToken, RequestWithUser } from '@interfaces/auth.interface';
import { UserModel } from '@models/users.model';

const getAuthorization = req => {
const coockie = req.cookies['Authorization'];
Expand All @@ -21,10 +21,18 @@ export const AuthMiddleware = async (req: RequestWithUser, res: Response, next:

if (Authorization) {
const { id } = (await verify(Authorization, SECRET_KEY)) as DataStoredInToken;
const findUser = UserModel.find(user => user.id === id);
const { rows, rowCount } = await pg.query(`
SELECT
"email",
"password"
FROM
users
WHERE
"id" = $1
`, id);

if (findUser) {
req.user = findUser;
if (rowCount) {
req.user = rows[0];
next();
} else {
next(new HttpException(401, 'Wrong authentication token'));
Expand Down
9 changes: 0 additions & 9 deletions lib/node-postgres/src/models/users.model.ts

This file was deleted.

4 changes: 2 additions & 2 deletions lib/node-postgres/src/routes/auth.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export class AuthRoute implements Routes {
}

private initializeRoutes() {
this.router.post('/signup', ValidationMiddleware(CreateUserDto, 'body'), this.auth.signUp);
this.router.post('/login', ValidationMiddleware(CreateUserDto, 'body'), this.auth.logIn);
this.router.post('/signup', ValidationMiddleware(CreateUserDto), this.auth.signUp);
this.router.post('/login', ValidationMiddleware(CreateUserDto), this.auth.logIn);
this.router.post('/logout', AuthMiddleware, this.auth.logOut);
}
}
4 changes: 2 additions & 2 deletions lib/node-postgres/src/routes/users.route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export class UserRoute implements Routes {
private initializeRoutes() {
this.router.get(`${this.path}`, this.user.getUsers);
this.router.get(`${this.path}/:id(\\d+)`, this.user.getUserById);
this.router.post(`${this.path}`, ValidationMiddleware(CreateUserDto, 'body'), this.user.createUser);
this.router.put(`${this.path}/:id(\\d+)`, ValidationMiddleware(CreateUserDto, 'body', true), this.user.updateUser);
this.router.post(`${this.path}`, ValidationMiddleware(CreateUserDto), this.user.createUser);
this.router.put(`${this.path}/:id(\\d+)`, ValidationMiddleware(CreateUserDto, true), this.user.updateUser);
this.router.delete(`${this.path}/:id(\\d+)`, this.user.deleteUser);
}
}
81 changes: 66 additions & 15 deletions lib/node-postgres/src/services/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { hash, compare } from 'bcrypt';
import { sign } from 'jsonwebtoken';
import { Service } from 'typedi';
import { SECRET_KEY } from '@config';
import pg from '@database';
import { HttpException } from '@exceptions/httpException';
import { DataStoredInToken, TokenData } from '@interfaces/auth.interface';
import { User } from '@interfaces/users.interface';
import { UserModel } from '@models/users.model';

const createToken = (user: User): TokenData => {
const dataStoredInToken: DataStoredInToken = { id: user.id };
Expand All @@ -21,32 +21,83 @@ const createCookie = (tokenData: TokenData): string => {
@Service()
export class AuthService {
public async signup(userData: User): Promise<User> {
const findUser: User = UserModel.find(user => user.email === userData.email);
if (findUser) throw new HttpException(409, `This email ${userData.email} already exists`);
const { email, password } = userData;

const hashedPassword = await hash(userData.password, 10);
const createUserData: User = { id: UserModel.length + 1, ...userData, password: hashedPassword };
const { rows: findUser } = await pg.query(
`
SELECT EXISTS(
SELECT
"email"
FROM
users
WHERE
"email" = $1
)`,
[email],
);
if (findUser[0].exists) throw new HttpException(409, `This email ${userData.email} already exists`);

return createUserData;
const hashedPassword = await hash(password, 10);
const { rows: signUpUserData } = await pg.query(
`
INSERT INTO
users(
"email",
"password"
)
VALUES ($1, $2)
RETURNING "email", "password"
`,
[email, hashedPassword],
);

return signUpUserData[0];
}

public async login(userData: User): Promise<{ cookie: string; findUser: User }> {
const findUser: User = UserModel.find(user => user.email === userData.email);
if (!findUser) throw new HttpException(409, `This email ${userData.email} was not found`);
const { email, password } = userData;

const { rows, rowCount } = await pg.query(
`
SELECT
"email",
"password"
FROM
users
WHERE
"email" = $1
`,
[email],
);
if (!rowCount) throw new HttpException(409, `This email ${email} was not found`);

const isPasswordMatching: boolean = await compare(userData.password, findUser.password);
const isPasswordMatching: boolean = await compare(password, rows[0].password);
if (!isPasswordMatching) throw new HttpException(409, "You're password not matching");

const tokenData = createToken(findUser);
const tokenData = createToken(rows[0]);
const cookie = createCookie(tokenData);

return { cookie, findUser };
return { cookie, findUser: rows[0] };
}

public async logout(userData: User): Promise<User> {
const findUser: User = UserModel.find(user => user.email === userData.email && user.password === userData.password);
if (!findUser) throw new HttpException(409, "User doesn't exist");
const { email, password } = userData;

const { rows, rowCount } = await pg.query(
`
SELECT
"email",
"password"
FROM
users
WHERE
"email" = $1
AND
"password" = $2
`,
[email, password],
);
if (!rowCount) throw new HttpException(409, "User doesn't exist");

return findUser;
return rows[0];
}
}
Loading

0 comments on commit 02c853c

Please sign in to comment.