From cf8c8ba033c11e9c7ee5544ac6cbbde388e6af67 Mon Sep 17 00:00:00 2001 From: joonsooha123 <135545450+joonsooha123@users.noreply.github.com> Date: Wed, 5 Jul 2023 22:41:55 +0900 Subject: [PATCH 1/3] =?UTF-8?q?Add:=20=EC=96=B4=EB=93=9C=EB=AF=BC=EC=9C=A0?= =?UTF-8?q?=EC=A0=80=20=EB=93=B1=EB=A1=9D=EC=9D=84=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EB=B0=8F=20=EC=A0=9C=EB=B0=98=EC=82=AC?= =?UTF-8?q?=ED=95=AD=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/controllers/adminUserController.js | 36 +++++++ api/controllers/index.js | 2 + api/models/adminUserDao.js | 95 +++++++++++++++++++ api/models/index.js | 2 + api/models/productDao.js | 14 ++- api/routes/adminUserRouter.js | 8 ++ api/routes/index.js | 2 + api/services/adminUserService.js | 84 ++++++++++++++++ api/services/index.js | 2 + ...0230705060310_create_admin_users_table.sql | 16 ++++ ...0705071115_create_insider_emails_table.sql | 9 ++ 11 files changed, 267 insertions(+), 3 deletions(-) create mode 100644 api/controllers/adminUserController.js create mode 100644 api/models/adminUserDao.js create mode 100644 api/routes/adminUserRouter.js create mode 100644 api/services/adminUserService.js create mode 100644 db/migrations/20230705060310_create_admin_users_table.sql create mode 100644 db/migrations/20230705071115_create_insider_emails_table.sql diff --git a/api/controllers/adminUserController.js b/api/controllers/adminUserController.js new file mode 100644 index 0000000..b8f6de5 --- /dev/null +++ b/api/controllers/adminUserController.js @@ -0,0 +1,36 @@ +const { adminUserService } = require("../services"); + +const adminUserSignUp = async (req, res) => { + try { + const { accountName, password, personalCode, name, email, phoneNumber } = + req.body; + + if ( + !accountName || + !password || + !personalCode || + !name || + !email || + !phoneNumber + ) { + const error = new Error("KEY_ERROR"); + error.statusCode = 400; + throw error; + } + + await adminUserService.adminUserSignUp( + accountName, + password, + personalCode, + name, + email, + phoneNumber + ); + return res.status(201).json({ message: "CREATE_ADMIN_USER_SUCCESS!" }); + } catch (error) { + console.log(error); + return res.status(error.statusCode).json({ message: error.message }); + } +}; + +module.exports = { adminUserSignUp }; diff --git a/api/controllers/index.js b/api/controllers/index.js index a0ccf8c..9a26b4e 100644 --- a/api/controllers/index.js +++ b/api/controllers/index.js @@ -1,9 +1,11 @@ const userController = require("./userController"); const productController = require("./productController"); const cartController = require("./cartController"); +const adminUserController = require("./adminUserController"); module.exports = { userController, productController, cartController, + adminUserController, }; diff --git a/api/models/adminUserDao.js b/api/models/adminUserDao.js new file mode 100644 index 0000000..0471183 --- /dev/null +++ b/api/models/adminUserDao.js @@ -0,0 +1,95 @@ +const { appDataSource } = require("./dataSource"); + +const confirmInsiderByEmail = async (email) => { + const [confirmedInsider] = await appDataSource.query( + ` + SELECT EXISTS ( + SELECT id + FROM insider_emails + WHERE email = ? + ) exist + `, + [email] + ); + return !!parseInt(confirmedInsider.exist); +}; + +const adminUserExistsByAccountName = async (accountName) => { + const [adminUserExistsByAccountName] = await appDataSource.query( + ` + SELECT EXISTS ( + SELECT * + FROM admin_users + WHERE account_name = ? + ) exist + `, + [accountName] + ); + return adminUserExistsByAccountName; +}; + +const adminUserExistsByEmail = async (email) => { + const [adminUserExistsByEmail] = await appDataSource.query( + ` + SELECT EXISTS ( + SELECT * + FROM admin_users + WHERE email = ? + ) exist + `, + [email] + ); + return adminUserExistsByEmail; +}; + +const adminUserExistsByPhoneNumber = async (phoneNumber) => { + const [adminUserExistsByPhoneNumber] = await appDataSource.query( + ` + SELECT EXISTS ( + SELECT * + FROM admin_users + WHERE phone_number = ? + ) exist + `, + [phoneNumber] + ); + return adminUserExistsByPhoneNumber; +}; + +const createAdminUser = async ( + accountName, + hashedPassword, + personalCode, + name, + email, + phoneNumber +) => { + return await appDataSource.query( + ` + INSERT INTO admin_users( + account_name, + password, + personal_code, + name, + email, + phone_number + ) VALUES ( + ?, + ?, + ?, + ?, + ?, + ? + ); + `, + [accountName, hashedPassword, personalCode, name, email, phoneNumber] + ); +}; + +module.exports = { + confirmInsiderByEmail, + adminUserExistsByAccountName, + adminUserExistsByEmail, + adminUserExistsByPhoneNumber, + createAdminUser, +}; diff --git a/api/models/index.js b/api/models/index.js index 3e01288..025c16f 100644 --- a/api/models/index.js +++ b/api/models/index.js @@ -2,10 +2,12 @@ const dataSource = require("./dataSource"); const userDao = require("./userDao.js"); const productDao = require("./productDao"); const cartDao = require("./cartDao.js"); +const adminUserDao = require("./adminUserDao"); module.exports = { dataSource, userDao, productDao, cartDao, + adminUserDao, }; diff --git a/api/models/productDao.js b/api/models/productDao.js index b554c3c..c9eeee8 100644 --- a/api/models/productDao.js +++ b/api/models/productDao.js @@ -1,11 +1,19 @@ -const appDataSource = require("./dataSource"); +const { appDataSource } = require("./dataSource"); const queryBuilder = require("./queryBuilder"); -const getProductList = async (categoryIds, sorting, parsedLimit, parsedOffset) => { +const getProductList = async ( + categoryIds, + sorting, + parsedLimit, + parsedOffset +) => { try { const filterQuery = queryBuilder.filterBuilder(categoryIds); const orderQuery = queryBuilder.sortingBuilder(sorting); - const paginationQuery = queryBuilder.paginationBuilder(parsedLimit, parsedOffset); + const paginationQuery = queryBuilder.paginationBuilder( + parsedLimit, + parsedOffset + ); const productList = await appDataSource.query( ` SELECT diff --git a/api/routes/adminUserRouter.js b/api/routes/adminUserRouter.js new file mode 100644 index 0000000..04ace2d --- /dev/null +++ b/api/routes/adminUserRouter.js @@ -0,0 +1,8 @@ +const express = require("express"); +const { adminUserController } = require("../controllers"); + +const router = express.Router(); + +router.post("/signup", adminUserController.adminUserSignUp); + +module.exports = router; diff --git a/api/routes/index.js b/api/routes/index.js index a0fda45..63859d0 100644 --- a/api/routes/index.js +++ b/api/routes/index.js @@ -4,9 +4,11 @@ const router = express.Router(); const userRouter = require("./userRouter"); const productRouter = require("./productRouter"); const cartRouter = require("./cartRouter"); +const adminUserRouter = require("./adminUserRouter"); router.use("/users", userRouter); router.use("/products", productRouter); router.use("/carts", cartRouter); +router.use("/adminUsers", adminUserRouter); module.exports = router; diff --git a/api/services/adminUserService.js b/api/services/adminUserService.js new file mode 100644 index 0000000..3887f91 --- /dev/null +++ b/api/services/adminUserService.js @@ -0,0 +1,84 @@ +const bcrypt = require("bcrypt"); + +const { adminUserDao } = require("../models"); + +const adminUserSignUp = async ( + accountName, + password, + personalCode, + name, + email, + phoneNumber +) => { + const confirmedInsider = await adminUserDao.confirmInsiderByEmail(email); + + if (!confirmedInsider) { + const error = new Error("INVALID_APPROACH"); + error.statusCode = 401; + throw error; + } + + const saltRounds = 12; + + const accountNameRegEx = /^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]+$/; + const passwordRegEx = + /^(?=.*[a-z])(?=.*[!@#$%^&*()-=_+])[a-zA-Z\d!@#$%^&*()-=_+]{10,16}$/; + const personalCodeRegEx = /^\d{6}$/; + const emailRegEx = + /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/; + + const accountNameExist = await adminUserDao.adminUserExistsByAccountName( + accountName + ); + const emailExist = await adminUserDao.adminUserExistsByEmail(email); + const phoneNumberExist = await adminUserDao.adminUserExistsByPhoneNumber( + phoneNumber + ); + + if (!accountNameRegEx.test(accountName)) { + const error = new Error("INVALID_ACCOUNT_NAME"); + error.statusCode = 400; + throw error; + } + if (!passwordRegEx.test(password)) { + const error = new Error("INVALID_PASSWORD"); + error.statusCode = 400; + throw error; + } + if (!personalCodeRegEx.test(personalCode)) { + const error = new Error("INVALID_PERSONAL_CODE"); + error.statusCode = 400; + throw error; + } + + if (accountNameExist.exist > 0) { + const error = new Error("ACCOUNT_NAME_EXIST"); + error.statusCode = 409; + throw error; + } + if (emailExist.exist > 0) { + const error = new Error("EMAIL_EXIST"); + error.statusCode = 409; + throw error; + } + if (phoneNumberExist.exist > 0) { + const error = new Error("PHONE_NUMBER_EXIST"); + error.statusCode = 409; + throw error; + } + + const hashedPassword = await bcrypt.hash(password, saltRounds); + + return await adminUserDao.createAdminUser( + accountName, + hashedPassword, + personalCode, + name, + email, + phoneNumber + ); +}; + +module.exports = { + adminUserSignUp, +}; diff --git a/api/services/index.js b/api/services/index.js index afc8343..6cb571d 100644 --- a/api/services/index.js +++ b/api/services/index.js @@ -1,9 +1,11 @@ const userService = require("./userService"); const productService = require("./productService"); const cartService = require("./cartService"); +const adminUserService = require("./adminUserService"); module.exports = { userService, productService, cartService, + adminUserService, }; diff --git a/db/migrations/20230705060310_create_admin_users_table.sql b/db/migrations/20230705060310_create_admin_users_table.sql new file mode 100644 index 0000000..77d6516 --- /dev/null +++ b/db/migrations/20230705060310_create_admin_users_table.sql @@ -0,0 +1,16 @@ +-- migrate:up +CREATE TABLE admin_users ( + id INT NOT NULL AUTO_INCREMENT, + account_name varchar(200) NOT NULL UNIQUE, + password VARCHAR(200) NOT NULL, + personal_code INT NOT NULL, + name VARCHAR(50) NOT NULL, + email VARCHAR(200) NOT NULL UNIQUE, + phone_number VARCHAR(50) NOT NULL UNIQUE, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (id) +) + +-- migrate:down +DROP TABLE admin_users diff --git a/db/migrations/20230705071115_create_insider_emails_table.sql b/db/migrations/20230705071115_create_insider_emails_table.sql new file mode 100644 index 0000000..0f4d73a --- /dev/null +++ b/db/migrations/20230705071115_create_insider_emails_table.sql @@ -0,0 +1,9 @@ +-- migrate:up +CREATE TABLE insider_emails ( + id INT NOT NULL AUTO_INCREMENT, + email VARCHAR(200) NOT NULL UNIQUE, + PRIMARY KEY (id) +) + +-- migrate:down +DROP TABLE insider_emails From 6d1e5c50f4bb784ea84c5cf359fe3f904a846764 Mon Sep 17 00:00:00 2001 From: joonsooha123 <135545450+joonsooha123@users.noreply.github.com> Date: Thu, 6 Jul 2023 12:44:32 +0900 Subject: [PATCH 2/3] =?UTF-8?q?Modify:=20dao=EB=A0=88=EB=B2=A8=EC=97=90?= =?UTF-8?q?=EC=84=9C=20service=EB=A0=88=EB=B2=A8=EB=A1=9C=20=EC=A0=84?= =?UTF-8?q?=EB=8B=AC=ED=95=98=EB=8A=94=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=ED=98=95=EC=8B=9D=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EA=B7=B8?= =?UTF-8?q?=EC=97=90=20=EB=A7=9E=EA=B2=8C=20service=20=EC=A1=B0=EA=B1=B4?= =?UTF-8?q?=ED=8C=90=EB=B3=84=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/models/adminUserDao.js | 12 ++++++------ api/services/adminUserService.js | 14 ++++++++++---- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/api/models/adminUserDao.js b/api/models/adminUserDao.js index 0471183..1b7fed9 100644 --- a/api/models/adminUserDao.js +++ b/api/models/adminUserDao.js @@ -18,42 +18,42 @@ const adminUserExistsByAccountName = async (accountName) => { const [adminUserExistsByAccountName] = await appDataSource.query( ` SELECT EXISTS ( - SELECT * + SELECT id FROM admin_users WHERE account_name = ? ) exist `, [accountName] ); - return adminUserExistsByAccountName; + return !!parseInt(adminUserExistsByAccountName.exist); }; const adminUserExistsByEmail = async (email) => { const [adminUserExistsByEmail] = await appDataSource.query( ` SELECT EXISTS ( - SELECT * + SELECT id FROM admin_users WHERE email = ? ) exist `, [email] ); - return adminUserExistsByEmail; + return !!parseInt(adminUserExistsByEmail.exist); }; const adminUserExistsByPhoneNumber = async (phoneNumber) => { const [adminUserExistsByPhoneNumber] = await appDataSource.query( ` SELECT EXISTS ( - SELECT * + SELECT id FROM admin_users WHERE phone_number = ? ) exist `, [phoneNumber] ); - return adminUserExistsByPhoneNumber; + return !!parseInt(adminUserExistsByPhoneNumber.exist); }; const createAdminUser = async ( diff --git a/api/services/adminUserService.js b/api/services/adminUserService.js index 3887f91..36ec240 100644 --- a/api/services/adminUserService.js +++ b/api/services/adminUserService.js @@ -50,18 +50,24 @@ const adminUserSignUp = async ( error.statusCode = 400; throw error; } - - if (accountNameExist.exist > 0) { + // 중복검사 툴 수행 + // if (accountNameExist.exist > 0) { + // const error = new Error("ACCOUNT_NAME_EXIST"); + // error.statusCode = 409; + // throw error; + // } + if (accountNameExist) { const error = new Error("ACCOUNT_NAME_EXIST"); error.statusCode = 409; throw error; } - if (emailExist.exist > 0) { + + if (emailExist) { const error = new Error("EMAIL_EXIST"); error.statusCode = 409; throw error; } - if (phoneNumberExist.exist > 0) { + if (phoneNumberExist) { const error = new Error("PHONE_NUMBER_EXIST"); error.statusCode = 409; throw error; From f5679a8f33d68642634a880262d4b4bddd59d2b7 Mon Sep 17 00:00:00 2001 From: joonsooha123 <135545450+joonsooha123@users.noreply.github.com> Date: Thu, 6 Jul 2023 14:02:13 +0900 Subject: [PATCH 3/3] =?UTF-8?q?Style:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/services/adminUserService.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/api/services/adminUserService.js b/api/services/adminUserService.js index 36ec240..4e932da 100644 --- a/api/services/adminUserService.js +++ b/api/services/adminUserService.js @@ -50,12 +50,7 @@ const adminUserSignUp = async ( error.statusCode = 400; throw error; } - // 중복검사 툴 수행 - // if (accountNameExist.exist > 0) { - // const error = new Error("ACCOUNT_NAME_EXIST"); - // error.statusCode = 409; - // throw error; - // } + if (accountNameExist) { const error = new Error("ACCOUNT_NAME_EXIST"); error.statusCode = 409;