Commit 3639e9fe authored by Jiwon Yoon's avatar Jiwon Yoon
Browse files

Merge branch 'gyumin'

parents c4a8991d bd9ff2cc
......@@ -3073,6 +3073,14 @@
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.2.3.tgz",
"integrity": "sha512-pXnVMfJKSIWU2Ml4JHP7pZEPIrgBO1Fd3WGx+fPBsS+KRGhE4vxooD8XBGWbQOIVSZsVK7pUDBBkCicNu80yzQ=="
},
"axios": {
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
"requires": {
"follow-redirects": "^1.10.0"
}
},
"axobject-query": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
......@@ -3865,6 +3873,11 @@
}
}
},
"buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
},
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
......@@ -4925,6 +4938,11 @@
"whatwg-url": "^8.0.0"
}
},
"dayjs": {
"version": "1.10.6",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.6.tgz",
"integrity": "sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw=="
},
"debug": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
......@@ -5362,6 +5380,14 @@
"safer-buffer": "^2.1.0"
}
},
"ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
"requires": {
"safe-buffer": "^5.0.1"
}
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
......@@ -9942,6 +9968,30 @@
"universalify": "^2.0.0"
}
},
"jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"requires": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
},
"dependencies": {
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
}
}
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
......@@ -9962,6 +10012,25 @@
"object.assign": "^4.1.2"
}
},
"jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"requires": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"requires": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"killable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
......@@ -10093,6 +10162,36 @@
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168="
},
"lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
"integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
},
"lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
},
"lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
"integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M="
},
"lodash.isnumber": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
"integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
},
"lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
},
"lodash.isstring": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
"integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
},
"lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
......@@ -10103,6 +10202,11 @@
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
},
"lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
},
"lodash.template": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
......@@ -11417,6 +11521,11 @@
"ts-pnp": "^1.1.6"
}
},
"pop-iterate": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pop-iterate/-/pop-iterate-1.0.1.tgz",
"integrity": "sha1-zqz9q0q/NT16DyqqLB/Hs/lBO6M="
},
"portfinder": {
"version": "1.0.28",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz",
......@@ -13649,6 +13758,11 @@
}
}
},
"rootpath": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/rootpath/-/rootpath-0.1.2.tgz",
"integrity": "sha1-Wzeah9ypBum5HWkKWZQ5vvJn6ms="
},
"rsvp": {
"version": "4.8.5",
"resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz",
......@@ -13890,6 +14004,11 @@
"ajv-keywords": "^3.5.2"
}
},
"scmp": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/scmp/-/scmp-2.1.0.tgz",
"integrity": "sha512-o/mRQGk9Rcer/jEEw/yw4mwo3EU/NvYvp577/Btqrym9Qy5/MdWGBqipbALgd2lrdWTJ5/gqDusxfnQBxOxT2Q=="
},
"scss-tokenizer": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
......@@ -15306,6 +15425,44 @@
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
"twilio": {
"version": "3.66.0",
"resolved": "https://registry.npmjs.org/twilio/-/twilio-3.66.0.tgz",
"integrity": "sha512-2jek7akXcRMusoR20EWA1+e5TQp9Ahosvo81wTUoeS7H24A1xbVQJV4LfSWQN4DLUY1oZ4d6tH2oCe/+ELcpNA==",
"requires": {
"axios": "^0.21.1",
"dayjs": "^1.8.29",
"https-proxy-agent": "^5.0.0",
"jsonwebtoken": "^8.5.1",
"lodash": "^4.17.21",
"q": "2.0.x",
"qs": "^6.9.4",
"rootpath": "^0.1.2",
"scmp": "^2.1.0",
"url-parse": "^1.5.0",
"xmlbuilder": "^13.0.2"
},
"dependencies": {
"q": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/q/-/q-2.0.3.tgz",
"integrity": "sha1-dbjbAlWhpa+C9Yw/Oqoe/sfQ0TQ=",
"requires": {
"asap": "^2.0.0",
"pop-iterate": "^1.0.1",
"weak-map": "^1.0.5"
}
},
"qs": {
"version": "6.10.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz",
"integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==",
"requires": {
"side-channel": "^1.0.4"
}
}
}
},
"type": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
......@@ -15923,6 +16080,11 @@
"minimalistic-assert": "^1.0.0"
}
},
"weak-map": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/weak-map/-/weak-map-1.0.5.tgz",
"integrity": "sha1-eWkVhNmGB/UHC9O3CkDmuyLkAes="
},
"web-vitals": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-1.1.2.tgz",
......@@ -16947,6 +17109,11 @@
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
"integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw=="
},
"xmlbuilder": {
"version": "13.0.2",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz",
"integrity": "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ=="
},
"xmlchars": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
......
......@@ -15,6 +15,7 @@
"react-dom": "^17.0.2",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"twilio": "^3.66.0",
"web-vitals": "^1.0.1"
},
"scripts": {
......
import React, { useState, useEffect } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import { AuthProvider } from "./context/auth_context";
import Header from "./components/Header";
import SubNav from "./components/Navs/SubNav";
import MainNav from "./components/Navs/MainNav";
......@@ -16,16 +16,12 @@ import TicketingSeatPage from './pages/TicketingSeatPage'
import SearchPage from "./pages/SearchPage";
import Payment from "./pages/PaymentPage";
const AppContext = React.createContext();
function App() {
const [role, setRole] = useState("user");
const store = {role, setRole};
return (
<div style={{ backgroundColor: "black" }}>
<AppContext.Provider value={store}>
<Router style={{ backgroundColor: "black"}}>
<div className="" style={{ backgroundColor: "black" }}>
<AuthProvider>
<Router style={{ backgroundColor: "black" }}>
<SubNav />
<Header />
<MainNav />
......@@ -35,6 +31,7 @@ function App() {
<Route path="/signup" component={SignupPage} />
<Route path="/movielist" component={MovieListPage} />
<Route path="/movie/:movieId" component={MoviePage} />
<Route path="/mypage" component={MyPage} />
<Route path="/ticket/seat" component={TicketingSeatPage} />
<Route path="/ticket" component={TicketingPage} />
<Route path="/payment" component={Payment} />
......@@ -42,10 +39,9 @@ function App() {
<Route path="/admin" component={AdminPage} />
</Switch>
</Router>
</AppContext.Provider>
</AuthProvider>
</div>
);
}
export { AppContext }
export default App;
......@@ -25,10 +25,25 @@ const compareId = async (userId) => {
return data
}
const confirmMbnum = async (id,token) => {
const url = `${baseUrl}/api/auth/${id}/${token}`
const { data } = await axios.get(url)
return data
}
const getNickName = async(id) =>{
const url = `${baseUrl}/api/auth/${id}`
console.log("url : ", url);
const { nickName } = await axios.get(url)
return nickName
}
const authApi = {
login,
logout,
signup,
compareId,
confirmMbnum,
getNickName,
};
export default authApi
\ No newline at end of file
import React, { useState } from "react";
import { useState } from "react";
import styles from "./login.module.scss";
import authApi from "../../apis/auth.api.js";
import { Redirect } from "react-router";
import { Redirect } from "react-router-dom";
import catchErrors from "../../utils/catchErrors";
import {AppContext} from "../../App";
import {useAuth} from "../../context/auth_context.js";
const Login = () => {
const store = React.useContext(AppContext);
const {login, loading} = useAuth();
//useState를 이용해서 각 state 생성 및 초기값 저장
const [state, setState] = useState(true); // 이 줄은 css에 해당하는 state
//state변수 지정 하지만 이 변수는 react에 의해 없어지지 않음, 그리고 그 다음 변수는 state변수를 갱신해주는 함수
const [login, setLogin] = useState({
id:'',
password:''
const [user, setUser] = useState({
id: '',
password: ''
});
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const [success, setSuccess] = useState(false);
const [guest, setGuset] = useState({
guestName:'',
gusetBirthday:'',
gusetMbnum:'',
guestPassword:''
guestName: '',
gusetBirthday: '',
gusetMbnum: '',
guestPassword: ''
})
//input태그에 걸려있는 onchange에서 실행할 함수설정
const handleLoginOnChange = (e) =>{
const handleLoginOnChange = (e) => {
// ... 전개 연산자
// 현재 state에 방금 변화한 값을 다시 저장함
setLogin({ ...login,
[e.target.name]:e.target.value
setUser({
...user,
[e.target.name]: e.target.value
})
};
const handleGuestOnChange = (e) =>{
setGuset({ ...guest,
[e.target.name]:e.target.value
const handleGuestOnChange = (e) => {
setGuset({
...guest,
[e.target.name]: e.target.value
})
}
const requestServer = async (data) => {
await authApi.login(data);
if(data === user){
await login(data);
}else{
}
}
const handleOnSummit = async(e) => {
const handleOnSummit = async (e) => {
e.preventDefault();
try{
try {
setError("");
setLoading(true);
if(e.target.value === "Login"){ requestServer(login); }
else{ requestServer(guest); }
alert('로그인이 완료되었습니다.')
setSuccess(true);
}catch(error){
console.log(e.target.name);
if (e.target.name === "login") {
requestServer(user);
alert('로그인이 완료되었습니다.')
setSuccess(true);
}
else {
requestServer(guest);
alert('로그인이 완료되었습니다.')
}
} catch (error) {
catchErrors(error, setError);
}finally{
setLoading(false);
}
}
if (success) {
store.setRole("member");
return <Redirect to="/" />;
}
return (
<div className={`d-flex flex-column col-md-5 col-10`}>
{/* nav-tabs */}
{/* {console.log(login)} */}
<span className={styles.title}>로그인</span>
<ul className="nav nav-fill nav-tabs w-100" id="loginTab" role="tablist">
<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"}}
id="login-tab" data-bs-toggle="tab" data-bs-target="#login" type="button" role="tab" aria-controls="login" aria-selected="true"
onClick={() => setState(true)}>로그인</button>
<button className={`nav-link active px-2 ${styles.fontSize}`} style={{ color: state ? "black" : "#FEDC00", backgroundColor: state ? "#FEDC00" : "black" }}
id="login-tab" data-bs-toggle="tab" data-bs-target="#login" type="button" role="tab" aria-controls="login" aria-selected="true"
onClick={() => setState(true)}>로그인</button>
</li>
<li className="nav-item" role="presentation">
<button className={`nav-link px-2 ${styles.fontSize}`}
id="guest-tab" data-bs-toggle="tab" data-bs-target="#guest" type="button" role="tab" aria-controls="guest" aria-selected="false"
onClick={() => setState(false)} style={{ color: state ? "#FEDC00" : "black", backgroundColor: state ? "black" : "#FEDC00" }}>비회원 예매 확인</button>
id="guest-tab" data-bs-toggle="tab" data-bs-target="#guest" type="button" role="tab" aria-controls="guest" aria-selected="false"
onClick={() => setState(false)} style={{ color: state ? "#FEDC00" : "black", backgroundColor: state ? "black" : "#FEDC00" }}>비회원 예매 확인</button>
</li>
</ul>
<div className="tab-content w-100" id="myTabContent">
{/* 로그인 */}
<div className="tab-pane fade show active" id="login" role="tabpanel" aria-labelledby="login-tab">
<form className="d-flex flex-column" onSubmit={handleOnSummit}>
<input className={styles.input} type="text" name="id" placeholder="ID" onChange={handleLoginOnChange} maxLength="10" required/>
<form className="d-flex flex-column" name="login" onSubmit={handleOnSummit}>
<input className={styles.input} type="text" name="id" placeholder="ID" onChange={handleLoginOnChange} maxLength="10" required />
<input className={styles.input} type="password" name="password" placeholder="Password" onChange={handleLoginOnChange} maxLength="11" required />
<input className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} type="submit" value="Login" disabled={loading} />
<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>
</form>
</div>
......@@ -95,6 +99,7 @@ const Login = () => {
<div className="tab-pane fade" id="guest" role="tabpanel" aria-labelledby="guest-tab">
<form className="d-flex flex-column" onSubmit={handleOnSummit}>
<input className={styles.input} type="text" name="guestName" id="guestName" placeholder="이름" onChange={handleGuestOnChange} maxLength="5" required />
<input className={styles.input} type="email" name="guestEmail" id="guestEmail" placeholder="이메일" onChange={handleGuestOnChange} maxLength="16" 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} maxLength="11" required />
<input className={styles.input} type="password" name="guestPassword" id="password" placeholder="비밀번호" onChange={handleGuestOnChange} maxLength="11" required />
......@@ -102,7 +107,7 @@ const Login = () => {
<p className={`text-white ${styles.fontSizeTwo}`}>
비회원 정보 입력 예매 내역 확인/취소 티켓 발권이 어려울 있으니 다시 한번 확인해 주시기 바랍니다.
</p>
<input className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} type="submit" value="비회원 예매 확인" disabled={loading}/>
<input className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} type="submit" value="비회원 예매 확인" disabled={loading} />
</form>
</div>
</div>
......
.title{
display: flex;
justify-content: center;
color: #FEDC00;
font-size: 1.7rem;
margin: 2rem 0;
}
.intoSignupPage{
font-size: 13px;
text-decoration: none;
......
import styles from "./my-info.module.scss";
import { useAuth } from "../../context/auth_context";
import { useState, useEffect } from "react";
import authApi from "../../apis/auth.api";
const MyInfo = () => {
const { user } = useAuth();
const [userNickName, setUserNickName] = useState("");
const getNickName = async (id) => {
console.log(id);
const nickname = await authApi.getNickName(id);
console.log(nickname);
return nickname
}
useEffect(() => {
let name = getNickName(user.id);
setUserNickName(name);
}, [])
return (
<div className="d-flex flex-column">
<span className={styles.title}>마이페이지</span>
<div className="d-flex flex mh-100">
<img src="/images/cat.jpg" className="img-thumbnail rounded-circle" />
<div>
<span>{`${userNickName}`} 반갑습니다!</span>
<button>수정</button>
</div>
</div>
</div>
)
}
export default MyInfo
\ No newline at end of file
export { default } from "./MyInfo"
\ No newline at end of file
.title{
display: flex;
justify-content: center;
color: #FEDC00;
font-size: 25px;
margin: 1rem 0;
}
\ No newline at end of file
import {useEffect, useContext} from "react";
import { AppContext } from "../../App";
import authApi from '../../apis/auth.api'
import { Link } from "react-router-dom";
import { useAuth } from "../../context/auth_context.js"
const SubNav = () => {
const store = useContext(AppContext);
useEffect(() => {
window.localStorage.setItem("user", JSON.stringify(store.role));
}, [store]);
const { user, logout } = useAuth();
const handleOnClick = async() => {
store.setRole("user");
await authApi.logout();
}
if (store.role === "user") {
return (
<nav class="nav justify-content-end py-1">
<a class="nav-link text-white" href="/login">로그인</a>
<a class="nav-link text-white" href="/signup">회원가입</a>
</nav>
)
} else if (store.role === "member") {
return (
<nav class="nav justify-content-end py-1">
<a class="nav-link text-white" href="/">마이페이지</a>
<a class="nav-link text-white" onClick={handleOnClick}>로그아웃</a>
</nav>
)
} else if (store.role === "admin") {
<nav class="nav justify-content-end py-1">
<a class="nav-link text-white" href="/admin">관리자페이지</a>
<a class="nav-link text-white" href="/">로그아웃</a>
</nav>
} else {
<nav class="nav justify-content-end py-1">
<a class="nav-link text-white" href="/">로그인 오류</a>
</nav>
}
return (
<nav className="nav justify-content-end py-1">
<a className="nav-link text-white" href="/login">로그인</a>
<a className="nav-link text-white" href="/signup">회원가입</a>
</nav>
<> {(user) ?
<nav className="nav justify-content-end py-1">
{(user.role === "member")
? <><Link className="nav-link text-white" to="/mypage">마이페이지</Link>
</>
: <Link className="nav-link text-white" to="/admin">관리자페이지</Link>}
<Link className="nav-link text-white" to="/" onClick={logout}>로그아웃 </Link>
{/* <a className="nav-link text-white" href="/mypage" onClick={logout}>로그아웃</a> */}
</nav> :
<nav className="nav justify-content-end py-1">
<Link className="nav-link text-white" to="/login">로그인</Link>
<Link className="nav-link text-white" to="/signup" >회원가입</Link>
</nav>
}
</>
)
}
export default SubNav
\ No newline at end of file
import styles from "./signup.module.scss";
import { useState } from 'react';
import { useState } from "react";
import authApi from "../../apis/auth.api.js";
import { Redirect } from "react-router";
import catchErrors from "../../utils/catchErrors.js";
import Twilio from "twilio";
const Signup = () => {
const [user, setUser] = useState({
userId: "",
userEmail: "",
userNickName: "",
userBirthday: "",
userMbnum: "",
......@@ -17,9 +19,10 @@ const Signup = () => {
const [loading, setLoading] = useState(false);
const [success, setSuccess] = useState(false);
//각 타입별 error 유무 state
const [error,setError] = useState("");
const [error, setError] = useState("");
const [errorMsg, setErrorMsg] = useState({
errorId: null,
errorEmail: false,
errorNickName: false,
errorBirthday: false,
errorMbnum: false,
......@@ -36,7 +39,7 @@ const Signup = () => {
...user,
[e.target.name]: e.target.value
})
if(e.target.name === "userBirthday" || e.target.name === "userMbum"){
if (e.target.name === "userBirthday" || e.target.name === "userMbum") {
setUser({
...user,
[e.target.name]: String(e.target.value)
......@@ -47,7 +50,7 @@ const Signup = () => {
//id(중복확인 체크, 형식 에러)
const handleOnClickId = async (e) => {
e.preventDefault();
try{
try {
setError("");
if (user.userId.length < 5) {
setErrorMsg(errorMsg => ({
......@@ -60,32 +63,41 @@ const Signup = () => {
} else {
const userId = user.userId;
await authApi.compareId(userId);
if(!await authApi.compareId(userId)){
if (!await authApi.compareId(userId)) {
alert("이 아이디는 사용가능합니다.")
setErrorMsg(errorMsg => ({
...errorMsg,
[e.target.name]: false
}));
setOverlapId(()=>(true));
}else{
setOverlapId(() => (true));
} else {
alert("이미 사용중인 아이디입니다.")
setOverlapId(()=>(false));
setOverlapId(() => (false));
}
}
}catch(error){
catchErrors(error,setError)
}finally {
} catch (error) {
catchErrors(error, setError)
} finally {
setLoading(false);
}
}
const handleOnClickMbnum = async (e) => {
try {
const id = "AC01ecdbffb36dc0766cfea487a54a4c6e";
const token = "1d86d5d43760b5dce5582badf7b0a775";
await authApi.confirmMbnum(id,token);
} catch (error) {
console.log('twilio error'+ error)
}
}
const handleOnSummit = async (e) => {
e.preventDefault();
try {
setError(()=>(""));
setError(() => (""));
//처리가 될때까지 버튼(가입하기)이 안눌리게 지정
setLoading(()=>(true));
setLoading(() => (true));
//유효성 검사
validation();
const userData = user;
......@@ -105,28 +117,28 @@ const Signup = () => {
const vaildationData = (text, compareValue, error) => {
if (text !== compareValue) {
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: true }));
} else{
} else {
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: false }));
}
}
//아이디 비번 유효성 검사
const vaildationIdPw = (text, minValue, error) => {
if((text < minValue)){
setErrorMsg(errorMsg => ({...errorMsg, [error]: true}));
} else if(text >= minValue){
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);
if (overlapId === true) {
if (preId !== user.userId) {
setOverlapId(false);
}
}
}
}
}
//유효성 검사
const validation = () => {
setPreId(user.userId);
//아이디 유효성 검사
vaildationIdPw(user.userId.length,5,"errorId");
vaildationIdPw(user.userId.length, 5, "errorId");
//별명 유효성 검사
vaildationData((user.userNickName.length === 0), false, "errorNickName");
// 생일 유효성 검사
......@@ -134,16 +146,16 @@ const Signup = () => {
// 휴대폰 유효성 검사
vaildationData(user.userMbnum.length, 11, "errorMbnum");
// 비밀번호 유효성 검사
vaildationIdPw(user.userPassword.length,8,"errorPassword");
vaildationIdPw(user.userPassword.length, 8, "errorPassword");
// 비밀번호 확인 유효성 검사
vaildationData(user.userRePassword, user.userPassword, "errorRePassword");
// 최종 유효성 검사
if (overlapId && (Object.values(errorMsg).some((element) => (element)) === false)) {
}else if(!overlapId && (Object.values(errorMsg).some((element) => (element)) === false)){
setErrorMsg(errorMsg => ({...errorMsg, errorId: false}));
} else if (!overlapId && (Object.values(errorMsg).some((element) => (element)) === false)) {
setErrorMsg(errorMsg => ({ ...errorMsg, errorId: false }));
throw new Error("먼저 아이디 중복확인을 해주세요");
}else{
} else {
throw new Error("유효하지 않은 데이터입니다.");
}
}
......@@ -151,7 +163,7 @@ const Signup = () => {
if (success) {
return <Redirect to="/login" />;
}
return (
// 데이터 입력과 유효성 검사 후 보이는 경고창
......@@ -162,7 +174,7 @@ const Signup = () => {
<div className={styles.inputContent}>
<label className={styles.signupLabel}>아이디</label>
<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" 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>
......@@ -170,10 +182,17 @@ const Signup = () => {
{overlapId && (errorMsg.errorId === false) && <p className={styles.passwordConfirmError}>아이디 중복이 확인되었습니다.</p>}
{(errorMsg.errorId === false) && (overlapId === false) && <p className={styles.passwordConfirmError}>아이디 중복확인을 해주세요.</p>}
</div>
<div className="d-flex flex-column">
<div className={styles.inputContent}>
<label className={styles.signupLabel}>이메일</label>
<input className={`${styles.input} ${styles.inputSize}`} type="email" name="userEmail" placeholder="이메일을 입력해주세요" onChange={handleUserOnChange} maxlength="20" required />
</div>
{errorMsg.errorEmail && <p className={styles.passwordConfirmError}>이메일을 입력해주세요</p>}
</div>
<div className="d-flex flex-column">
<div className={styles.inputContent}>
<label className={styles.signupLabel}>별명</label>
<input className={`${styles.input} ${styles.inputSize}`} type="text" name="userNickName" id="userNickName" placeholder="10자리 이내" onChange={handleUserOnChange} maxLength="10" required />
<input className={`${styles.input} ${styles.inputSize}`} type="text" name="userNickName" placeholder="10자리 이내" onChange={handleUserOnChange} maxLength="10" required />
</div>
{errorMsg.errorNickName && <p className={styles.passwordConfirmError}>10 이내로 입력해주세요.</p>}
</div>
......@@ -181,7 +200,7 @@ const Signup = () => {
<div className="d-flex flex-column">
<div className={styles.inputContent}>
<label className={styles.signupLabel}>생년월일</label>
<input className={`${styles.input} ${styles.inputSize} ${styles.input.placeholder}`} type="number" name="userBirthday" id="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" required />
</div>
{errorMsg.errorBirthday && <p className={styles.passwordConfirmError}>숫자 6자리를 입력해주세요.</p>}
</div>
......@@ -189,14 +208,17 @@ const Signup = () => {
<div className="d-flex flex-column">
<div className={styles.inputContent}>
<label className={styles.signupLabel}>휴대폰 번호</label>
<input className={`${styles.input} ${styles.inputSize}`} type="number" name="userMbnum" id="userMbnum" placeholder="-없이 11자리 입력" onChange={handleUserOnChange} min="" max="99999999999" required />
<div className="d-flex col-md-auto">
<input className={`${styles.input}`} type="number" name="userMbnum" placeholder="-없이 11자리 입력" onChange={handleUserOnChange} min="" max="99999999999" required />
<button type="button" disabled={loading} name="errorId" className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} onClick={handleOnClickMbnum}>인증번호받기</button>
</div>
</div>
{errorMsg.errorMbnum && <p className={styles.passwordConfirmError}>-없이 숫자 11자리를 입력해주세요.</p>}
</div>
<div className="d-flex flex-column">
<div className={`${styles.inputContent}`}>
<label className={styles.signupLabel}>비밀번호</label>
<input className={`${styles.input} ${styles.inputSize}`} type="password" name="userPassword" id="password" 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" required />
</div>
{errorMsg.errorPassword && <p className={styles.passwordConfirmError}>8~11자리 사이로 입력해주세요.</p>}
</div>
......@@ -204,7 +226,7 @@ const Signup = () => {
<div className="d-flex flex-column">
<div className={styles.inputContent}>
<label className={styles.signupLabel}>비밀번호 확인</label>
<input className={`${styles.input} ${styles.inputSize}`} type="password" name="userRePassword" id="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" required />
</div>
{errorMsg.errorRePassword && <p className={styles.passwordConfirmError}>비밀번호가 일치하지 않습니다.</p>}
</div>
......
......@@ -2,8 +2,8 @@
display: flex;
justify-content: center;
color: #FEDC00;
font-size: 25px;
margin-top: 20px;
font-size: 1.7rem;
margin-top: 2rem;
}
.contents{
......
import axios from "axios";
import { createContext, useCallback, useContext, useState } from "react";
import authApi from "../apis/auth.api";
import { getLocalUser } from "../utils/auth";
import {baseUrl} from "../utils/baseUrl";
import catchErrors from "../utils/catchErrors";
import config from "../utils/clientConfig";
const AuthContext = createContext({
error: "",
loading: false,
user: {id:0, role:"user"},
setUser: () => { },
login: () => Promise.resolve(false),
logout: () => { },
catchErrorAuth: (error, displayError) => { },
});
const AuthProvider = ({ children }) => {
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const [user, setUser] = useState(getLocalUser());
const login = useCallback(async (id, password) => {
try {
setError("");
setLoading(true);
const user = await authApi.login(id, password);
localStorage.setItem(config.loginUser, JSON.stringify(user));
setUser(user);
return true;
} catch (error) {
catchErrors(error, setError);
return false;
} finally {
setLoading(false);
}
}, []);
const logout = useCallback(async () => {
try {
setError("");
setUser(null);
alert("로그아웃되었습니다.");
localStorage.removeItem(config.loginUser);
setLoading(true);
await axios.get(`${baseUrl}/api/auth/logout`);
} catch (error) {
catchErrors(error, setError);
} finally {
setLoading(false);
}
}, []);
const catchErrorAuth = useCallback(async (error, displayError) => {
let errorMsg;
if (error.response) {
if (typeof error.response.data === "string") {
errorMsg = error.response.data;
console.log("Error response:", errorMsg);
} else {
const { data } = error.response;
if (data.redirectUrl) {
errorMsg = data.message;
console.log("Error response with redirected message:", errorMsg);
console.log("redirect url", data.redirectUrl);
return await logout();
}
}
} else if (error.request) {
errorMsg = error.request;
console.log("Error request:", errorMsg);
} else {
errorMsg = error.message;
console.log("Error message:", errorMsg);
}
displayError(errorMsg);
}, []);
return (
<AuthContext.Provider
value={{ error, loading, user, setUser, login, logout, catchErrorAuth }}
>
{children}
</AuthContext.Provider>
);
};
const useAuth = () => useContext(AuthContext);
export { AuthProvider, useAuth };
\ No newline at end of file
......@@ -3,7 +3,7 @@ import Login from "../components/Login/Login";
const LoginPage = () => {
return (
<div className="d-flex justify-content-center py-5">
<div className="d-flex justify-content-center pb-5">
<Login />
</div>
)
......
import MyInfo from "../components/MyInfo/MyInfo"
const MyPage = () => {
return (
<div>
마이 페이지
<div className="d-flex justify-content-center py-5">
<MyInfo/>
</div>
)
}
......
import config from "./clientConfig";
export function handleLogin(user) {
if (user) {
localStorage.setItem(config.loginUser, JSON.stringify(user));
}
}
export function getLocalUser() {
const userData = localStorage.getItem(config.loginUser);
let user = null;
if (userData) {
user = JSON.parse(userData);
}
return user;
}
\ No newline at end of file
......@@ -39,6 +39,29 @@
"negotiator": "0.6.2"
}
},
"agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
"requires": {
"debug": "4"
},
"dependencies": {
"debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"ansi-align": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
......@@ -101,6 +124,11 @@
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
},
"asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
},
"axios": {
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
......@@ -239,6 +267,15 @@
}
}
},
"call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"requires": {
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.2"
}
},
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
......@@ -427,6 +464,11 @@
"integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
"dev": true
},
"dayjs": {
"version": "1.10.6",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.6.tgz",
"integrity": "sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw=="
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
......@@ -631,6 +673,21 @@
"dev": true,
"optional": true
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"get-intrinsic": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
"integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
"requires": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1"
}
},
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
......@@ -683,12 +740,25 @@
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
"dev": true
},
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"requires": {
"function-bind": "^1.1.1"
}
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"has-symbols": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw=="
},
"has-yarn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
......@@ -713,6 +783,30 @@
"toidentifier": "1.0.0"
}
},
"https-proxy-agent": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
"integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
"requires": {
"agent-base": "6",
"debug": "4"
},
"dependencies": {
"debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
"integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==",
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
......@@ -1153,6 +1247,11 @@
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"object-inspect": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
"integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg=="
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
......@@ -1279,6 +1378,11 @@
"integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
"dev": true
},
"pop-iterate": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pop-iterate/-/pop-iterate-1.0.1.tgz",
"integrity": "sha1-zqz9q0q/NT16DyqqLB/Hs/lBO6M="
},
"postgres-array": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
......@@ -1347,11 +1451,26 @@
"escape-goat": "^2.0.0"
}
},
"q": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/q/-/q-2.0.3.tgz",
"integrity": "sha1-dbjbAlWhpa+C9Yw/Oqoe/sfQ0TQ=",
"requires": {
"asap": "^2.0.0",
"pop-iterate": "^1.0.1",
"weak-map": "^1.0.5"
}
},
"qs": {
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
},
"querystringify": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
"integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
},
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
......@@ -1418,6 +1537,11 @@
"rc": "^1.2.8"
}
},
"requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"responselike": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
......@@ -1435,6 +1559,11 @@
"any-promise": "^1.3.0"
}
},
"rootpath": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/rootpath/-/rootpath-0.1.2.tgz",
"integrity": "sha1-Wzeah9ypBum5HWkKWZQ5vvJn6ms="
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
......@@ -1445,6 +1574,11 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"scmp": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/scmp/-/scmp-2.1.0.tgz",
"integrity": "sha512-o/mRQGk9Rcer/jEEw/yw4mwo3EU/NvYvp577/Btqrym9Qy5/MdWGBqipbALgd2lrdWTJ5/gqDusxfnQBxOxT2Q=="
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
......@@ -1558,6 +1692,16 @@
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
},
"side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"requires": {
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
"object-inspect": "^1.9.0"
}
},
"signal-exit": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
......@@ -1716,6 +1860,34 @@
"nopt": "~1.0.10"
}
},
"twilio": {
"version": "3.66.0",
"resolved": "https://registry.npmjs.org/twilio/-/twilio-3.66.0.tgz",
"integrity": "sha512-2jek7akXcRMusoR20EWA1+e5TQp9Ahosvo81wTUoeS7H24A1xbVQJV4LfSWQN4DLUY1oZ4d6tH2oCe/+ELcpNA==",
"requires": {
"axios": "^0.21.1",
"dayjs": "^1.8.29",
"https-proxy-agent": "^5.0.0",
"jsonwebtoken": "^8.5.1",
"lodash": "^4.17.21",
"q": "2.0.x",
"qs": "^6.9.4",
"rootpath": "^0.1.2",
"scmp": "^2.1.0",
"url-parse": "^1.5.0",
"xmlbuilder": "^13.0.2"
},
"dependencies": {
"qs": {
"version": "6.10.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.10.1.tgz",
"integrity": "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg==",
"requires": {
"side-channel": "^1.0.4"
}
}
}
},
"type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
......@@ -1794,6 +1966,15 @@
"xdg-basedir": "^4.0.0"
}
},
"url-parse": {
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz",
"integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==",
"requires": {
"querystringify": "^2.1.1",
"requires-port": "^1.0.0"
}
},
"url-parse-lax": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
......@@ -1828,6 +2009,11 @@
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
},
"weak-map": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/weak-map/-/weak-map-1.0.5.tgz",
"integrity": "sha1-eWkVhNmGB/UHC9O3CkDmuyLkAes="
},
"widest-line": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
......@@ -1869,6 +2055,11 @@
"integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==",
"dev": true
},
"xmlbuilder": {
"version": "13.0.2",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz",
"integrity": "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ=="
},
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
......
......@@ -26,7 +26,8 @@
"nodemailer": "^6.6.3",
"pg": "^8.6.0",
"pg-hstore": "^2.3.4",
"sequelize": "^6.6.4"
"sequelize": "^6.6.4",
"twilio": "^3.66.0"
},
"devDependencies": {
"nodemon": "^2.0.12"
......
import jwt from "jsonwebtoken";
import config from "../config/app.config.js";
import { User, Role } from '../db/index.js'
import { User, Role } from '../db/index.js';
import Twilio from "twilio";
const login = async (req, res) => {
try {
const { id, password } = req.body;
//사용자 존재 확인
const user = await User.scope("withPassword").findOne({ where: { userId: id } });
console.log("user : ", user);
if (!user) {
return res.status(422).send(`사용자가 존재하지 않습니다`);
}
......@@ -15,14 +16,20 @@ const login = async (req, res) => {
const passwordMatch = await user.comparePassword(password);
if (passwordMatch) {
// 3) 비밀번호가 맞으면 토큰 생성
// const userRole = await user.getRole();
const userRole = await user.getRole();
// const userId = await user.getId();
console.log("userRole1111 : ", userRole);
// console.log("userId : ", userId);
const signData = {
userId: user.userid,
// role: userRole.name,
id: user.id,
role: userRole.name,
};
console.log("signData : ", signData);
const token = jwt.sign(signData, config.jwtSecret, {
expiresIn: config.jwtExpires,
});
console.log(token);
// 4) 토큰을 쿠키에 저장
res.cookie(config.cookieName, token, {
maxAge: config.cookieMaxAge,
......@@ -32,9 +39,8 @@ const login = async (req, res) => {
});
// 5) 사용자 반환
res.json({
userId: user.id,
id: user.id,
role: userRole.name,
// isMember: user.isMember,
});
} else {
// 6) 비밀번호 불일치
......@@ -49,13 +55,13 @@ const login = async (req, res) => {
const logout = async (req, res) => {
try {
res.cookie()
res.cookie(config.cookieName,"")
} catch (error) {
console.error(error);
return res.status(500).send("로그인 에러");
}
}
const compareId = async (req, res) => {
const id = req.params.userId;
const userid = await User.findOne({ where: { userId: id } });
......@@ -66,8 +72,26 @@ const compareId = async (req, res) => {
}
}
const confirmMbnum = async (req, res) => {
const id = req.params.id;
const token = req.params.token;
const client = Twilio(id, token);
// console.log(client);
client.messages
.create({
to: '+8201086074580',
from: '+14159428621',
body: '[ButterStudio] 인증번호[1234]를 입력해주세요',
})
.then(message => console.log(message.sid))
.catch(e => console.log(error));
// console.log("id = ", id, "token = ", token);
return res.json(true);
}
const signup = async (req, res) => {
const { userId, userNickName, userBirthday, userPassword } = req.body;
const { userId, userEmail, userNickName, userBirthday, userPassword } = req.body;
// 휴대폰 중복 확인
const userMbnum = String(req.body.userMbnum);
try {
......@@ -75,9 +99,10 @@ const signup = async (req, res) => {
if (mbnum) {
return res.status(422).send(`이미 있는 휴대폰번호입니다.`);
}
const role = await Role.findOne({ where: { name: "user" } })
const role = await Role.findOne({ where: { name: "member" } })
const newUser = await User.create({
userId: userId,
email: userEmail,
nickname: userNickName,
birth: userBirthday,
phoneNumber: userMbnum,
......@@ -91,10 +116,25 @@ const signup = async (req, res) => {
}
};
const getNickName = async (req, res) => {
console.log("여기여기");
const id = req.params.id;
console.log("id : ", id);
try {
const userNickName = await User.findOne({ where: { id: id }, attributes:["nickname"] });
console.log("userNickName: ", userNickName);
return res.json(userNickName.nickname)
} catch (error) {
console.error("error : ",error.message);
res.status(500).send("회원가입 에러. 나중에 다시 시도 해주세요");
}
}
export default {
login,
logout,
compareId,
signup
confirmMbnum,
signup,
getNickName
}
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