Commit 73dd813f authored by Jiwon Yoon's avatar Jiwon Yoon
Browse files

Merge branch 'gyumin'

parents 0b1deeab eacc9ce9
...@@ -23,6 +23,7 @@ function App() { ...@@ -23,6 +23,7 @@ function App() {
<AuthProvider> <AuthProvider>
<Router> <Router>
<Switch> <Switch>
<>
<Route path="/admin" component={AdminPage} /> <Route path="/admin" component={AdminPage} />
<div style={{ backgroundColor: "black" }}> <div style={{ backgroundColor: "black" }}>
<Router> <Router>
...@@ -45,6 +46,7 @@ function App() { ...@@ -45,6 +46,7 @@ function App() {
</Switch> </Switch>
</Router> </Router>
</div> </div>
</>
</Switch> </Switch>
</Router> </Router>
</AuthProvider> </AuthProvider>
......
...@@ -14,19 +14,13 @@ const login = async (login) => { ...@@ -14,19 +14,13 @@ const login = async (login) => {
}; };
const logout = async () => { const logout = async () => {
alert("로그아웃되었습니다.");
const { data } = await axios.get(`${baseUrl}/api/auth/logout`); const { data } = await axios.get(`${baseUrl}/api/auth/logout`);
return data return data
}; };
const signup = async (user) => { const signup = async (user) => {
const url = `${baseUrl}/api/auth/signup` const url = `${baseUrl}/api/auth/signup`;
await axios.post(url, user) const { data } = await axios.post(url, user);
}
const compareId = async (userId) => {
const url = `${baseUrl}/api/auth/${userId}`
const { data } = await axios.get(url)
return data return data
} }
...@@ -47,7 +41,7 @@ const profile = async (formData) => { ...@@ -47,7 +41,7 @@ const profile = async (formData) => {
const { data } = await axios.post(url, formData) const { data } = await axios.post(url, formData)
return data return data
} }
const getMember = async (id) => { const getMember = async () => {
const url = `${baseUrl}/api/auth/member` const url = `${baseUrl}/api/auth/member`
const { data } = await axios.get(url) const { data } = await axios.get(url)
return data return data
...@@ -70,7 +64,6 @@ const authApi = { ...@@ -70,7 +64,6 @@ const authApi = {
login, login,
logout, logout,
signup, signup,
compareId,
confirmMbnum, confirmMbnum,
confirmNum, confirmNum,
profile, profile,
......
...@@ -42,7 +42,11 @@ const Login = () => { ...@@ -42,7 +42,11 @@ const Login = () => {
const requestServer = async (data) => { const requestServer = async (data) => {
if(data === user){ if(data === user){
await login(data); const success = await login(data);
if(success){
setSuccess(true);
alert('로그인이 완료되었습니다.')
}
}else{ }else{
} }
} }
...@@ -51,11 +55,8 @@ const Login = () => { ...@@ -51,11 +55,8 @@ const Login = () => {
e.preventDefault(); e.preventDefault();
try { try {
setError(""); setError("");
console.log(e.target.name);
if (e.target.name === "login") { if (e.target.name === "login") {
requestServer(user); requestServer(user);
alert('로그인이 완료되었습니다.')
setSuccess(true);
} }
else { else {
requestServer(guest); requestServer(guest);
......
...@@ -42,7 +42,6 @@ const MyInfo = () => { ...@@ -42,7 +42,6 @@ const MyInfo = () => {
errorNickName: false, errorNickName: false,
errorMbnum: false, errorMbnum: false,
errorPassword: false, errorPassword: false,
errorRePassword: false
}) })
useEffect(() => { useEffect(() => {
...@@ -83,7 +82,6 @@ const MyInfo = () => { ...@@ -83,7 +82,6 @@ const MyInfo = () => {
const formData = new FormData(); const formData = new FormData();
formData.append("image", img); formData.append("image", img);
const image = await authApi.profile(formData); const image = await authApi.profile(formData);
console.log(image.img);
setProfile(image.img); setProfile(image.img);
} catch (error) { } catch (error) {
catchErrors(error, setError); catchErrors(error, setError);
...@@ -93,13 +91,15 @@ const MyInfo = () => { ...@@ -93,13 +91,15 @@ const MyInfo = () => {
const handleOnSummitVerify = async (e) => { const handleOnSummitVerify = async (e) => {
e.preventDefault(); e.preventDefault();
try { try {
setError(() => ("")); setError("");
setLoading(() => (true)); setLoading(true);
const pw = presentPw; const pw = presentPw;
console.log(pw);
const confirmPw = await authApi.comparePw(pw); const confirmPw = await authApi.comparePw(pw);
console.log("confirmPw : "+ confirmPw); console.log("confirmPw : ", confirmPw);
if (confirmPw) { if (confirmPw) {
setPage(false); setPage(false);
setPresentPw("");
} else { } else {
alert("비밀번호가 일치하지 않습니다."); alert("비밀번호가 일치하지 않습니다.");
} }
...@@ -117,12 +117,9 @@ const MyInfo = () => { ...@@ -117,12 +117,9 @@ const MyInfo = () => {
setError(""); setError("");
setLoading(true); setLoading(true);
const phone = userRe.userMbnum; const phone = userRe.userMbnum;
console.log("phone : ", phone);
const message = await authApi.confirmMbnum(phone); const message = await authApi.confirmMbnum(phone);
console.log("message : ", message);
if(message.isSuccess){ if(message.isSuccess){
console.log("mberror: "+mbError);
setMbError("보냄"); setMbError("보냄");
setStartTime(message.startTime); setStartTime(message.startTime);
} }
...@@ -142,11 +139,8 @@ const MyInfo = () => { ...@@ -142,11 +139,8 @@ const MyInfo = () => {
try { try {
setError(""); setError("");
setLoading(true); setLoading(true);
console.log("startTime : ", startTime);
const confirmNum = {userMbnum : userRe.userMbnum, number : number, startTime : startTime}; const confirmNum = {userMbnum : userRe.userMbnum, number : number, startTime : startTime};
console.log(confirmNum);
const message = await authApi.confirmNum(confirmNum); const message = await authApi.confirmNum(confirmNum);
console.log(message);
setMbError(message); setMbError(message);
if(message === "성공"){ if(message === "성공"){
setConfirmMb(true); setConfirmMb(true);
...@@ -159,73 +153,49 @@ const MyInfo = () => { ...@@ -159,73 +153,49 @@ const MyInfo = () => {
} }
} }
//비교하여 error메세지 반환 const validationPw = () => {
const vaildationData = (text, compareValue, error) => { if(userRe.userPassword !== userRe.userRePassword){
if (text !== compareValue) { return false;
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: true })); }else{return true;}
} else {
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: false }));
}
}
const vaildationIdPw = (text, minValue, error) => {
if ((text < minValue)) {
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: true }));
} else {
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: false }));
}
}
//유효성 검사
const validation = () => {
//이름 유효성 검사
vaildationData((userRe.userName.length === 0), false, "errorName");
//별명 유효성 검사
vaildationData((userRe.userNickName.length === 0), false, "errorNickName");
// 휴대폰 유효성 검사
vaildationData(userRe.userMbnum.length, 11, "errorMbnum");
// 비밀번호 유효성 검사
vaildationIdPw(userRe.userPassword.length, 8, "errorPassword");
// 비밀번호 확인 유효성 검사
vaildationData(userRe.userPassword, userRe.userRePassword, "errorRePassword");
// 최종 유효성 검사
if (!(Object.values(errorMsg).some((element) => (element)))) {
return true
} else {
return false
}
} }
const handleOnSummit = async (e) => { const handleOnSummit = async (e) => {
e.preventDefault(); e.preventDefault();
try { try {
console.log('handle ?????') setError("");
setError(() => (""));
//처리가 될때까지 버튼(가입하기)이 안눌리게 지정 //처리가 될때까지 버튼(가입하기)이 안눌리게 지정
setLoading(() => (true)); setLoading(true);
//유효성 검사 let validPw = validationPw();
let valid = validation(); if(confirmMb){
console.log('handle on submit', valid) if(validPw){
if (valid) {
const userData = userRe; const userData = userRe;
console.log(userData);
//서버로 전송 //서버로 전송
const result = await authApi.modifyUser(userData); const error = await authApi.modifyUser(userData);
console.log("result : " + result); if(error === "성공"){
alert("회원정보 수정 완료"); alert("회원정보수정에 성공하였습니다.")
valid = false; }else{
} else { throw new Error("유효하지 않은 데이터입니다.") } setErrorMsg(error);
alert("형식에 맞게 다시 작성해주세요");
}
}else{
throw new Error("비밀번호가 일치하지 않습니다.");
}
}else{
throw new Error("핸드폰 번호를 인증해주세요.");
}
} catch (error) { } catch (error) {
//에러전송 //에러전송
catchErrors(error, setError); catchErrors(error, setError);
} finally { } finally {
setLoading(() => (false)); setLoading(false);
} }
} }
const handleOnclickOut = (e) => {
setConfirmMb(false);
}
const handleOnClick = (e) => { const handleOnClick = (e) => {
e.preventDefault(); e.preventDefault();
handleOnclickOut(e);
setPage(true); setPage(true);
} }
...@@ -234,14 +204,14 @@ const MyInfo = () => { ...@@ -234,14 +204,14 @@ const MyInfo = () => {
{/* 마이페이지 창 */} {/* 마이페이지 창 */}
<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 justify-content-around"> <div className={`d-flex justify-content-around`}>
<div className={`${styles.box} me-5`}> <div className={`${styles.box}`}>
<p className={`${styles.hoverTxt}`}>프로필 변경</p> <p className={`${styles.hoverTxt}`}>프로필 변경</p>
<img src={`/upload/${profile}`} className={`figure-img img-fluid rounded-circle ${styles.profile}`} role="button" data-bs-toggle="modal" data-bs-target="#staticBackdrop" /> <img src={`/upload/${profile}`} className={`figure-img img-fluid rounded-circle ${styles.img} ${styles.profile}`} role="button" data-bs-toggle="modal" data-bs-target="#staticBackdrop" />
</div> </div>
<div className="d-flex flex-column py-4 justify-content-around"> <div className="d-flex flex-column py-2 justify-content-around">
<span className={`${styles.userName}`}>{`${userNickName}`} 반갑습니다!</span> <span className={`${styles.userName}`}>{`${userNickName}`} 반갑습니다!</span>
<button className={`rounded my-3 fs-5 ${styles.butterYellowAndBtn} ${styles.btnHover}`} data-bs-toggle="modal" href="#verifyPassword" >회원정보 수정</button> <button className={`rounded my-2 fs-5 ${styles.butterYellowAndBtn} ${styles.btnHover}`} data-bs-toggle="modal" href="#verifyPassword" >회원정보 수정</button>
</div> </div>
</div> </div>
</div> </div>
...@@ -277,7 +247,7 @@ const MyInfo = () => { ...@@ -277,7 +247,7 @@ const MyInfo = () => {
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<div className="d-flex justify-content-around align-items-center my-4"> <div className="d-flex justify-content-around align-items-center my-4">
<label className={styles.signupLabel}>현재 비밀번호</label> <label className={styles.signupLabel}>현재 비밀번호</label>
<input className={`${styles.input} ${styles.inputSize}`} type="password" name="userPassword" placeholder="8~11자리 사이" onChange={handlePwOnChange} onKeyPress={enterKey} maxLength="11" required /> <input className={`${styles.input} ${styles.inputSize}`} type="password" name="userPassword" placeholder="8~11자리 사이" onChange={handlePwOnChange} onKeyPress={enterKey} maxLength="11" />
</div> </div>
</div> </div>
</div> </div>
...@@ -294,21 +264,21 @@ const MyInfo = () => { ...@@ -294,21 +264,21 @@ const MyInfo = () => {
<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" placeholder="이름을 입력해주세요" onChange={handleUserOnChange} maxLength="11" required /> <input className={`${styles.input} ${styles.inputSize}`} type="text" name="userName" placeholder="이름을 입력해주세요" onChange={handleUserOnChange} maxLength="11" />
</div> </div>
{errorMsg.errorName && <p className={styles.passwordConfirmError}>이름을 입력해주세요</p>} {errorMsg.errorName && <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="email" name="userEmail" placeholder="이메일을 입력해주세요" onChange={handleUserOnChange} maxLength="20" required /> <input className={`${styles.input} ${styles.inputSize}`} type="email" name="userEmail" placeholder="이메일을 입력해주세요" onChange={handleUserOnChange} maxLength="20" />
</div> </div>
{errorMsg.errorEmail && <p className={styles.passwordConfirmError}>이메일을 입력해주세요</p>} {errorMsg.errorEmail && <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="userNickName" placeholder="10자리 이내" onChange={handleUserOnChange} maxLength="10" required /> <input className={`${styles.input} ${styles.inputSize}`} type="text" name="userNickName" placeholder="10자리 이내" onChange={handleUserOnChange} maxLength="10" />
</div> </div>
{errorMsg.errorNickName && <p className={styles.passwordConfirmError}>10 이내로 입력해주세요.</p>} {errorMsg.errorNickName && <p className={styles.passwordConfirmError}>10 이내로 입력해주세요.</p>}
</div> </div>
...@@ -317,7 +287,7 @@ const MyInfo = () => { ...@@ -317,7 +287,7 @@ const MyInfo = () => {
<div className={styles.inputContent}> <div className={styles.inputContent}>
<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="number" name="userMbnum" placeholder="-없이 11자리 입력" onChange={handleUserOnChange} min="" max="99999999999" required /> <input className={`${styles.input} `} type="number" name="userMbnum" placeholder="-없이 11자리 입력" onChange={handleUserOnChange} min="" max="99999999999" />
<button type="button" disabled={loading} className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} data-bs-toggle="collapse" data-bs-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample" onClick={handleOnClickMbnum}>인증번호받기</button> <button type="button" disabled={loading} className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} data-bs-toggle="collapse" data-bs-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample" onClick={handleOnClickMbnum}>인증번호받기</button>
</div> </div>
</div> </div>
...@@ -327,7 +297,7 @@ const MyInfo = () => { ...@@ -327,7 +297,7 @@ const MyInfo = () => {
<div className="d-flex justify-content-around mt-3"> <div className="d-flex justify-content-around mt-3">
<label className={`${styles.confirm}`}>인증하기</label> <label className={`${styles.confirm}`}>인증하기</label>
<div> <div>
<input className={`${styles.input}`} type="number" placeholder="인증번호를 입력" onChange={handleOnChangeMb} required/> <input className={`${styles.input}`} type="number" placeholder="인증번호를 입력" onChange={handleOnChangeMb} />
<button type="button" className={`rounded-2 py-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} onClick={handleOnClickMbConfirm}>확인</button> <button type="button" className={`rounded-2 py-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} onClick={handleOnClickMbConfirm}>확인</button>
<button type="button" className={`rounded-2 py-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} onClick={handleOnClickMbnum}>재전송</button> <button type="button" className={`rounded-2 py-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} onClick={handleOnClickMbnum}>재전송</button>
</div> </div>
...@@ -338,12 +308,10 @@ const MyInfo = () => { ...@@ -338,12 +308,10 @@ const MyInfo = () => {
{(mbError === "실패") && <p className={styles.passwordConfirmError}>인증번호를 다시 입력해주세요.</p>} {(mbError === "실패") && <p className={styles.passwordConfirmError}>인증번호를 다시 입력해주세요.</p>}
</div> </div>
</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" placeholder="8~11자리 사이" onChange={handleUserOnChange} maxLength="11" required /> <input className={`${styles.input} ${styles.inputSize}`} type="password" name="userPassword" placeholder="8~11자리 사이" onChange={handleUserOnChange} maxLength="11" />
</div> </div>
{errorMsg.errorPassword && <p className={styles.passwordConfirmError}>8~11자리 사이로 입력해주세요.</p>} {errorMsg.errorPassword && <p className={styles.passwordConfirmError}>8~11자리 사이로 입력해주세요.</p>}
...@@ -352,7 +320,7 @@ const MyInfo = () => { ...@@ -352,7 +320,7 @@ const MyInfo = () => {
<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" placeholder="8~11자리 사이" onChange={handleUserOnChange} maxLength="11" required /> <input className={`${styles.input} ${styles.inputSize}`} type="password" name="userRePassword" placeholder="8~11자리 사이" onChange={handleUserOnChange} maxLength="11" />
</div> </div>
{errorMsg.errorRePassword && <p className={styles.passwordConfirmError}>비밀번호가 일치하지 않습니다.</p>} {errorMsg.errorRePassword && <p className={styles.passwordConfirmError}>비밀번호가 일치하지 않습니다.</p>}
......
...@@ -5,9 +5,6 @@ ...@@ -5,9 +5,6 @@
font-size: 3rem; font-size: 3rem;
margin: 2rem 0; margin: 2rem 0;
} }
.img{
width: 40%;
}
.confirm{ .confirm{
color: black; color: black;
...@@ -53,8 +50,10 @@ width: 40%; ...@@ -53,8 +50,10 @@ width: 40%;
} }
.box{ .box{
width:12rem; width:12rem;
margin: 0px auto; margin: 0px 3rem;
position: relative; position: relative;
display: flex;
align-items: center;
} }
.box:hover{ .box:hover{
display: block; display: block;
...@@ -76,7 +75,7 @@ width: 40%; ...@@ -76,7 +75,7 @@ width: 40%;
} }
.profile:hover{ .profile:hover{
opacity: 0.5; opacity: 0.5;
} }
.input { .input {
margin: 0.5rem 0 0 0; margin: 0.5rem 0 0 0;
padding: 0.5rem 0 0.5rem 0; padding: 0.5rem 0 0.5rem 0;
...@@ -104,6 +103,7 @@ width: 40%; ...@@ -104,6 +103,7 @@ width: 40%;
.butterYellowAndBtn{ .butterYellowAndBtn{
color: black; color: black;
font-size: 1rem;
background-color: #FEDC00; background-color: #FEDC00;
border: 1px solid black; border: 1px solid black;
text-align: center; text-align: center;
...@@ -128,5 +128,34 @@ width: 40%; ...@@ -128,5 +128,34 @@ width: 40%;
} }
@media (max-width: 403px) { @media (max-width: 403px) {
.title{
display: flex;
justify-content: center;
color: #FEDC00;
font-size: 2rem;
margin: 2rem 0;
}
.box{
width:8rem;
margin: 0px 1.5rem 0 0.5rem;
position: relative;
}
.profile{
width: 8rem;
height: 8rem;
}
.userName{
color: white;
font-size: 1.1rem;
}
.hoverTxt{
display: none;
position:absolute;
top:5rem;
left:2.5rem;
color : #FEDC00;
font-size: 1.5rem;
}
} }
\ No newline at end of file
...@@ -3,7 +3,6 @@ import { Link } from "react-router-dom"; ...@@ -3,7 +3,6 @@ import { Link } from "react-router-dom";
import { useAuth } from "../../context/auth_context.js" import { useAuth } from "../../context/auth_context.js"
const SubNav = () => { const SubNav = () => {
const { user, setUser, logout } = useAuth(); const { user, setUser, logout } = useAuth();
console.log("user : ", user);
return ( return (
<> {(user.role !== "user") ? <> {(user.role !== "user") ?
......
...@@ -7,16 +7,16 @@ const ReservationDetails = () => { ...@@ -7,16 +7,16 @@ const ReservationDetails = () => {
<div className={`${styles.body}`}> <div className={`${styles.body}`}>
<div className={`d-flex justify-content-around align-items-center py-3`}> <div className={`d-flex justify-content-around align-items-center py-3`}>
<div className={`${styles.span} d-flex justify-content-center`}> <div className={`${styles.span} d-flex justify-content-center`}>
<span>영화 포스터</span> <span className={`${styles.layout}`}>영화 포스터</span>
</div> </div>
<div className={`${styles.span} d-flex flex-column`}> <div className={`${styles.span} d-flex flex-column`}>
<span>영화제목</span> <span className={`${styles.layout}`}>영화제목</span>
<span>예매확인번호</span> <span className={`${styles.layout}`}>예매확인번호</span>
<span>예매날짜</span> <span className={`${styles.layout}`}>예매날짜</span>
<span>상영관</span> <span className={`${styles.layout}`}>상영관</span>
<span>좌석정보</span> <span className={`${styles.layout}`}>좌석정보</span>
<span>결제금액</span> <span className={`${styles.layout}`}>결제금액</span>
<span>결제수단</span> <span className={`${styles.layout}`}>결제수단</span>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
.header{ .header{
display: flex; display: flex;
justify-content: center; justify-content: center;
...@@ -18,7 +19,21 @@ ...@@ -18,7 +19,21 @@
border-bottom: 1px solid #FEDC00; border-bottom: 1px solid #FEDC00;
} }
.span span{ .span .layout{
color:white; color:white;
font-size: 1.5rem; font-size: 1.5rem;
} }
@media (max-width: 403px) {
.header{
display: flex;
justify-content: center;
background-color: #FEDC00;
width: 80%;
text-align: center;
font-size: 1.5rem;
margin: 2rem;
}
}
\ No newline at end of file
...@@ -5,6 +5,7 @@ import { Redirect } from "react-router-dom"; ...@@ -5,6 +5,7 @@ import { Redirect } from "react-router-dom";
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:"", userName:"",
...@@ -23,19 +24,15 @@ const Signup = () => { ...@@ -23,19 +24,15 @@ const Signup = () => {
const [mbError,setMbError] = useState(false); const [mbError,setMbError] = useState(false);
const [error, setError] = useState(""); const [error, setError] = useState("");
const [errorMsg, setErrorMsg] = useState({ const [errorMsg, setErrorMsg] = useState({
errorId: null, errorId: false,
errorName: false, errorName: false,
errorEmail: false, errorEmail: false,
errorNickName: false, errorNickName: false,
errorBirthday: false, errorBirthday: false,
errorMbnum: false, errorMbnum: false,
errorPassword: false, errorPassword: false,
errorRePassword: false
}) })
// id중복확인 여부 state와 가입하기 누르면 id 임시 저장
const [overlapId, setOverlapId] = useState(false);
const [confirmMb, setConfirmMb] = useState(false); const [confirmMb, setConfirmMb] = useState(false);
const [preId, setPreId] = useState("");
//입력할때마다 state에 저장 //입력할때마다 state에 저장
const handleUserOnChange = (e) => { const handleUserOnChange = (e) => {
...@@ -50,42 +47,7 @@ const Signup = () => { ...@@ -50,42 +47,7 @@ const Signup = () => {
}) })
} }
} }
//인증번호 보내기
//id(중복확인 체크, 형식 에러)
const handleOnClickId = async (e) => {
e.preventDefault();
try {
setError("");
if (user.userId.length < 5) {
setErrorMsg(errorMsg => ({
...errorMsg,
[e.target.name]: true
}));
if (overlapId === true) {
setOverlapId(() => (false));
};
} else {
const userId = user.userId;
await authApi.compareId(userId);
if (!await authApi.compareId(userId)) {
alert("이 아이디는 사용가능합니다.")
setErrorMsg(errorMsg => ({
...errorMsg,
[e.target.name]: false
}));
setOverlapId(() => (true));
} else {
alert("이미 사용중인 아이디입니다.")
setOverlapId(() => (false));
}
}
} catch (error) {
catchErrors(error, setError)
} finally {
setLoading(false);
}
}
const handleOnClickMbnum = async (e) => { const handleOnClickMbnum = async (e) => {
e.preventDefault(); e.preventDefault();
try { try {
...@@ -93,14 +55,10 @@ const Signup = () => { ...@@ -93,14 +55,10 @@ const Signup = () => {
setError(""); setError("");
setLoading(true) setLoading(true)
const phone = user.userMbnum; const phone = user.userMbnum;
console.log("phone : ", phone);
const message = await authApi.confirmMbnum(phone); const message = await authApi.confirmMbnum(phone);
console.log("message : ", message);
if(message.isSuccess){ if(message.isSuccess){
console.log("mberror: "+mbError);
setMbError("보냄"); setMbError("보냄");
setStartTime(message.startTime); setStartTime(message.startTime);
} }
} catch (error) { } catch (error) {
console.log('error'+ error) console.log('error'+ error)
...@@ -108,21 +66,18 @@ const Signup = () => { ...@@ -108,21 +66,18 @@ const Signup = () => {
setLoading(false); setLoading(false);
} }
} }
//인증번호 입력
const handleOnChangeMb = (e) => { const handleOnChangeMb = (e) => {
setNumber(String(e.target.value)); setNumber(String(e.target.value));
} }
//인증번호 검증
const handleOnClickMbConfirm = async (e) => { const handleOnClickMbConfirm = async (e) => {
e.preventDefault(); e.preventDefault();
try { try {
setError(""); setError("");
setLoading(true); setLoading(true);
console.log("startTime : ", startTime);
const confirmNum = {userMbnum : user.userMbnum, number : number, startTime : startTime}; const confirmNum = {userMbnum : user.userMbnum, number : number, startTime : startTime};
console.log(confirmNum);
const message = await authApi.confirmNum(confirmNum); const message = await authApi.confirmNum(confirmNum);
console.log(message);
setMbError(message); setMbError(message);
if(message === "성공"){ if(message === "성공"){
setConfirmMb(true); setConfirmMb(true);
...@@ -134,23 +89,37 @@ const Signup = () => { ...@@ -134,23 +89,37 @@ const Signup = () => {
setLoading(false); setLoading(false);
} }
} }
//비밀번호일치 여부만 클라이언트에서 확인
const validationPw = () => {
if(user.userPassword !== user.userRePassword){
return false;
}else{return true;}
}
//서버로 전송
const handleOnSummit = async (e) => { const handleOnSummit = async (e) => {
e.preventDefault(); e.preventDefault();
try { try {
setError(() => ("")); setError("");
//처리가 될때까지 버튼(가입하기)이 안눌리게 지정 //처리가 될때까지 버튼(가입하기)이 안눌리게 지정
setLoading(() => (true)); setLoading(true);
//유효성 검사 let validPw = validationPw();
validation(); if(confirmMb){
if(validPw){
const userData = user; const userData = user;
//서버로 전송 //서버로 전송
await authApi.signup(userData) const error = await authApi.signup(userData);
alert("가입이 완료되었습니다. 로그인 해주세요."); if(error === "성공"){
setSuccess(true); setSuccess(true);
}else{
setErrorMsg(error);
alert("형식에 맞게 다시 작성해주세요");
}
}else{
throw new Error("비밀번호가 일치하지 않습니다.");
}
}else{
throw new Error("핸드폰 번호를 인증해주세요.");
}
} catch (error) { } catch (error) {
//에러전송 //에러전송
catchErrors(error, setError); catchErrors(error, setError);
...@@ -159,69 +128,10 @@ const Signup = () => { ...@@ -159,69 +128,10 @@ const Signup = () => {
} }
} }
//비교하여 error메세지 반환 if(success){
const vaildationData = (text, compareValue, error) => {
if (text !== compareValue) {
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: true }));
} else {
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 = () => {
setPreId(user.userId);
//아이디 유효성 검사
vaildationIdPw(user.userId.length, 5, "errorId");
//이름 유효성 검사
vaildationData((user.userName.length === 0), false, "errorName");
//별명 유효성 검사
vaildationData((user.userNickName.length === 0), false, "errorNickName");
// 생일 유효성 검사
vaildationData(user.userBirthday.length, 6, "errorBirthday");
// 휴대폰 유효성 검사
vaildationData(user.userMbnum.length, 11, "errorMbnum");
// 비밀번호 유효성 검사
vaildationIdPw(user.userPassword.length, 8, "errorPassword");
// 비밀번호 확인 유효성 검사
vaildationData(user.userRePassword, user.userPassword, "errorRePassword");
let validation = false;
validation = (Object.values(errorMsg).some((element) => (element)) === false);
// 최종 유효성 검사
if (overlapId) {
if(confirmMb){
if(!validation){
throw new Error("유효하지 않은 데이터입니다.");
}else{
console.log("가입성공");
return true
}
}else{
throw new Error("휴대폰 인증도 해주세요");
}
}else{
setErrorMsg(errorMsg => ({ ...errorMsg, errorId: false }));
throw new Error("먼저 아이디 중복확인을 해주세요");
}
}
if (success) {
return <Redirect to="/login" />; return <Redirect to="/login" />;
} }
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}>
...@@ -230,86 +140,78 @@ const Signup = () => { ...@@ -230,86 +140,78 @@ 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>
<div className="d-flex col-md-auto"> <input className={`${styles.input} ${styles.inputSize}`} type="text" name="userId" placeholder="5~10자리 사이" onChange={handleUserOnChange} maxLength="10"/>
<input className={styles.input} type="text" name="userId" placeholder="5~10자리 사이" onChange={handleUserOnChange} maxLength="10" required />
<button type="button" disabled={loading} name="errorId" className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} onClick={handleOnClickId}>중복확인</button>
</div>
</div> </div>
{(overlapId === false) && errorMsg.errorId && <p className={styles.passwordConfirmError}>5~10자리 사이로 입력해주세요.</p>} {errorMsg.errorId && <p className={styles.errorMsg}>5~10자리 사이로 입력해주세요.</p>}
{overlapId && (errorMsg.errorId === 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" placeholder="이름을 입력해주세요" onChange={handleUserOnChange} maxlength="10" required /> <input className={`${styles.input} ${styles.inputSize}`} type="text" name="userName" placeholder="이름을 입력해주세요" onChange={handleUserOnChange} maxLength="20" />
</div> </div>
{errorMsg.errorName && <p className={styles.passwordConfirmError}>이름을 입력해주세요</p>} {errorMsg.errorName && <p className={styles.errorMsg}>이름을 입력해주세요</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="email" name="userEmail" placeholder="이메일을 입력해주세요" onChange={handleUserOnChange} maxlength="20" required /> <input className={`${styles.input} ${styles.inputSize}`} type="email" name="userEmail" placeholder="이메일을 입력해주세요" onChange={handleUserOnChange} maxLength="20" />
</div> </div>
{errorMsg.errorEmail && <p className={styles.passwordConfirmError}>이메일을 입력해주세요</p>} {errorMsg.errorEmail && <p className={styles.errorMsg}>이메일을 입력해주세요</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="userNickName" placeholder="10자리 이내" onChange={handleUserOnChange} maxLength="10" required /> <input className={`${styles.input} ${styles.inputSize}`} type="text" name="userNickName" placeholder="10자리 이내" onChange={handleUserOnChange} maxLength="20" />
</div> </div>
{errorMsg.errorNickName && <p className={styles.passwordConfirmError}>10 이내로 입력해주세요.</p>} {errorMsg.errorNickName && <p className={styles.errorMsg}>10 이내로 입력해주세요.</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} ${styles.input.placeholder}`} type="number" name="userBirthday" placeholder="6자리(예시: 991225)" onChange={handleUserOnChange} min="0" max="999999" required /> <input className={`${styles.input} ${styles.inputSize} ${styles.input.placeholder}`} type="number" name="userBirthday" placeholder="6자리(예시: 991225)" onChange={handleUserOnChange} min="0" max="999999" />
</div> </div>
{errorMsg.errorBirthday && <p className={styles.passwordConfirmError}>숫자 6자리를 입력해주세요.</p>} {errorMsg.errorBirthday && <p className={styles.errorMsg}>숫자 6자리를 입력해주세요.</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>
<div className="d-flex col-md-auto"> <div className="d-flex col-md-auto">
<input className={`${styles.input} ${styles.input2}`} type="number" name="userMbnum" placeholder="-없이 11자리 입력" onChange={handleUserOnChange} min="" max="99999999999" required /> <input className={`${styles.input} ${styles.input2}`} type="number" name="userMbnum" placeholder="-없이 11자리 입력" onChange={handleUserOnChange} min="0" max="99999999999" />
<button type="button" disabled={loading} className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} data-bs-toggle="collapse" data-bs-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample" onClick={handleOnClickMbnum}>인증번호받기</button> <button type="button" disabled={loading} className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} data-bs-toggle="collapse" data-bs-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample" onClick={handleOnClickMbnum}>인증번호받기</button>
</div> </div>
</div> </div>
{errorMsg.errorMbnum && <p className={styles.passwordConfirmError}>-없이 숫자 11자리를 입력해주세요.</p>} {errorMsg.errorMbnum && <p className={styles.errorMsg}>-없이 숫자 11자리를 입력해주세요.</p>}
<div class="collapse" id="collapseExample"> <div className="collapse" id="collapseExample">
{/* <div className="d-flex col-md-auto justify-content-end"> */} {/* <div className="d-flex col-md-auto justify-content-end"> */}
<div className="d-flex justify-content-between mt-3"> <div className="d-flex justify-content-between mt-3">
<label className={`${styles.confirm}`}>인증하기</label> <label className={`${styles.confirm}`}>인증하기</label>
<div> <div>
<input className={`${styles.input} ${styles.input2}`} type="number" placeholder="인증번호를 입력" onChange={handleOnChangeMb} required/> <input className={`${styles.input} ${styles.input2}`} type="number" placeholder="인증번호를 입력" onChange={handleOnChangeMb} />
<button type="button" className={`rounded-2 py-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} onClick={handleOnClickMbConfirm}>확인</button> <button type="button" className={`rounded-2 py-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} onClick={handleOnClickMbConfirm}>확인</button>
<button type="button" className={`rounded-2 py-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} onClick={handleOnClickMbnum}>재전송</button> <button type="button" className={`rounded-2 py-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} onClick={handleOnClickMbnum}>재전송</button>
</div> </div>
</div> </div>
{(mbError === "재전송") && <p className={styles.passwordConfirmError}>유효시간이 만료되었습니다. 재전송해주세요.</p>} {(mbError === "재전송") && <p className={styles.errorMsg}>유효시간이 만료되었습니다. 재전송해주세요.</p>}
{(mbError === "보냄") && <p className={styles.passwordConfirmError}>5분이내에 입력해주세요.</p>} {(mbError === "보냄") && <p className={styles.errorMsg}>5분이내에 입력해주세요.</p>}
{(mbError === "성공") && <p className={styles.passwordConfirmError}>인증되었습니다.</p>} {(mbError === "성공") && <p className={styles.errorMsg}>인증되었습니다.</p>}
{(mbError === "실패") && <p className={styles.passwordConfirmError}>인증번호를 다시 입력해주세요.</p>} {(mbError === "실패") && <p className={styles.errorMsg}>인증번호를 다시 입력해주세요.</p>}
</div> </div>
</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" placeholder="8~11자리 사이" onChange={handleUserOnChange} maxLength="11" required /> <input className={`${styles.input} ${styles.inputSize}`} type="password" name="userPassword" placeholder="8~11자리 사이" onChange={handleUserOnChange} maxLength="20" />
</div> </div>
{errorMsg.errorPassword && <p className={styles.passwordConfirmError}>8~11자리 사이로 입력해주세요.</p>} {errorMsg.errorPassword && <p className={styles.errorMsg}>8~11자리 사이로 입력해주세요.</p>}
</div> </div>
<div className="d-flex flex-column"> <div className={`d-flex ${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" placeholder="8~11자리 사이" onChange={handleUserOnChange} maxLength="11" required /> <input className={`${styles.input} ${styles.inputSize}`} type="password" name="userRePassword" placeholder="8~11자리 사이" onChange={handleUserOnChange} maxLength="20" />
</div>
{errorMsg.errorRePassword && <p className={styles.passwordConfirmError}>비밀번호가 일치하지 않습니다.</p>}
</div> </div>
<button className={`rounded my-3 py-2 fs-5 ${styles.butterYellowAndBtn} ${styles.btnHover}`} type="submit" disabled={loading}>가입하기</button> <button className={`rounded my-3 py-2 fs-5 ${styles.butterYellowAndBtn} ${styles.btnHover}`} type="submit" disabled={loading}>가입하기</button>
......
...@@ -73,7 +73,7 @@ border: 1px solid white ; ...@@ -73,7 +73,7 @@ border: 1px solid white ;
text-align: center; text-align: center;
} }
.passwordConfirmError{ .errorMsg{
margin-bottom: 0; margin-bottom: 0;
margin-top: 0.5rem; margin-top: 0.5rem;
text-align: end; text-align: end;
......
...@@ -33,7 +33,6 @@ const AuthProvider = ({ children }) => { ...@@ -33,7 +33,6 @@ const AuthProvider = ({ children }) => {
setError(""); setError("");
setLoading(true); setLoading(true);
const user = await authApi.login(id, password); const user = await authApi.login(id, password);
console.log("user : ", user);
setUser(user); setUser(user);
return true; return true;
} catch (error) { } catch (error) {
......
...@@ -1544,6 +1544,11 @@ ...@@ -1544,6 +1544,11 @@
"requires": { "requires": {
"lru-cache": "^6.0.0" "lru-cache": "^6.0.0"
} }
},
"validator": {
"version": "10.11.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz",
"integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw=="
} }
} }
}, },
...@@ -1829,9 +1834,9 @@ ...@@ -1829,9 +1834,9 @@
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
}, },
"validator": { "validator": {
"version": "10.11.0", "version": "13.6.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", "resolved": "https://registry.npmjs.org/validator/-/validator-13.6.0.tgz",
"integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==" "integrity": "sha512-gVgKbdbHgtxpRyR8K0O6oFZPhhB5tT1jeEHZR0Znr9Svg03U0+r9DXWMrnRAB+HtCStDQKlaIZm42tVsVjqtjg=="
}, },
"vary": { "vary": {
"version": "1.1.2", "version": "1.1.2",
......
...@@ -29,7 +29,8 @@ ...@@ -29,7 +29,8 @@
"nodemailer": "^6.6.3", "nodemailer": "^6.6.3",
"pg": "^8.6.0", "pg": "^8.6.0",
"pg-hstore": "^2.3.4", "pg-hstore": "^2.3.4",
"sequelize": "^6.6.4" "sequelize": "^6.6.4",
"validator": "^13.6.0"
}, },
"devDependencies": { "devDependencies": {
"nodemon": "^2.0.12" "nodemon": "^2.0.12"
......
...@@ -3,9 +3,9 @@ import config from "../config/app.config.js"; ...@@ -3,9 +3,9 @@ import config from "../config/app.config.js";
import { User, Role, Guest, ConfirmNum } from '../db/index.js'; import { User, Role, Guest, ConfirmNum } from '../db/index.js';
import fs from "fs"; import fs from "fs";
import CryptoJS from "crypto-js"; import CryptoJS from "crypto-js";
import axios from "axios"; import validator from "validator";
// 현재 유저 상태 결정
const getUser = async (req, res) => { const getUser = async (req, res) => {
try { try {
if (req.cookies.butterStudio) { if (req.cookies.butterStudio) {
...@@ -20,7 +20,7 @@ const getUser = async (req, res) => { ...@@ -20,7 +20,7 @@ const getUser = async (req, res) => {
return res.status(500).send("유저를 가져오지 못했습니다."); return res.status(500).send("유저를 가져오지 못했습니다.");
} }
} }
// 로그인
const login = async (req, res) => { const login = async (req, res) => {
try { try {
const { id, password } = req.body; const { id, password } = req.body;
...@@ -41,7 +41,6 @@ const login = async (req, res) => { ...@@ -41,7 +41,6 @@ const login = async (req, res) => {
const token = jwt.sign(signData, config.jwtSecret, { const token = jwt.sign(signData, config.jwtSecret, {
expiresIn: config.jwtExpires, expiresIn: config.jwtExpires,
}); });
console.log(token);
// 4) 토큰을 쿠키에 저장 // 4) 토큰을 쿠키에 저장
res.cookie(config.cookieName, token, { res.cookie(config.cookieName, token, {
maxAge: config.cookieMaxAge, maxAge: config.cookieMaxAge,
...@@ -62,9 +61,8 @@ const login = async (req, res) => { ...@@ -62,9 +61,8 @@ const login = async (req, res) => {
console.error(error); console.error(error);
return res.status(500).send("로그인 에러"); return res.status(500).send("로그인 에러");
} }
} }
// 로그아웃
const logout = async (req, res) => { const logout = async (req, res) => {
try { try {
res.clearCookie(config.cookieName); res.clearCookie(config.cookieName);
...@@ -79,64 +77,47 @@ const logout = async (req, res) => { ...@@ -79,64 +77,47 @@ const logout = async (req, res) => {
} }
} }
const compareId = async (req, res) => {
try {
const id = req.params.userId;
const userid = await User.findOne({ where: { userId: id } });
if (userid !== null) {
return res.json(true);
} else {
return res.json(false);
}
} catch (error) {
console.error(error);
return res.status(500).send("아이디 중복 확인 에러");
}
}
// 휴대폰 인증
const NCP_serviceID = 'ncp:sms:kr:270376424445:butterstudio';
const NCP_accessKey = 'GQmVCT2ZFxnEaJOWbrQs';
const NCP_secretKey = 'XLQQ8sd9WxW40hNi0xNBTOG0T8ksRsr8c8sUIEvy';
const date = Date.now().toString();
const uri = NCP_serviceID;
const secretKey = NCP_secretKey;
const accessKey = NCP_accessKey;
const method = 'POST';
const space = " ";
const newLine = "\n";
const url = `https://sens.apigw.ntruss.com/sms/v2/services/${uri}/messages`;
const url2 = `/sms/v2/services/${uri}/messages`;
//시크릿 키를 암호화하는 작업
const hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, secretKey);
hmac.update(method);
hmac.update(space);
hmac.update(url2);
hmac.update(newLine);
hmac.update(date);
hmac.update(newLine);
hmac.update(accessKey);
const hash = hmac.finalize();
const signature = hash.toString(CryptoJS.enc.Base64);
// 인증번호 발송 // 인증번호 발송
const confirmMbnum = async (req, res) => { const confirmMbnum = async (req, res) => {
try { try {
// 휴대폰 인증
const NCP_serviceID = process.env.NCP_serviceID;
const NCP_accessKey = process.env.NCP_accessKey;
const NCP_secretKey = process.env.NCP_secretKey;
const date = Date.now().toString();
const uri = NCP_serviceID;
const accessKey = NCP_accessKey;
const secretKey = NCP_secretKey;
const method = 'POST';
const space = " ";
const newLine = "\n";
const url = `https://sens.apigw.ntruss.com/sms/v2/services/${uri}/messages`;
const url2 = `/sms/v2/services/${uri}/messages`;
//시크릿 키를 암호화하는 작업
const hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, secretKey);
hmac.update(method);
hmac.update(space);
hmac.update(url2);
hmac.update(newLine);
hmac.update(date);
hmac.update(newLine);
hmac.update(accessKey);
const hash = hmac.finalize();
const signature = hash.toString(CryptoJS.enc.Base64);
const phoneNumber = req.params.phone; const phoneNumber = req.params.phone;
console.log(phoneNumber); console.log(phoneNumber);
//인증번호 생성 //인증번호 생성
const verifyCode = Math.floor(Math.random() * (999999 - 100000)) + 100000; const verifyCode = Math.floor(Math.random() * (999999 - 100000)) + 100000;
console.log("verifyCode : ",verifyCode); console.log("verifyCode : ", verifyCode);
let today = new Date(); let today = new Date();
let time = String(today.getTime()); let time = String(today.getTime());
console.log("time : ", time);
// let result = await axios({ // let result = await axios({
// method: method, // method: method,
// json: true, // json: true,
...@@ -165,9 +146,8 @@ const confirmMbnum = async (req, res) => { ...@@ -165,9 +146,8 @@ const confirmMbnum = async (req, res) => {
// console.log('resultMs', resultMs); // console.log('resultMs', resultMs);
// console.log('response', res.data, res['data']); // console.log('response', res.data, res['data']);
const confirm = await ConfirmNum.findOne({ where: { phone: phoneNumber} }); const confirm = await ConfirmNum.findOne({ where: { phone: phoneNumber } });
console.log(confirm); if (confirm) {
if(confirm){
await confirm.destroy(); await confirm.destroy();
// 5분 유효시간 설정 // 5분 유효시간 설정
await ConfirmNum.create({ await ConfirmNum.create({
...@@ -175,7 +155,7 @@ const confirmMbnum = async (req, res) => { ...@@ -175,7 +155,7 @@ const confirmMbnum = async (req, res) => {
phone: phoneNumber, phone: phoneNumber,
startTime: time, startTime: time,
}); });
}else{ } else {
await ConfirmNum.create({ await ConfirmNum.create({
confirmNum: String(verifyCode), confirmNum: String(verifyCode),
phone: phoneNumber, phone: phoneNumber,
...@@ -196,25 +176,21 @@ const confirmMbnum = async (req, res) => { ...@@ -196,25 +176,21 @@ const confirmMbnum = async (req, res) => {
// 인증번호 확인 // 인증번호 확인
const confirmNum = async (req, res) => { const confirmNum = async (req, res) => {
try { try {
const {userMbnum, number, startTime} = req.body; const { userMbnum, number, startTime } = req.body;
console.log(userMbnum, number, startTime); const confirm = await ConfirmNum.findOne({ where: { phone: userMbnum, startTime: startTime } });
const confirm = await ConfirmNum.findOne({ where: { phone: userMbnum, startTime: startTime} });
console.log(confirm);
let today = new Date(); let today = new Date();
let time = today.getTime(); let time = today.getTime();
console.log("time2 :", time);
const elapsedMSec = time - confirm.startTime; const elapsedMSec = time - confirm.startTime;
const elapsedMin = String(elapsedMSec / 1000 / 60); const elapsedMin = String(elapsedMSec / 1000 / 60);
console.log("elapsedMin : ", elapsedMin); if (elapsedMin <= 5) {
if(elapsedMin <= 5 ){
if (number !== confirm.confirmNum) { if (number !== confirm.confirmNum) {
res.send("실패"); res.send("실패");
}else { } else {
await confirm.destroy(); await confirm.destroy();
res.send("성공"); res.send("성공");
} }
}else{ } else {
res.send("재전송") res.send("재전송")
} }
} catch (error) { } catch (error) {
...@@ -223,21 +199,62 @@ const confirmNum = async (req, res) => { ...@@ -223,21 +199,62 @@ const confirmNum = async (req, res) => {
} }
}; };
//유효성 검사
const validation = (errorMsg, data, minLength, maxLength, dataType) => {
if (validator.isLength(data, minLength, maxLength)) {
errorMsg[dataType] = false;
} else {
errorMsg[dataType] = true;
}
if (dataType === "userEmail") {
if (validator.isEmail(data, minLength, maxLength)) {
errorMsg[dataType] = false;
} else {
errorMsg[dataType] = true;
}
}
};
// 회원정보
const signup = async (req, res) => { const signup = async (req, res) => {
const { userId, userName, userEmail, userNickName, userBirthday, userMbnum, userPassword } = req.body; const { userId, userName, userEmail, userNickName, userBirthday, userMbnum, userPassword } = req.body;
try { try {
const mbnum = await User.findOne({ where: { phoneNumber: userMbnum }}); let errorMsg = {
const email = await User.findOne({ where: { email: userEmail } }); errorId: false,
errorName: false,
errorEmail: false,
errorBirthday: false,
errorNickName: false,
errorMbnum: false,
errorPassword: false,
};
if (mbnum && email) { //유효성 검사
return res.status(422).send(`이미 있는 이메일, 휴대폰번호입니다.`); validation(errorMsg, userId, 5, 10, "errorId");
} else if (!mbnum && email) { validation(errorMsg, userName, 1, 10, "errorName");
return res.status(422).send(`이미 있는 이메일입니다.`); validation(errorMsg, userEmail, 3, 20, "errorEmail");
} else if (mbnum && !email) { validation(errorMsg, userBirthday, 6, 6, "errorBirthday");
return res.status(422).send(`이미 있는 휴대폰번호입니다.`); validation(errorMsg, userNickName, 1, 10, "errorNickName");
validation(errorMsg, userMbnum, 11, 11, "errorMbnum");
validation(errorMsg, userPassword, 8, 11, "errorPassword");
let valid = !(Object.values(errorMsg).some((element) => (element)));
// db에서 데이터 중복검사
const id = await User.findOne({ where: { userId: userId } });
const mbnum = await User.findOne({ where: { phoneNumber: userMbnum } });
const email = await User.findOne({ where: { email: userEmail } });
if (!valid) {
res.json(errorMsg);
} else { } else {
if (id) {
return res.status(401).send(`이미 있는 아이디입니다.`);
} else if (email) {
return res.status(401).send(`이미 있는 이메일입니다.`);
} else if (mbnum) {
return res.status(401).send(`이미 있는 휴대폰번호입니다.`);
} else{
const role = await Role.findOne({ where: { name: "member" } }) const role = await Role.findOne({ where: { name: "member" } })
const newUser = await User.create({ await User.create({
userId: userId, userId: userId,
name: userName, name: userName,
email: userEmail, email: userEmail,
...@@ -248,7 +265,8 @@ const signup = async (req, res) => { ...@@ -248,7 +265,8 @@ const signup = async (req, res) => {
img: "", img: "",
roleId: role.id roleId: role.id
}); });
res.json(newUser); res.json("성공");
}
} }
} catch (error) { } catch (error) {
console.error(error.message); console.error(error.message);
...@@ -264,18 +282,17 @@ const getMember = async (req, res) => { ...@@ -264,18 +282,17 @@ const getMember = async (req, res) => {
const user = await User.findOne({ where: { id: decoded.id } }); const user = await User.findOne({ where: { id: decoded.id } });
res.json({ nickname: user.nickname, img: user.img }); res.json({ nickname: user.nickname, img: user.img });
} else { } else {
res.status(401).send("잘못된 접근입니다."); res.status(500).send("잘못된 접근입니다.");
} }
} catch (error) { } catch (error) {
console.error("error : ", error.message); console.error("error : ", error.message);
res.status(500).send("잘못된 접근입니다."); res.status(500).send("잘못된 접근입니다.");
} }
} }
// 프로필 변경
const uploadProfile = async (req, res) => { const uploadProfile = async (req, res) => {
try { try {
const image = req.file.filename; const image = req.file.filename;
console.log(req.file);
const token = req.cookies.butterStudio; const token = req.cookies.butterStudio;
const decoded = jwt.verify(token, config.jwtSecret); const decoded = jwt.verify(token, config.jwtSecret);
...@@ -298,7 +315,7 @@ const uploadProfile = async (req, res) => { ...@@ -298,7 +315,7 @@ const uploadProfile = async (req, res) => {
res.status(500).send("프로필 에러"); res.status(500).send("프로필 에러");
} }
} }
// 기본 비밀번호인지 확인
const comparePw = async (req, res) => { const comparePw = async (req, res) => {
try { try {
//쿠키 안 토큰에서 id추출 //쿠키 안 토큰에서 id추출
...@@ -308,7 +325,6 @@ const comparePw = async (req, res) => { ...@@ -308,7 +325,6 @@ const comparePw = async (req, res) => {
const user = await User.scope("withPassword").findOne({ where: { id: decoded.id } }); const user = await User.scope("withPassword").findOne({ where: { id: decoded.id } });
//입력한 비번과 해당 행 비번을 비교 //입력한 비번과 해당 행 비번을 비교
const passwordMatch = await user.comparePassword(req.params.pw); const passwordMatch = await user.comparePassword(req.params.pw);
console.log("passwordMatch : ", passwordMatch);
//클라이언트로 동일여부를 전송 //클라이언트로 동일여부를 전송
if (passwordMatch) { if (passwordMatch) {
return res.json(true) return res.json(true)
...@@ -320,16 +336,16 @@ const comparePw = async (req, res) => { ...@@ -320,16 +336,16 @@ const comparePw = async (req, res) => {
res.status(500).send("인증 에러"); res.status(500).send("인증 에러");
} }
} }
// 회원정보 수정할 때 쓰는 함수
const overlap = async (decoded, dataType, data) => { const overlap = async (decoded, dataType, data) => {
try { try {
let overlap = await User.findOne({ where: { id: decoded.id } }); let overlap = await User.findOne({ where: { id: decoded.id } });
console.log("기존 데이터 : ", overlap, "변경할 데이터 : ", data); // 변경할 데이터가 자기자신이면 true
if (overlap[dataType] === data) { if (overlap[dataType] === data) {
return true return true
} else { } else {
// 그렇지 않으면 다른 데이터들 중에서 중복되는지 검사
let overlap2 = await User.findOne({ attributes: [dataType] }); let overlap2 = await User.findOne({ attributes: [dataType] });
console.log(overlap2)
if (overlap2[dataType] === data) { if (overlap2[dataType] === data) {
return false return false
} else { } else {
...@@ -340,26 +356,43 @@ const overlap = async (decoded, dataType, data) => { ...@@ -340,26 +356,43 @@ const overlap = async (decoded, dataType, data) => {
console.error(error.message); console.error(error.message);
} }
} }
// 회원정보 수정
const modifyUser = async (req, res) => { const modifyUser = async (req, res) => {
try { try {
const token = req.cookies.butterStudio; const token = req.cookies.butterStudio;
const decoded = jwt.verify(token, config.jwtSecret); const decoded = jwt.verify(token, config.jwtSecret);
const { userName, userEmail, userNickName, userMbnum, userPassword } = req.body; const { userName, userEmail, userNickName, userMbnum, userPassword } = req.body;
let errorMsg = {
errorName: false,
errorEmail: false,
errorNickName: false,
errorMbnum: false,
errorPassword: false,
};
//유효성 검사
validation(errorMsg, userName, 1, 10, "errorName");
validation(errorMsg, userEmail, 3, 20, "errorEmail");
validation(errorMsg, userNickName, 1, 10, "errorNickName");
validation(errorMsg, userMbnum, 11, 11, "errorMbnum");
validation(errorMsg, userPassword, 8, 11, "errorPassword");
let valid = !(Object.values(errorMsg).some((element) => (element)));
const overlapEmail = await overlap(decoded, "email", userEmail); const overlapEmail = await overlap(decoded, "email", userEmail);
const overlapMbnum = await overlap(decoded, "phoneNumber", userMbnum); const overlapMbnum = await overlap(decoded, "phoneNumber", userMbnum);
if (!valid) {
res.json(errorMsg);
} else {
if (overlapEmail && overlapMbnum) { if (overlapEmail && overlapMbnum) {
const user = await User.update({ await User.update({
name: userName, name: userName,
email: userEmail, email: userEmail,
nickname: userNickName, nickname: userNickName,
phoneNumber: userMbnum, phoneNumber: userMbnum,
password: userPassword, password: userPassword,
}, { where: { id: decoded.id }, individualHooks: true }); }, { where: { id: decoded.id }, individualHooks: true });
console.log("user22 :", user); res.json("성공");
res.json(user);
} else if (!overlapEmail && overlapMbnum) { } else if (!overlapEmail && overlapMbnum) {
res.status(500).send("이미 있는 이메일입니다."); res.status(500).send("이미 있는 이메일입니다.");
} else if (overlapEmail && !overlapMbnum) { } else if (overlapEmail && !overlapMbnum) {
...@@ -367,6 +400,7 @@ const modifyUser = async (req, res) => { ...@@ -367,6 +400,7 @@ const modifyUser = async (req, res) => {
} else { } else {
res.status(500).send("이미 있는 이메일, 핸드폰번호입니다."); res.status(500).send("이미 있는 이메일, 핸드폰번호입니다.");
} }
}
} catch (error) { } catch (error) {
console.error(error.message); console.error(error.message);
res.status(500).send("수정 에러. 나중에 다시 시도 해주세요"); res.status(500).send("수정 에러. 나중에 다시 시도 해주세요");
...@@ -434,7 +468,6 @@ export default { ...@@ -434,7 +468,6 @@ export default {
getUser, getUser,
login, login,
logout, logout,
compareId,
confirmMbnum, confirmMbnum,
confirmNum, confirmNum,
signup, signup,
......
...@@ -54,7 +54,6 @@ const UserModel = (sequelize) => { ...@@ -54,7 +54,6 @@ const UserModel = (sequelize) => {
); );
User.beforeSave(async (user) => { User.beforeSave(async (user) => {
console.log('update before', user)
if (!user.changed("password")) { if (!user.changed("password")) {
return; return;
} }
......
...@@ -41,7 +41,6 @@ router ...@@ -41,7 +41,6 @@ router
.route("/pw/:pw") .route("/pw/:pw")
.get(userCtrl.comparePw) .get(userCtrl.comparePw)
router router
.route("/phone/:phone") .route("/phone/:phone")
.post(userCtrl.confirmMbnum) .post(userCtrl.confirmMbnum)
......
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