Skip to content

Commit

Permalink
Merge pull request #8 from netCard-TUK/wonchan
Browse files Browse the repository at this point in the history
회원 가입, 로그인, 회원 탈퇴 구현
  • Loading branch information
Leewonchan14 authored Jan 19, 2024
2 parents b0599b9 + c7331cb commit 2111d4d
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 69 deletions.
25 changes: 25 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Ignore node modules
node_modules

# Ignore logs
npm-debug.log
npm-error.log

# Ignore the Git repository and its logs
.git
.gitignore
.gitattributes

# Ignore Docker files (optional)
Dockerfile
.dockerignore

# Ignore environment files
.env
.env.*

# Ignore other unnecessary files
README.md
LICENSE
.DS_Store
*.md
41 changes: 41 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Node.js Package

on:
pull_request:
branches:
- main
types:
- closed

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build docker file
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/netcard:latest
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Deploy to EC2
uses: appleboy/scp-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ubuntu
key: ${{ secrets.EC2_KEY }}
script: |
rm .env
echo "${{ secrets.ENV }}" > .env
sudo docker stop netcard || true
sudo docker rm netcard || true
sudo docker rmi ${{ secrets.DOCKER_USERNAME }}/netcard:latest || true
sudo docker run -d --name netcard -p 8000:8000 --env-file .env ${{ secrets.DOCKER_USERNAME }}/netcard:latest
13 changes: 13 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Stage 1: Build
FROM node:14-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm install --only=production
COPY . .

# Stage 2: Runtime
FROM node:14-alpine
WORKDIR /app
COPY --from=builder /app .
EXPOSE 8000
CMD ["npm", "start"]
178 changes: 143 additions & 35 deletions src/api/user/controller.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,151 @@
const jwt = require("./jwt");
const { register, find } = require("./repogitory");
const userRepository = require("./repogitory");
const crypto = require("crypto");

exports.register = async (req, res) => {
const { email, password, name } = req.body;
let { count } = await find(email);

if (typeof password !== "string" || !password.trim()) {
return res.status(400).send({
isSuccess: "false",
message: "비밀번호는 필수 입력 항목입니다.",
});
}
if (count > 0) {
return res.send({
isSuccess: "false",
message: "중복된 이메일이 존재합니다.",
});
}
const result = await crypto.pbkdf2Sync(
password,
process.env.SALT_KET,
50,
100,
"sha512"
);

const { affectedRows, insertId } = await register(
email,
result.toString("base64"),
name
);
if (affectedRows > 0) {
const data = await jwt.jwtSign({ id: insertId, name });
res.send({ access_token: data });
} else {
// 영어, 숫자 최소 1자리
const emailRegex = /^[a-zA-Z0-9]+$/;
// 영어, 숫자 최소 1자리
const passwordRegex = /^[a-zA-Z0-9]+$/;
// 한글, 영어, 숫자 최소 1자리
const nameRegex = /^[-a-zA-Z0-9]+$/;
// 숫자 최소 1자리
const phoneRegex = /^[0-9]+$/;

const {email, password, name, phone} = req.body;

if (
emailRegex.test(email) === false ||
passwordRegex.test(password) === false ||
nameRegex.test(name) === false ||
phoneRegex.test(phone) === false
) {
return res.send({
isSuccess: false,
message: "email, password, name, phone 은 숫자와 영어만 입력 가능합니다.",
});
}

let isExist = await userRepository.isExistByEmail(email);

if (isExist) {
return res.send({
isSuccess: false,
message: "중복된 이메일이 존재합니다.",
});
}

// 비밀번호 암호화
const result = await crypto.pbkdf2Sync(
password,
process.env.SALT_KET,
50,
100,
"sha512"
);

const {affectedRows, insertId} = await userRepository.register(
email,
result.toString("base64"),
name,
phone
);

const data = await jwt.jwtSign({id: insertId});

res.send({
isSuccess: "false",
message: "항목 중 빈 칸이 존재하거나 올바른 값이 아닙니다.",
isSuccess: true,
userId : insertId,
access_token: data,
});
}
};

exports.login = async (req, res) => {
let {email, password} = req.body;

// 영어, 숫자 최소 1자리
const emailRegex = /^[a-zA-Z0-9]+$/;
// 영어, 숫자 최소 1자리
const passwordRegex = /^[a-zA-Z0-9]+$/;

if (
emailRegex.test(email) === false ||
passwordRegex.test(password) === false
) {
return res.send({
isSuccess: false,
message: "email, password 는 숫자와 영어만 입력 가능합니다.",
});
}

// 비밀번호 암호화
const result = await crypto.pbkdf2Sync(
password,
process.env.SALT_KET,
50,
100,
"sha512"
);

const user = await userRepository.login(email, result.toString("base64"));

if (!user){
return res.send({
isSuccess: false,
message: "일치하는 회원이 없습니다.",
});
}

const token = await jwt.jwtSign({id: user.id});

res.send({
isSuccess: true,
userId : user.id,
access_token: token,
});
}

exports.delete = async (req, res) => {
let {userId} = req.body
const tokenUserId = req.user.id;


// 숫자 최소 1자리
const regExp = /^[0-9]+$/;

if (!regExp.test(userId)) {
return res.send({
isSuccess: false,
message: "userId가 잘못되었습니다.",
});
}

userId = Number(userId);

// 토큰 유저 아이디와 요청 유저 아이디가 다를 경우
if (tokenUserId !== userId) {
return res.send({
isSuccess: false,
message: "인증실패 : 토큰 유저 아이디와 요청 유저 아이디가 다릅니다.",
});
}

// 유저 아이디로 유저 찾기
const user = await userRepository.show_user(userId);
if (!user) {
return res.send({
isSuccess: false,
message: "존재하지 않는 유저입니다.",
});
}

let {affectedRows} = await userRepository.delete(userId);

if (affectedRows > 0) {
res.send({ isSuccess: true });
}
else {
res.send({ isSuccess: false, message: "삭제 실패" });
}
}
46 changes: 31 additions & 15 deletions src/api/user/repogitory.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,41 @@
const { pool } = require("../../data");
const {pool} = require("../../data");

exports.register = async (email, password, name) => {
const query = `INSERT INTO user (email, password, name) VALUES (?,?,?)`;
return await pool(query, [email, password, name]);
exports.register = async (email, password, name, phone) => {
const query = `INSERT INTO user (email, password, name, phone)
VALUES (?, ?, ?, ?)`;
return await pool(query, [email, password, name, phone]);
};

exports.login = async (email, password) => {
const query = `SELECT * FROM user WHERE email = ? AND password = ?`;
let result = await pool(query, [email, password]);
return result.length < 0 ? null : result[0];
const query = `SELECT *
FROM user
WHERE email = ?
AND password = ?`;
let result = await pool(query, [email, password]);
return result.length < 0 ? null : result[0];
};

exports.find = async (email) => {
let result = await pool(`SELECT count(*) count FROM user WHERE email = ?`, [
email,
]);
return result.length < 0 ? null : result[0];
exports.isExistByEmail = async (email) => {
let result = await pool(
`SELECT count(*) count
FROM user
WHERE email = ?`,
[email]
);

return result[0].count > 0;
};

exports.delete = async (userId) => {
return await pool(`UPDATE user
SET isActivate = false
WHERE id = ?`, [userId]);
}

exports.show_user = async (id) => {
const query = `SELECT * FROM user WHERE id =?`;
let result = await pool(query, [id]);
return result.length < 0 ? null : result[0];
const query = `SELECT *
FROM user
WHERE id = ?`;
let result = await pool(query, [id]);
return result.length < 0 ? null : result[0];
};
6 changes: 5 additions & 1 deletion src/middleware/jwtVerify.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@ module.exports = async (req, res, next) => {

jwt.verify(token, process.env.JWT_KEY, function (err, decoded) {
if (err) {
return res.send(err);
return res.send({
isSuccess: false,
message: "토큰이 유효하지 않습니다.",
err
});
}
req.user = decoded;
next();
Expand Down
30 changes: 12 additions & 18 deletions src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,25 @@ const storage = multer.diskStorage({

const upload = multer({ storage: storage });

const webController = require("./web/controller");
const apiUserController = require("./api/user/controller");
const apiFeedCOntroller = require("./api/feed/controller");
const fileController = require("./api/file/controller");
const userController = require("./api/user/controller");
const cardsController = require("./api/cards/controller");

const walletController = require("./api/wallet/controller");


// static file
router.use("/", express.static("./public"));
// CORS setting
router.use(headers);
// logging
router.use(logging);
router.post("/api/file", upload.single("file"), fileController.upload);
router.get("/api/file/:id", fileController.download);

router.get("/", webController.home);
router.get("/page/:page", webController.page);
router.get("/sitemap", webController.sitemap);

router.post("/api/user/register", apiUserController.register);

router.get("/api/feed", verify, apiFeedCOntroller.index);
router.post("/api/feed", verify, apiFeedCOntroller.store);
router.get("/api/feed/:id", verify, apiFeedCOntroller.show);
router.post("/api/feed/:id", verify, apiFeedCOntroller.update);
router.post("/api/feed/:id/delete", verify, apiFeedCOntroller.destroy);
// 유저 관련 api
// 회원가입
router.post("/api/users/register", userController.register);
// 로그인
router.post("/api/users/login", userController.login);
// 회원탈퇴
router.post("/api/users/delete",verify, userController.delete);

//명함 관련 api
router.post(
Expand Down

0 comments on commit 2111d4d

Please sign in to comment.