Commit ed9e5a14 authored by Jiwon Yoon's avatar Jiwon Yoon
Browse files

Merge branch 'gyumin'

parents 308d4f7f 3c84b7c1
...@@ -2,8 +2,8 @@ import axios from "axios"; ...@@ -2,8 +2,8 @@ import axios from "axios";
import { baseUrl } from "../utils/baseUrl.js"; import { baseUrl } from "../utils/baseUrl.js";
import config from "../utils/clientConfig.js"; import config from "../utils/clientConfig.js";
const login = async (id, password) => { const login = async (login) => {
const payload = { id, password }; const payload = login;
const { data } = await axios.post(`${baseUrl}/api/auth/login`, payload); const { data } = await axios.post(`${baseUrl}/api/auth/login`, payload);
return data return data
}; };
......
import { useState } from "react";
import styles from "./login.module.scss"; import styles from "./login.module.scss";
import { useState } from "react";
import authApi from "../../apis/auth.api.js";
import { Redirect } from "react-router";
import catchErrors from "../../utils/catchErrors";
const Login = () => { const Login = () => {
//useState를 이용해서 각 state 생성 및 초기값 저장 //useState를 이용해서 각 state 생성 및 초기값 저장
...@@ -9,9 +12,11 @@ const Login = () => { ...@@ -9,9 +12,11 @@ const Login = () => {
id:'', id:'',
password:'' password:''
}); });
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const [success, setSuccess] = useState(false); const [success, setSuccess] = useState(false);
const [guestText, setGusetText] = useState({ const [guest, setGuset] = useState({
guestName:'', guestName:'',
gusetBirthday:'', gusetBirthday:'',
gusetMbnum:'', gusetMbnum:'',
...@@ -28,15 +33,54 @@ const Login = () => { ...@@ -28,15 +33,54 @@ const Login = () => {
}; };
const handleGuestOnChange = (e) =>{ const handleGuestOnChange = (e) =>{
setGusetText({ ...guestText, setGuset({ ...guest,
[e.target.name]:e.target.value [e.target.name]:e.target.value
}) })
} }
const handleOnSummitUser = async(e) => {
e.preventDefault();
try{
console.log("하하")
setError("");
setLoading(true);
const userData = login;
await authApi.login(userData);
alert('로그인이 완료되었습니다.')
setSuccess(true);
}catch(error){
catchErrors(error, setError);
}finally{
setLoading(false);
}
}
const handleOnSummitGuest = async(e) => {
e.preventDefault();
try{
setError("");
setLoading(true);
const gusetData = guest;
await authApi.login(gusetData);
alert('로그인이 완료되었습니다.')
setSuccess(true);
}catch(error){
catchErrors(error, setError);
}finally{
setLoading(false);
}
}
if (success) {
return <Redirect to="/" />;
}
return ( return (
<div className={`d-flex flex-column col-md-5 col-10`}> <div className={`d-flex flex-column col-md-5 col-10`}>
{/* nav-tabs */} {/* nav-tabs */}
{/* {console.log(login)} */} {/* {console.log(login)} */}
{console.log(success)}
<ul className="nav nav-fill nav-tabs w-100" id="loginTab" role="tablist"> <ul className="nav nav-fill nav-tabs w-100" id="loginTab" role="tablist">
<li className="nav-item fs-6" role="presentation"> <li className="nav-item fs-6" role="presentation">
<button className={`nav-link active px-2 ${styles.fontSize}`} style={{ color: state ? "black" : "#FEDC00", backgroundColor: state ? "#FEDC00" : "black"}} <button className={`nav-link active px-2 ${styles.fontSize}`} style={{ color: state ? "black" : "#FEDC00", backgroundColor: state ? "#FEDC00" : "black"}}
...@@ -53,27 +97,27 @@ const Login = () => { ...@@ -53,27 +97,27 @@ const Login = () => {
<div className="tab-content w-100" id="myTabContent"> <div className="tab-content w-100" id="myTabContent">
{/* 로그인 */} {/* 로그인 */}
<div className="tab-pane fade show active" id="login" role="tabpanel" aria-labelledby="login-tab"> <div className="tab-pane fade show active" id="login" role="tabpanel" aria-labelledby="login-tab">
<div className="d-flex flex-column "> <form className="d-flex flex-column" onSubmit={handleOnSummitUser}>
<input className={styles.input} type="text" name="id" placeholder="ID" onChange={handleLoginOnChange}/> <input className={styles.input} type="text" name="id" placeholder="ID" onChange={handleLoginOnChange} maxLength="10" required/>
<input className={styles.input} type="text" name="password" placeholder="Password" onChange={handleLoginOnChange} minlength="8" required /> <input className={styles.input} type="password" name="password" placeholder="Password" onChange={handleLoginOnChange} maxLength="8" required />
<input className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} type="submit" value="Login" /> <input className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} type="submit" value="Login" disabled={loading} />
<span><a href="./signup" className={styles.intoSignupPage}>회원이 아니십니까?</a></span> <span><a href="./signup" className={styles.intoSignupPage}>회원이 아니십니까?</a></span>
</div> </form>
</div> </div>
{/* 비회원예매 학인 */} {/* 비회원예매 학인 */}
<div className="tab-pane fade" id="guest" role="tabpanel" aria-labelledby="guest-tab"> <div className="tab-pane fade" id="guest" role="tabpanel" aria-labelledby="guest-tab">
<div className="d-flex flex-column"> <form className="d-flex flex-column" onSubmit={handleOnSummitGuest}>
<input className={styles.input} type="text" name="guestName" id="guestName" placeholder="이름" onChange={handleGuestOnChange} minlength="8" required /> <input className={styles.input} type="text" name="guestName" id="guestName" placeholder="이름" onChange={handleGuestOnChange} maxLength="5" required />
<input className={styles.input} type="number" name="gusetBirthday" id="gusetBirthday" placeholder="생년월일" onChange={handleGuestOnChange} minlength="8" required /> <input className={styles.input} type="number" name="gusetBirthday" id="gusetBirthday" placeholder="생년월일" onChange={handleGuestOnChange} maxLength="6" required />
<input className={styles.input} type="number" name="gusetMbnum" id="gusetMbnum" placeholder="휴대폰 번호" onChange={handleGuestOnChange} minlength="8" required /> <input className={styles.input} type="number" name="gusetMbnum" id="gusetMbnum" placeholder="휴대폰 번호" onChange={handleGuestOnChange} maxLength="11" required />
<input className={styles.input} type="text" name="guestPassword" id="password" placeholder="비밀번호" onChange={handleGuestOnChange} minlength="8" required /> <input className={styles.input} type="password" name="guestPassword" id="password" placeholder="비밀번호" onChange={handleGuestOnChange} maxLength="8" required />
<p className={`text-white ${styles.fontSizeTwo}`}> <p className={`text-white ${styles.fontSizeTwo}`}>
비회원 정보 입력 예매 내역 확인/취소 티켓 발권이 어려울 있으니 다시 한번 확인해 주시기 바랍니다. 비회원 정보 입력 예매 내역 확인/취소 티켓 발권이 어려울 있으니 다시 한번 확인해 주시기 바랍니다.
</p> </p>
<input className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} type="submit" value="비회원 예매 확인" /> <input className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} type="submit" value="비회원 예매 확인" disabled={loading}/>
</div> </form>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -14,6 +14,14 @@ ...@@ -14,6 +14,14 @@
border-radius: 3px; border-radius: 3px;
} }
input[type=password]{
font-family: 'Courier New', Courier, monospace;
}
input::placeholder{
font-family: 'HangeulNuriB'
}
.fontSize{ .fontSize{
font-size: 16px; font-size: 16px;
} }
......
import styles from "./signup.module.scss"; import styles from "./signup.module.scss";
import { useState, useEffect } from 'react'; import { useState } from 'react';
import authApi from "../../apis/auth.api.js"; import authApi from "../../apis/auth.api.js";
import { Redirect } from "react-router"; import { Redirect } from "react-router";
import catchErrors from "../../utils/catchErrors.js"; import catchErrors from "../../utils/catchErrors.js";
const Signup = () => { const Signup = () => {
const [user, setUser] = useState({ const [user, setUser] = useState({
userId: '', userId: "",
userName: '', userNickName: "",
userBirthday: '', userBirthday: "",
userMbnum: '', userMbnum: "",
userPassword: '', userPassword: "",
userRePassword: '' userRePassword: ""
}) })
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [success, setSuccess] = useState(false); const [success, setSuccess] = useState(false);
//각 타입별 error 유무 state //각 타입별 error 유무 state
const [error,setError] = useState(""); const [error,setError] = useState("");
const [errorMsg, setErrorMsg] = useState({ const [errorMsg, setErrorMsg] = useState({
errorId: null, errorId: null,
errorName: false, errorNickName: false,
errorBirthday: false, errorBirthday: false,
errorMbnum: false, errorMbnum: false,
errorPassword: false, errorPassword: false,
...@@ -36,36 +36,56 @@ const Signup = () => { ...@@ -36,36 +36,56 @@ const Signup = () => {
...user, ...user,
[e.target.name]: e.target.value [e.target.name]: e.target.value
}) })
if(e.target.name === "userBirthday" || e.target.name === "userMbum"){
setUser({
...user,
[e.target.name]: String(e.target.value)
})
}
} }
//id(중복확인 체크, 형식 에러) //id(중복확인 체크, 형식 에러)
const handleOnClickId = async (e) => { const handleOnClickId = async (e) => {
e.preventDefault(); e.preventDefault();
const existId = await authApi.compareId(user.userId) try{
if (user.userId.length < 5) { setError("");
setErrorMsg(errorMsg => ({ if (user.userId.length < 5) {
...errorMsg, setErrorMsg(errorMsg => ({
[e.target.name]: true ...errorMsg,
})); [e.target.name]: true
if (existId === true) { }));
setOverlapId(() => (false)); if (overlapId === true) {
}; setOverlapId(() => (false));
} else { };
setErrorMsg(errorMsg => ({ } else {
...errorMsg, const userId = user.userId;
[e.target.name]: false await authApi.compareId(userId);
})); if(!await authApi.compareId(userId)){
setOverlapId(() => (true)); alert("이 아이디는 사용가능합니다.")
alert("이 아이디는 사용가능합니다.") setErrorMsg(errorMsg => ({
...errorMsg,
[e.target.name]: false
}));
setOverlapId(()=>(true));
}else{
alert("이미 사용중인 아이디입니다.")
setOverlapId(()=>(false));
}
}
}catch(error){
catchErrors(error,setError)
}finally {
setLoading(false);
} }
} }
const handleOnSummit = async (e) => { const handleOnSummit = async (e) => {
e.preventDefault(); e.preventDefault();
try { try {
setError(""); setError(()=>(""));
//처리가 될때까지 버튼(가입하기)이 안눌리게 지정 //처리가 될때까지 버튼(가입하기)이 안눌리게 지정
setLoading(true); setLoading(()=>(true));
//유효성 검사 //유효성 검사
validation(); validation();
const userData = user; const userData = user;
...@@ -81,46 +101,49 @@ const Signup = () => { ...@@ -81,46 +101,49 @@ const Signup = () => {
} }
} }
//유효성 검사 함수 //비교하여 error메세지 반환
const vaildationData = (text, compareValue, error) =>{ const vaildationData = (text, compareValue, error) => {
if (text !== compareValue) { if (text !== compareValue) {
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: true })); setErrorMsg(errorMsg => ({ ...errorMsg, [error]: true }));
} else{ } else{
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: false })); setErrorMsg(errorMsg => ({ ...errorMsg, [error]: false }));
} }
} }
//아이디 비번 유효성 검사
const vaildationIdPw = (text, minValue, error) => {
if((text < minValue)){
setErrorMsg(errorMsg => ({...errorMsg, [error]: true}));
} else if(text >= minValue){
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: false }));
if(overlapId === true){
if(preId !== user.userId){
setOverlapId(false);
}
}
}
}
//유효성 검사 //유효성 검사
const validation = () => { const validation = () => {
setPreId(()=> (user.userId)); setPreId(user.userId);
//아이디 유효성 검사 //아이디 유효성 검사
if ((user.userId.length < 5)) { vaildationIdPw(user.userId.length,5,"errorId");
setErrorMsg(errorMsg => ({ ...errorMsg, errorId: true }));
} else if((user.userId.length >= 5) && (overlapId === true)){
if(preId !== user.userId){
console.log(preId);
setOverlapId(()=> (false));
}
}
else if(user.userId >= 5){
setErrorMsg(errorMsg => ({ ...errorMsg, errorId: false }));
}
//별명 유효성 검사 //별명 유효성 검사
vaildationData((user.userName.length === 0), false, "errorName"); vaildationData((user.userNickName.length === 0), false, "errorNickName");
// 생일 유효성 검사 // 생일 유효성 검사
vaildationData(user.userBirthday.length, 6, "errorBirthday"); vaildationData(user.userBirthday.length, 6, "errorBirthday");
// 휴대폰 유효성 검사 // 휴대폰 유효성 검사
vaildationData(user.userMbnum.length, 11, "errorMbnum"); vaildationData(user.userMbnum.length, 11, "errorMbnum");
// 비밀번호 유효성 검사 // 비밀번호 유효성 검사
vaildationData(user.userPassword.length, 8, "errorPassword"); vaildationIdPw(user.userPassword.length,8,"errorPassword");
// 비밀번호 확인 유효성 검사 // 비밀번호 확인 유효성 검사
vaildationData(user.userRePassword, user.userPassword, "errorRePassword"); vaildationData(user.userRePassword, user.userPassword, "errorRePassword");
// 최종 유효성 검사 // 최종 유효성 검사
if (overlapId && (Object.values(errorMsg).some((element) => (element)) === false)) { if (overlapId && (Object.values(errorMsg).some((element) => (element)) === false)) {
console.log(";sadasda") }else if(!overlapId && (Object.values(errorMsg).some((element) => (element)) === false)){
setErrorMsg(errorMsg => ({...errorMsg, errorId: false}));
throw new Error("먼저 아이디 중복확인을 해주세요");
}else{ }else{
console.log("에러발생")
throw new Error("유효하지 않은 데이터입니다."); throw new Error("유효하지 않은 데이터입니다.");
} }
} }
...@@ -133,7 +156,6 @@ const Signup = () => { ...@@ -133,7 +156,6 @@ const Signup = () => {
return ( return (
// 데이터 입력과 유효성 검사 후 보이는 경고창 // 데이터 입력과 유효성 검사 후 보이는 경고창
<form className={`d-flex col-md-6 col-12 justify-content-center`} onSubmit={handleOnSummit}> <form className={`d-flex col-md-6 col-12 justify-content-center`} onSubmit={handleOnSummit}>
{console.log("user==", user, errorMsg, overlapId)}
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<span className={styles.title}>회원가입</span> <span className={styles.title}>회원가입</span>
<div className="d-flex flex-column"> <div className="d-flex flex-column">
...@@ -141,20 +163,19 @@ const Signup = () => { ...@@ -141,20 +163,19 @@ const Signup = () => {
<label className={styles.signupLabel}>아이디</label> <label className={styles.signupLabel}>아이디</label>
<div className="d-flex col-md-auto"> <div className="d-flex col-md-auto">
<input className={styles.input} type="text" name="userId" id="userId" placeholder="5~10자리 사이" onChange={handleUserOnChange} maxLength="10" required /> <input className={styles.input} type="text" name="userId" id="userId" placeholder="5~10자리 사이" onChange={handleUserOnChange} maxLength="10" required />
<button type="button" name="errorId" className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} onClick={handleOnClickId}>중복확인</button> <button type="button" disabled={loading} name="errorId" className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} onClick={handleOnClickId}>중복확인</button>
</div> </div>
</div> </div>
{(overlapId === false) && errorMsg.errorId && <p className={styles.passwordConfirmError}>5~10자리 사이로 입력해주세요.</p>} {(overlapId === false) && errorMsg.errorId && <p className={styles.passwordConfirmError}>5~10자리 사이로 입력해주세요.</p>}
{overlapId && (errorMsg.errorId === false) && <p className={styles.passwordConfirmError}>아이디 중복이 확인되었습니다.</p>} {overlapId && (errorMsg.errorId === false) && <p className={styles.passwordConfirmError}>아이디 중복이 확인되었습니다.</p>}
{(errorMsg.errorId === false) && (overlapId === false) && <p className={styles.passwordConfirmError}>아이디 중복확인을 해주세요.</p>} {(errorMsg.errorId === false) && (overlapId === false) && <p className={styles.passwordConfirmError}>아이디 중복확인을 해주세요.</p>}
</div> </div>
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<div className={styles.inputContent}> <div className={styles.inputContent}>
<label className={styles.signupLabel}>별명</label> <label className={styles.signupLabel}>별명</label>
<input className={`${styles.input} ${styles.inputSize}`} type="text" name="userName" id="userName" placeholder="10자리 이내" onChange={handleUserOnChange} maxLength="10" required /> <input className={`${styles.input} ${styles.inputSize}`} type="text" name="userNickName" id="userNickName" placeholder="10자리 이내" onChange={handleUserOnChange} maxLength="10" required />
</div> </div>
{errorMsg.errorName && <p className={styles.passwordConfirmError}>10 이내로 입력해주세요.</p>} {errorMsg.errorNickName && <p className={styles.passwordConfirmError}>10 이내로 입력해주세요.</p>}
</div> </div>
<div className="d-flex flex-column"> <div className="d-flex flex-column">
...@@ -168,23 +189,22 @@ const Signup = () => { ...@@ -168,23 +189,22 @@ const Signup = () => {
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<div className={styles.inputContent}> <div className={styles.inputContent}>
<label className={styles.signupLabel}>휴대폰 번호</label> <label className={styles.signupLabel}>휴대폰 번호</label>
<input className={`${styles.input} ${styles.inputSize}`} type="number" name="userMbnum" id="userMbnum" placeholder="-없이 11자리 입력" onChange={handleUserOnChange} min="0" max="99999999999" required /> <input className={`${styles.input} ${styles.inputSize}`} type="number" name="userMbnum" id="userMbnum" placeholder="-없이 11자리 입력" onChange={handleUserOnChange} min="" max="99999999999" required />
</div> </div>
{errorMsg.errorMbnum && <p className={styles.passwordConfirmError}>-없이 숫자 11자리를 입력해주세요.</p>} {errorMsg.errorMbnum && <p className={styles.passwordConfirmError}>-없이 숫자 11자리를 입력해주세요.</p>}
</div> </div>
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<div className={`${styles.inputContent}`}> <div className={`${styles.inputContent}`}>
<label className={styles.signupLabel}>비밀번호</label> <label className={styles.signupLabel}>비밀번호</label>
<input className={`${styles.input} ${styles.inputSize}`} type="password" name="userPassword" id="password" placeholder="8자리 입력" onChange={handleUserOnChange} maxLength="8" required /> <input className={`${styles.input} ${styles.inputSize}`} type="password" name="userPassword" id="password" placeholder="8~11자리 사이" onChange={handleUserOnChange} maxLength="11" required />
</div> </div>
{errorMsg.errorPassword && <p className={styles.passwordConfirmError}>8자리를 입력해주세요.</p>} {errorMsg.errorPassword && <p className={styles.passwordConfirmError}>8~11자리 사이로 입력해주세요.</p>}
</div> </div>
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<div className={styles.inputContent}> <div className={styles.inputContent}>
<label className={styles.signupLabel}>비밀번호 확인</label> <label className={styles.signupLabel}>비밀번호 확인</label>
<input className={`${styles.input} ${styles.inputSize}`} type="password" name="userRePassword" id="userRePassword" placeholder="8자리 입력" onChange={handleUserOnChange} maxLength="8" required /> <input className={`${styles.input} ${styles.inputSize}`} type="password" name="userRePassword" id="userRePassword" placeholder="8~11자리 사이" onChange={handleUserOnChange} maxLength="11" required />
</div> </div>
{errorMsg.errorRePassword && <p className={styles.passwordConfirmError}>비밀번호가 일치하지 않습니다.</p>} {errorMsg.errorRePassword && <p className={styles.passwordConfirmError}>비밀번호가 일치하지 않습니다.</p>}
</div> </div>
......
const config = { const config = {
env: process.env.NODE_ENV === 'production' ? 'production' : 'development', env: process.env.NODE_ENV === 'production' ? 'production' : 'development',
port: process.env.PORT || 3001, port: process.env.PORT || 3001,
// jwtSecret: 'dfkasf23i$efksdfks!', jwtSecret: 'dfkasf23i$efksdfks!',
jwtExpires: '7d', jwtExpires: '7d',
cookieName: 'butterStudio', cookieName: 'butterStudio',
cookieMaxAge: 60 * 60 * 24 * 7 * 1000, cookieMaxAge: 60 * 60 * 24 * 7 * 1000,
......
import axios from 'axios' import jwt from "jsonwebtoken";
import sequelize from 'sequelize' import config from "../config/app.config.js";
import { User } from '../db/index.js' import { User, Role } from '../db/index.js'
const login = async(req, res) => {
try {
const { id, password } = req.body;
//사용자 존재 확인
const user = await User.scope("withPassword").findOne({ where: { userId: id } });
if (!user) {
return res.status(422).send(`사용자가 존재하지 않습니다`);
}
// 2) 비밀번호 확인은 데이터베이스 프로토타입 메소드에서 처리(사용자가 입력한 비밀번호와 서버에 있는 비번 비교)
const passwordMatch = await user.comparePassword(password);
if (passwordMatch) {
// 3) 비밀번호가 맞으면 토큰 생성
// const userRole = await user.getRole();
const signData = {
userId: user.id,
// role: userRole.name,
};
const token = jwt.sign(signData, config.jwtSecret, {
expiresIn: config.jwtExpires,
});
console.log("token = ", token);
// 4) 토큰을 쿠키에 저장
res.cookie(config.cookieName, token, {
maxAge: config.cookieMaxAge,
path: "/",
httpOnly: config.env === "production",
secure: config.env === "production",
});
// 5) 사용자 반환
res.json({
userId: user.id,
isLoggedIn: true,
// role: userRole.name,
// isMember: user.isMember,
});
} else {
// 6) 비밀번호 불일치
res.status(401).send("비밀번호가 일치하지 않습니다");
}
} catch (error) {
console.error(error);
return res.status(500).send("로그인 에러");
}
}
const compareId = async (req, res) => { const compareId = async (req, res) => {
const id = req.params.userId; const id = req.params.userId;
const userid = await User.findAll({where:{userId: id}}); const userid = await User.findOne({where:{userId: id}});
if(userid){ if(userid !== null){
return res.json(true); return res.json(true);
}else{ }else{
return res.json(false); return res.json(false);
} }
} }
const signup = async (req, res) => {
const { userId, userNickName, userBirthday, userPassword } = req.body;
// 휴대폰 중복 확인
const userMbnum = String(req.body.userMbnum);
try {
const mbnum = await User.findOne({ where: { phoneNumber: userMbnum } });
if (mbnum) {
return res.status(422).send(`이미 있는 휴대폰번호입니다.`);
}
const role = await Role.findOne({ where: {name: "user"} })
const newUser = await User.create({
userId: userId,
nickname: userNickName,
birth: userBirthday,
phoneNumber: userMbnum,
password: userPassword,
roleId: role.id
});
res.json(newUser);
} catch (error) {
console.error(error.message);
res.status(500).send("회원가입 에러. 나중에 다시 시도 해주세요");
}
};
export default { export default {
compareId login,
compareId,
signup
} }
...@@ -29,6 +29,9 @@ const Cinema = CinemaModel(sequelize) ...@@ -29,6 +29,9 @@ const Cinema = CinemaModel(sequelize)
User.belongsTo(Role); User.belongsTo(Role);
Role.hasOne(User); Role.hasOne(User);
User.belongsTo(Role);
Role.hasOne(User);
export { export {
sequelize, sequelize,
User, User,
......
import dotenv from "dotenv"; import dotenv from "dotenv";
import { sequelize } from "./db/index.js"; import { sequelize, Role } from "./db/index.js";
import app from "./app.js"; import app from "./app.js";
import appConfig from "./config/app.config.js"; import appConfig from "./config/app.config.js";
import { ROLE_NAME } from './models/role.model.js';
dotenv.config({ dotenv.config({
path: `${process.env.NODE_ENV === "production" ? ".env" : ".env.development" path: `${process.env.NODE_ENV === "production" ? ".env" : ".env.development"
...@@ -11,11 +12,11 @@ dotenv.config({ ...@@ -11,11 +12,11 @@ dotenv.config({
sequelize sequelize
.sync({ force: false }) .sync({ force: false })
.then(async () => { .then(async () => {
// await Promise.all( await Promise.all(
// Object.keys(ROLE_NAME).map((name) => { Object.keys(ROLE_NAME).map((name) => {
// return Role.create({ name }); return Role.create({ name });
// }) })
// ); );
// const adminRole = await Role.findOne({ where: { name: "admin" } }); // const adminRole = await Role.findOne({ where: { name: "admin" } });
......
...@@ -16,33 +16,53 @@ const UserModel = (sequelize) => { ...@@ -16,33 +16,53 @@ const UserModel = (sequelize) => {
userId: { userId: {
type: DataTypes.STRING, type: DataTypes.STRING,
}, },
password: {
type: DataTypes.STRING,
},
nickname: { nickname: {
type: DataTypes.STRING, type: DataTypes.STRING,
}, },
birth: { birth: {
type: DataTypes.INTEGER, type: DataTypes.STRING,
}, },
phoneNumber: { phoneNumber: {
type: DataTypes.INTEGER type: DataTypes.STRING
},
password: {
type: DataTypes.STRING,
}, },
}, },
{ {
timestamps: true, timestamps: true,
freezeTableName: true, freezeTableName: true,
tableName: "users" tableName: "users",
// defaultScope: { defaultScope: {
// attributes: { exclude: ["password"] }, attributes: { exclude: ["password"] },
// }, },
// scopes: { scopes: {
// withPassword: { withPassword: {
// attributes: { include: ["password"] }, attributes: { include: ["password"] },
// }, },
// }, },
} }
); );
User.beforeSave(async (user) => {
if (!user.changed("password")) {
return;
}
if (user.password) {
const hashedPassword = await bcrypt.hash(user.password, 10);
user.password = hashedPassword;
}
});
User.prototype.comparePassword = async function (plainPassword) {
const passwordMatch = await bcrypt.compare(
plainPassword,
this.password
);
return passwordMatch;
};
return User return User
}; };
......
...@@ -4,9 +4,13 @@ import userCtrl from "../controllers/user.controller.js"; ...@@ -4,9 +4,13 @@ import userCtrl from "../controllers/user.controller.js";
const router = express.Router(); const router = express.Router();
router router
.route("/") .route("/login")
.post() .post(userCtrl.login)
.get()
router
.route("/signup")
.post(userCtrl.signup)
router router
.route("/:userId") .route("/:userId")
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment