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

Merge branch 'gyumin'

parents c4a8991d bd9ff2cc
...@@ -3073,6 +3073,14 @@ ...@@ -3073,6 +3073,14 @@
"resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.2.3.tgz", "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.2.3.tgz",
"integrity": "sha512-pXnVMfJKSIWU2Ml4JHP7pZEPIrgBO1Fd3WGx+fPBsS+KRGhE4vxooD8XBGWbQOIVSZsVK7pUDBBkCicNu80yzQ==" "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": { "axobject-query": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz",
...@@ -3865,6 +3873,11 @@ ...@@ -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": { "buffer-from": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
...@@ -4925,6 +4938,11 @@ ...@@ -4925,6 +4938,11 @@
"whatwg-url": "^8.0.0" "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": { "debug": {
"version": "4.3.1", "version": "4.3.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
...@@ -5362,6 +5380,14 @@ ...@@ -5362,6 +5380,14 @@
"safer-buffer": "^2.1.0" "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": { "ee-first": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
...@@ -9942,6 +9968,30 @@ ...@@ -9942,6 +9968,30 @@
"universalify": "^2.0.0" "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": { "jsprim": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
...@@ -9962,6 +10012,25 @@ ...@@ -9962,6 +10012,25 @@
"object.assign": "^4.1.2" "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": { "killable": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
...@@ -10093,6 +10162,36 @@ ...@@ -10093,6 +10162,36 @@
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" "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": { "lodash.memoize": {
"version": "4.1.2", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
...@@ -10103,6 +10202,11 @@ ...@@ -10103,6 +10202,11 @@
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" "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": { "lodash.template": {
"version": "4.5.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
...@@ -11417,6 +11521,11 @@ ...@@ -11417,6 +11521,11 @@
"ts-pnp": "^1.1.6" "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": { "portfinder": {
"version": "1.0.28", "version": "1.0.28",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz",
...@@ -13649,6 +13758,11 @@ ...@@ -13649,6 +13758,11 @@
} }
} }
}, },
"rootpath": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/rootpath/-/rootpath-0.1.2.tgz",
"integrity": "sha1-Wzeah9ypBum5HWkKWZQ5vvJn6ms="
},
"rsvp": { "rsvp": {
"version": "4.8.5", "version": "4.8.5",
"resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz",
...@@ -13890,6 +14004,11 @@ ...@@ -13890,6 +14004,11 @@
"ajv-keywords": "^3.5.2" "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": { "scss-tokenizer": {
"version": "0.2.3", "version": "0.2.3",
"resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
...@@ -15306,6 +15425,44 @@ ...@@ -15306,6 +15425,44 @@
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" "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": { "type": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz",
...@@ -15923,6 +16080,11 @@ ...@@ -15923,6 +16080,11 @@
"minimalistic-assert": "^1.0.0" "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": { "web-vitals": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-1.1.2.tgz", "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-1.1.2.tgz",
...@@ -16947,6 +17109,11 @@ ...@@ -16947,6 +17109,11 @@
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
"integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" "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": { "xmlchars": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-scripts": "4.0.3", "react-scripts": "4.0.3",
"twilio": "^3.66.0",
"web-vitals": "^1.0.1" "web-vitals": "^1.0.1"
}, },
"scripts": { "scripts": {
......
import React, { useState, useEffect } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import { AuthProvider } from "./context/auth_context";
import Header from "./components/Header"; import Header from "./components/Header";
import SubNav from "./components/Navs/SubNav"; import SubNav from "./components/Navs/SubNav";
import MainNav from "./components/Navs/MainNav"; import MainNav from "./components/Navs/MainNav";
...@@ -16,16 +16,12 @@ import TicketingSeatPage from './pages/TicketingSeatPage' ...@@ -16,16 +16,12 @@ import TicketingSeatPage from './pages/TicketingSeatPage'
import SearchPage from "./pages/SearchPage"; import SearchPage from "./pages/SearchPage";
import Payment from "./pages/PaymentPage"; import Payment from "./pages/PaymentPage";
const AppContext = React.createContext();
function App() { function App() {
const [role, setRole] = useState("user");
const store = {role, setRole};
return ( return (
<div style={{ backgroundColor: "black" }}> <div className="" style={{ backgroundColor: "black" }}>
<AppContext.Provider value={store}> <AuthProvider>
<Router style={{ backgroundColor: "black"}}> <Router style={{ backgroundColor: "black" }}>
<SubNav /> <SubNav />
<Header /> <Header />
<MainNav /> <MainNav />
...@@ -35,6 +31,7 @@ function App() { ...@@ -35,6 +31,7 @@ function App() {
<Route path="/signup" component={SignupPage} /> <Route path="/signup" component={SignupPage} />
<Route path="/movielist" component={MovieListPage} /> <Route path="/movielist" component={MovieListPage} />
<Route path="/movie/:movieId" component={MoviePage} /> <Route path="/movie/:movieId" component={MoviePage} />
<Route path="/mypage" component={MyPage} />
<Route path="/ticket/seat" component={TicketingSeatPage} /> <Route path="/ticket/seat" component={TicketingSeatPage} />
<Route path="/ticket" component={TicketingPage} /> <Route path="/ticket" component={TicketingPage} />
<Route path="/payment" component={Payment} /> <Route path="/payment" component={Payment} />
...@@ -42,10 +39,9 @@ function App() { ...@@ -42,10 +39,9 @@ function App() {
<Route path="/admin" component={AdminPage} /> <Route path="/admin" component={AdminPage} />
</Switch> </Switch>
</Router> </Router>
</AppContext.Provider> </AuthProvider>
</div> </div>
); );
} }
export { AppContext }
export default App; export default App;
...@@ -25,10 +25,25 @@ const compareId = async (userId) => { ...@@ -25,10 +25,25 @@ const compareId = async (userId) => {
return data 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 = { const authApi = {
login, login,
logout, logout,
signup, signup,
compareId, compareId,
confirmMbnum,
getNickName,
}; };
export default authApi 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 styles from "./login.module.scss";
import authApi from "../../apis/auth.api.js"; import { Redirect } from "react-router-dom";
import { Redirect } from "react-router";
import catchErrors from "../../utils/catchErrors"; import catchErrors from "../../utils/catchErrors";
import {AppContext} from "../../App"; import {useAuth} from "../../context/auth_context.js";
const Login = () => { const Login = () => {
const store = React.useContext(AppContext); const {login, loading} = useAuth();
//useState를 이용해서 각 state 생성 및 초기값 저장 //useState를 이용해서 각 state 생성 및 초기값 저장
const [state, setState] = useState(true); // 이 줄은 css에 해당하는 state const [state, setState] = useState(true); // 이 줄은 css에 해당하는 state
//state변수 지정 하지만 이 변수는 react에 의해 없어지지 않음, 그리고 그 다음 변수는 state변수를 갱신해주는 함수 //state변수 지정 하지만 이 변수는 react에 의해 없어지지 않음, 그리고 그 다음 변수는 state변수를 갱신해주는 함수
const [login, setLogin] = useState({ const [user, setUser] = useState({
id:'', id: '',
password:'' password: ''
}); });
const [error, setError] = useState(""); const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const [success, setSuccess] = useState(false); const [success, setSuccess] = useState(false);
const [guest, setGuset] = useState({ const [guest, setGuset] = useState({
guestName:'', guestName: '',
gusetBirthday:'', gusetBirthday: '',
gusetMbnum:'', gusetMbnum: '',
guestPassword:'' guestPassword: ''
}) })
//input태그에 걸려있는 onchange에서 실행할 함수설정 //input태그에 걸려있는 onchange에서 실행할 함수설정
const handleLoginOnChange = (e) =>{ const handleLoginOnChange = (e) => {
// ... 전개 연산자 // ... 전개 연산자
// 현재 state에 방금 변화한 값을 다시 저장함 // 현재 state에 방금 변화한 값을 다시 저장함
setLogin({ ...login, setUser({
[e.target.name]:e.target.value ...user,
[e.target.name]: e.target.value
}) })
}; };
const handleGuestOnChange = (e) =>{ const handleGuestOnChange = (e) => {
setGuset({ ...guest, setGuset({
[e.target.name]:e.target.value ...guest,
[e.target.name]: e.target.value
}) })
} }
const requestServer = async (data) => { 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(); e.preventDefault();
try{ try {
setError(""); setError("");
setLoading(true); console.log(e.target.name);
if(e.target.value === "Login"){ requestServer(login); } if (e.target.name === "login") {
else{ requestServer(guest); } requestServer(user);
alert('로그인이 완료되었습니다.') alert('로그인이 완료되었습니다.')
setSuccess(true); setSuccess(true);
}catch(error){ }
else {
requestServer(guest);
alert('로그인이 완료되었습니다.')
}
} catch (error) {
catchErrors(error, setError); catchErrors(error, setError);
}finally{
setLoading(false);
} }
} }
if (success) { if (success) {
store.setRole("member");
return <Redirect to="/" />; return <Redirect to="/" />;
} }
return ( return (
<div className={`d-flex flex-column col-md-5 col-10`}> <div className={`d-flex flex-column col-md-5 col-10`}>
{/* nav-tabs */} <span className={styles.title}>로그인</span>
{/* {console.log(login)} */}
<ul className="nav nav-fill nav-tabs w-100" id="loginTab" role="tablist"> <ul className="nav nav-fill nav-tabs w-100" id="loginTab" role="tablist">
<li className="nav-item fs-6" role="presentation"> <li className="nav-item fs-6" role="presentation">
<button className={`nav-link active px-2 ${styles.fontSize}`} style={{ color: state ? "black" : "#FEDC00", backgroundColor: state ? "#FEDC00" : "black"}} <button className={`nav-link active px-2 ${styles.fontSize}`} style={{ color: state ? "black" : "#FEDC00", backgroundColor: state ? "#FEDC00" : "black" }}
id="login-tab" data-bs-toggle="tab" data-bs-target="#login" type="button" role="tab" aria-controls="login" aria-selected="true" 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> onClick={() => setState(true)}>로그인</button>
</li> </li>
<li className="nav-item" role="presentation"> <li className="nav-item" role="presentation">
<button className={`nav-link px-2 ${styles.fontSize}`} <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" 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> onClick={() => setState(false)} style={{ color: state ? "#FEDC00" : "black", backgroundColor: state ? "black" : "#FEDC00" }}>비회원 예매 확인</button>
</li> </li>
</ul> </ul>
<div className="tab-content w-100" id="myTabContent"> <div className="tab-content w-100" id="myTabContent">
{/* 로그인 */} {/* 로그인 */}
<div className="tab-pane fade show active" id="login" role="tabpanel" aria-labelledby="login-tab"> <div className="tab-pane fade show active" id="login" role="tabpanel" aria-labelledby="login-tab">
<form className="d-flex flex-column" onSubmit={handleOnSummit}> <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="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={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> <span><a href="./signup" className={styles.intoSignupPage}>회원이 아니십니까?</a></span>
</form> </form>
</div> </div>
...@@ -95,6 +99,7 @@ const Login = () => { ...@@ -95,6 +99,7 @@ const Login = () => {
<div className="tab-pane fade" id="guest" role="tabpanel" aria-labelledby="guest-tab"> <div className="tab-pane fade" id="guest" role="tabpanel" aria-labelledby="guest-tab">
<form className="d-flex flex-column" onSubmit={handleOnSummit}> <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="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="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="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 /> <input className={styles.input} type="password" name="guestPassword" id="password" placeholder="비밀번호" onChange={handleGuestOnChange} maxLength="11" required />
...@@ -102,7 +107,7 @@ const Login = () => { ...@@ -102,7 +107,7 @@ const Login = () => {
<p className={`text-white ${styles.fontSizeTwo}`}> <p className={`text-white ${styles.fontSizeTwo}`}>
비회원 정보 입력 예매 내역 확인/취소 티켓 발권이 어려울 있으니 다시 한번 확인해 주시기 바랍니다. 비회원 정보 입력 예매 내역 확인/취소 티켓 발권이 어려울 있으니 다시 한번 확인해 주시기 바랍니다.
</p> </p>
<input className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} type="submit" value="비회원 예매 확인" disabled={loading}/> <input className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} type="submit" value="비회원 예매 확인" disabled={loading} />
</form> </form>
</div> </div>
</div> </div>
......
.title{
display: flex;
justify-content: center;
color: #FEDC00;
font-size: 1.7rem;
margin: 2rem 0;
}
.intoSignupPage{ .intoSignupPage{
font-size: 13px; font-size: 13px;
text-decoration: none; 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 { Link } from "react-router-dom";
import { AppContext } from "../../App"; import { useAuth } from "../../context/auth_context.js"
import authApi from '../../apis/auth.api'
const SubNav = () => { const SubNav = () => {
const store = useContext(AppContext); const { user, logout } = useAuth();
useEffect(() => {
window.localStorage.setItem("user", JSON.stringify(store.role));
}, [store]);
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 ( return (
<nav className="nav justify-content-end py-1"> <> {(user) ?
<a className="nav-link text-white" href="/login">로그인</a> <nav className="nav justify-content-end py-1">
<a className="nav-link text-white" href="/signup">회원가입</a> {(user.role === "member")
</nav> ? <><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 export default SubNav
\ No newline at end of file
import styles from "./signup.module.scss"; import styles from "./signup.module.scss";
import { useState } from 'react'; import { useState } from "react";
import authApi from "../../apis/auth.api.js"; import authApi from "../../apis/auth.api.js";
import { Redirect } from "react-router"; import { Redirect } from "react-router";
import catchErrors from "../../utils/catchErrors.js"; import catchErrors from "../../utils/catchErrors.js";
import Twilio from "twilio";
const Signup = () => { const Signup = () => {
const [user, setUser] = useState({ const [user, setUser] = useState({
userId: "", userId: "",
userEmail: "",
userNickName: "", userNickName: "",
userBirthday: "", userBirthday: "",
userMbnum: "", userMbnum: "",
...@@ -17,9 +19,10 @@ const Signup = () => { ...@@ -17,9 +19,10 @@ const Signup = () => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [success, setSuccess] = useState(false); const [success, setSuccess] = useState(false);
//각 타입별 error 유무 state //각 타입별 error 유무 state
const [error,setError] = useState(""); const [error, setError] = useState("");
const [errorMsg, setErrorMsg] = useState({ const [errorMsg, setErrorMsg] = useState({
errorId: null, errorId: null,
errorEmail: false,
errorNickName: false, errorNickName: false,
errorBirthday: false, errorBirthday: false,
errorMbnum: false, errorMbnum: false,
...@@ -36,7 +39,7 @@ const Signup = () => { ...@@ -36,7 +39,7 @@ const Signup = () => {
...user, ...user,
[e.target.name]: e.target.value [e.target.name]: e.target.value
}) })
if(e.target.name === "userBirthday" || e.target.name === "userMbum"){ if (e.target.name === "userBirthday" || e.target.name === "userMbum") {
setUser({ setUser({
...user, ...user,
[e.target.name]: String(e.target.value) [e.target.name]: String(e.target.value)
...@@ -47,7 +50,7 @@ const Signup = () => { ...@@ -47,7 +50,7 @@ const Signup = () => {
//id(중복확인 체크, 형식 에러) //id(중복확인 체크, 형식 에러)
const handleOnClickId = async (e) => { const handleOnClickId = async (e) => {
e.preventDefault(); e.preventDefault();
try{ try {
setError(""); setError("");
if (user.userId.length < 5) { if (user.userId.length < 5) {
setErrorMsg(errorMsg => ({ setErrorMsg(errorMsg => ({
...@@ -60,32 +63,41 @@ const Signup = () => { ...@@ -60,32 +63,41 @@ const Signup = () => {
} else { } else {
const userId = user.userId; const userId = user.userId;
await authApi.compareId(userId); await authApi.compareId(userId);
if(!await authApi.compareId(userId)){ if (!await authApi.compareId(userId)) {
alert("이 아이디는 사용가능합니다.") alert("이 아이디는 사용가능합니다.")
setErrorMsg(errorMsg => ({ setErrorMsg(errorMsg => ({
...errorMsg, ...errorMsg,
[e.target.name]: false [e.target.name]: false
})); }));
setOverlapId(()=>(true)); setOverlapId(() => (true));
}else{ } else {
alert("이미 사용중인 아이디입니다.") alert("이미 사용중인 아이디입니다.")
setOverlapId(()=>(false)); setOverlapId(() => (false));
} }
} }
}catch(error){ } catch (error) {
catchErrors(error,setError) catchErrors(error, setError)
}finally { } finally {
setLoading(false); 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) => { const handleOnSummit = async (e) => {
e.preventDefault(); e.preventDefault();
try { try {
setError(()=>("")); setError(() => (""));
//처리가 될때까지 버튼(가입하기)이 안눌리게 지정 //처리가 될때까지 버튼(가입하기)이 안눌리게 지정
setLoading(()=>(true)); setLoading(() => (true));
//유효성 검사 //유효성 검사
validation(); validation();
const userData = user; const userData = user;
...@@ -105,28 +117,28 @@ const Signup = () => { ...@@ -105,28 +117,28 @@ const Signup = () => {
const vaildationData = (text, compareValue, error) => { const vaildationData = (text, compareValue, error) => {
if (text !== compareValue) { if (text !== compareValue) {
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: true })); setErrorMsg(errorMsg => ({ ...errorMsg, [error]: true }));
} else{ } else {
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: false })); setErrorMsg(errorMsg => ({ ...errorMsg, [error]: false }));
} }
} }
//아이디 비번 유효성 검사 //아이디 비번 유효성 검사
const vaildationIdPw = (text, minValue, error) => { const vaildationIdPw = (text, minValue, error) => {
if((text < minValue)){ if ((text < minValue)) {
setErrorMsg(errorMsg => ({...errorMsg, [error]: true})); setErrorMsg(errorMsg => ({ ...errorMsg, [error]: true }));
} else if(text >= minValue){ } else if (text >= minValue) {
setErrorMsg(errorMsg => ({ ...errorMsg, [error]: false })); setErrorMsg(errorMsg => ({ ...errorMsg, [error]: false }));
if(overlapId === true){ if (overlapId === true) {
if(preId !== user.userId){ if (preId !== user.userId) {
setOverlapId(false); setOverlapId(false);
} }
} }
} }
} }
//유효성 검사 //유효성 검사
const validation = () => { const validation = () => {
setPreId(user.userId); setPreId(user.userId);
//아이디 유효성 검사 //아이디 유효성 검사
vaildationIdPw(user.userId.length,5,"errorId"); vaildationIdPw(user.userId.length, 5, "errorId");
//별명 유효성 검사 //별명 유효성 검사
vaildationData((user.userNickName.length === 0), false, "errorNickName"); vaildationData((user.userNickName.length === 0), false, "errorNickName");
// 생일 유효성 검사 // 생일 유효성 검사
...@@ -134,16 +146,16 @@ const Signup = () => { ...@@ -134,16 +146,16 @@ const Signup = () => {
// 휴대폰 유효성 검사 // 휴대폰 유효성 검사
vaildationData(user.userMbnum.length, 11, "errorMbnum"); vaildationData(user.userMbnum.length, 11, "errorMbnum");
// 비밀번호 유효성 검사 // 비밀번호 유효성 검사
vaildationIdPw(user.userPassword.length,8,"errorPassword"); vaildationIdPw(user.userPassword.length, 8, "errorPassword");
// 비밀번호 확인 유효성 검사 // 비밀번호 확인 유효성 검사
vaildationData(user.userRePassword, user.userPassword, "errorRePassword"); vaildationData(user.userRePassword, user.userPassword, "errorRePassword");
// 최종 유효성 검사 // 최종 유효성 검사
if (overlapId && (Object.values(errorMsg).some((element) => (element)) === false)) { if (overlapId && (Object.values(errorMsg).some((element) => (element)) === false)) {
}else if(!overlapId && (Object.values(errorMsg).some((element) => (element)) === false)){ } else if (!overlapId && (Object.values(errorMsg).some((element) => (element)) === false)) {
setErrorMsg(errorMsg => ({...errorMsg, errorId: false})); setErrorMsg(errorMsg => ({ ...errorMsg, errorId: false }));
throw new Error("먼저 아이디 중복확인을 해주세요"); throw new Error("먼저 아이디 중복확인을 해주세요");
}else{ } else {
throw new Error("유효하지 않은 데이터입니다."); throw new Error("유효하지 않은 데이터입니다.");
} }
} }
...@@ -151,7 +163,7 @@ const Signup = () => { ...@@ -151,7 +163,7 @@ const Signup = () => {
if (success) { if (success) {
return <Redirect to="/login" />; return <Redirect to="/login" />;
} }
return ( return (
// 데이터 입력과 유효성 검사 후 보이는 경고창 // 데이터 입력과 유효성 검사 후 보이는 경고창
...@@ -162,7 +174,7 @@ const Signup = () => { ...@@ -162,7 +174,7 @@ const Signup = () => {
<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="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> <button type="button" disabled={loading} name="errorId" className={`rounded-2 mt-2 ${styles.butterYellowAndBtn} ${styles.btnHover}`} onClick={handleOnClickId}>중복확인</button>
</div> </div>
</div> </div>
...@@ -170,10 +182,17 @@ const Signup = () => { ...@@ -170,10 +182,17 @@ const Signup = () => {
{overlapId && (errorMsg.errorId === false) && <p className={styles.passwordConfirmError}>아이디 중복이 확인되었습니다.</p>} {overlapId && (errorMsg.errorId === false) && <p className={styles.passwordConfirmError}>아이디 중복이 확인되었습니다.</p>}
{(errorMsg.errorId === false) && (overlapId === false) && <p className={styles.passwordConfirmError}>아이디 중복확인을 해주세요.</p>} {(errorMsg.errorId === false) && (overlapId === false) && <p className={styles.passwordConfirmError}>아이디 중복확인을 해주세요.</p>}
</div> </div>
<div className="d-flex flex-column">
<div className={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="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" 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> </div>
{errorMsg.errorNickName && <p className={styles.passwordConfirmError}>10 이내로 입력해주세요.</p>} {errorMsg.errorNickName && <p className={styles.passwordConfirmError}>10 이내로 입력해주세요.</p>}
</div> </div>
...@@ -181,7 +200,7 @@ const Signup = () => { ...@@ -181,7 +200,7 @@ const Signup = () => {
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<div className={styles.inputContent}> <div className={styles.inputContent}>
<label className={styles.signupLabel}>생년월일</label> <label className={styles.signupLabel}>생년월일</label>
<input className={`${styles.input} ${styles.inputSize} ${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> </div>
{errorMsg.errorBirthday && <p className={styles.passwordConfirmError}>숫자 6자리를 입력해주세요.</p>} {errorMsg.errorBirthday && <p className={styles.passwordConfirmError}>숫자 6자리를 입력해주세요.</p>}
</div> </div>
...@@ -189,14 +208,17 @@ const Signup = () => { ...@@ -189,14 +208,17 @@ const Signup = () => {
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<div className={styles.inputContent}> <div className={styles.inputContent}>
<label className={styles.signupLabel}>휴대폰 번호</label> <label className={styles.signupLabel}>휴대폰 번호</label>
<input className={`${styles.input} ${styles.inputSize}`} type="number" name="userMbnum" id="userMbnum" placeholder="-없이 11자리 입력" onChange={handleUserOnChange} min="" 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> </div>
{errorMsg.errorMbnum && <p className={styles.passwordConfirmError}>-없이 숫자 11자리를 입력해주세요.</p>} {errorMsg.errorMbnum && <p className={styles.passwordConfirmError}>-없이 숫자 11자리를 입력해주세요.</p>}
</div> </div>
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<div className={`${styles.inputContent}`}> <div className={`${styles.inputContent}`}>
<label className={styles.signupLabel}>비밀번호</label> <label className={styles.signupLabel}>비밀번호</label>
<input className={`${styles.input} ${styles.inputSize}`} type="password" name="userPassword" id="password" placeholder="8~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> </div>
{errorMsg.errorPassword && <p className={styles.passwordConfirmError}>8~11자리 사이로 입력해주세요.</p>} {errorMsg.errorPassword && <p className={styles.passwordConfirmError}>8~11자리 사이로 입력해주세요.</p>}
</div> </div>
...@@ -204,7 +226,7 @@ const Signup = () => { ...@@ -204,7 +226,7 @@ const Signup = () => {
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<div className={styles.inputContent}> <div className={styles.inputContent}>
<label className={styles.signupLabel}>비밀번호 확인</label> <label className={styles.signupLabel}>비밀번호 확인</label>
<input className={`${styles.input} ${styles.inputSize}`} type="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> </div>
{errorMsg.errorRePassword && <p className={styles.passwordConfirmError}>비밀번호가 일치하지 않습니다.</p>} {errorMsg.errorRePassword && <p className={styles.passwordConfirmError}>비밀번호가 일치하지 않습니다.</p>}
</div> </div>
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
display: flex; display: flex;
justify-content: center; justify-content: center;
color: #FEDC00; color: #FEDC00;
font-size: 25px; font-size: 1.7rem;
margin-top: 20px; margin-top: 2rem;
} }
.contents{ .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"; ...@@ -3,7 +3,7 @@ import Login from "../components/Login/Login";
const LoginPage = () => { const LoginPage = () => {
return ( return (
<div className="d-flex justify-content-center py-5"> <div className="d-flex justify-content-center pb-5">
<Login /> <Login />
</div> </div>
) )
......
import MyInfo from "../components/MyInfo/MyInfo"
const MyPage = () => { const MyPage = () => {
return ( return (
<div> <div className="d-flex justify-content-center py-5">
마이 페이지 <MyInfo/>
</div> </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 @@ ...@@ -39,6 +39,29 @@
"negotiator": "0.6.2" "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": { "ansi-align": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
...@@ -101,6 +124,11 @@ ...@@ -101,6 +124,11 @@
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" "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": { "axios": {
"version": "0.21.1", "version": "0.21.1",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
...@@ -239,6 +267,15 @@ ...@@ -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": { "camelcase": {
"version": "5.3.1", "version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
...@@ -427,6 +464,11 @@ ...@@ -427,6 +464,11 @@
"integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
"dev": true "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": { "debug": {
"version": "2.6.9", "version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
...@@ -631,6 +673,21 @@ ...@@ -631,6 +673,21 @@
"dev": true, "dev": true,
"optional": 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": { "get-stream": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
...@@ -683,12 +740,25 @@ ...@@ -683,12 +740,25 @@
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
"dev": true "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": { "has-flag": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true "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": { "has-yarn": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
...@@ -713,6 +783,30 @@ ...@@ -713,6 +783,30 @@
"toidentifier": "1.0.0" "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": { "iconv-lite": {
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
...@@ -1153,6 +1247,11 @@ ...@@ -1153,6 +1247,11 @@
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" "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": { "on-finished": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
...@@ -1279,6 +1378,11 @@ ...@@ -1279,6 +1378,11 @@
"integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
"dev": true "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": { "postgres-array": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
...@@ -1347,11 +1451,26 @@ ...@@ -1347,11 +1451,26 @@
"escape-goat": "^2.0.0" "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": { "qs": {
"version": "6.7.0", "version": "6.7.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" "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": { "range-parser": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
...@@ -1418,6 +1537,11 @@ ...@@ -1418,6 +1537,11 @@
"rc": "^1.2.8" "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": { "responselike": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
...@@ -1435,6 +1559,11 @@ ...@@ -1435,6 +1559,11 @@
"any-promise": "^1.3.0" "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": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
...@@ -1445,6 +1574,11 @@ ...@@ -1445,6 +1574,11 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" "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": { "semver": {
"version": "5.7.1", "version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
...@@ -1558,6 +1692,16 @@ ...@@ -1558,6 +1692,16 @@
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" "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": { "signal-exit": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
...@@ -1716,6 +1860,34 @@ ...@@ -1716,6 +1860,34 @@
"nopt": "~1.0.10" "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": { "type-fest": {
"version": "0.8.1", "version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
...@@ -1794,6 +1966,15 @@ ...@@ -1794,6 +1966,15 @@
"xdg-basedir": "^4.0.0" "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": { "url-parse-lax": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
...@@ -1828,6 +2009,11 @@ ...@@ -1828,6 +2009,11 @@
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" "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": { "widest-line": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
...@@ -1869,6 +2055,11 @@ ...@@ -1869,6 +2055,11 @@
"integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==",
"dev": true "dev": true
}, },
"xmlbuilder": {
"version": "13.0.2",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz",
"integrity": "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ=="
},
"xtend": { "xtend": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
......
...@@ -26,7 +26,8 @@ ...@@ -26,7 +26,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",
"twilio": "^3.66.0"
}, },
"devDependencies": { "devDependencies": {
"nodemon": "^2.0.12" "nodemon": "^2.0.12"
......
import jwt from "jsonwebtoken"; import jwt from "jsonwebtoken";
import config from "../config/app.config.js"; 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) => { const login = async (req, res) => {
try { try {
const { id, password } = req.body; const { id, password } = req.body;
//사용자 존재 확인 //사용자 존재 확인
const user = await User.scope("withPassword").findOne({ where: { userId: id } }); const user = await User.scope("withPassword").findOne({ where: { userId: id } });
console.log("user : ", user);
if (!user) { if (!user) {
return res.status(422).send(`사용자가 존재하지 않습니다`); return res.status(422).send(`사용자가 존재하지 않습니다`);
} }
...@@ -15,14 +16,20 @@ const login = async (req, res) => { ...@@ -15,14 +16,20 @@ const login = async (req, res) => {
const passwordMatch = await user.comparePassword(password); const passwordMatch = await user.comparePassword(password);
if (passwordMatch) { if (passwordMatch) {
// 3) 비밀번호가 맞으면 토큰 생성 // 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 = { const signData = {
userId: user.userid, id: user.id,
// role: userRole.name, role: userRole.name,
}; };
console.log("signData : ", signData);
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,
...@@ -32,9 +39,8 @@ const login = async (req, res) => { ...@@ -32,9 +39,8 @@ const login = async (req, res) => {
}); });
// 5) 사용자 반환 // 5) 사용자 반환
res.json({ res.json({
userId: user.id, id: user.id,
role: userRole.name, role: userRole.name,
// isMember: user.isMember,
}); });
} else { } else {
// 6) 비밀번호 불일치 // 6) 비밀번호 불일치
...@@ -49,13 +55,13 @@ const login = async (req, res) => { ...@@ -49,13 +55,13 @@ const login = async (req, res) => {
const logout = async (req, res) => { const logout = async (req, res) => {
try { try {
res.cookie() res.cookie(config.cookieName,"")
} catch (error) { } catch (error) {
console.error(error); console.error(error);
return res.status(500).send("로그인 에러"); return res.status(500).send("로그인 에러");
} }
} }
const compareId = async (req, res) => { const compareId = async (req, res) => {
const id = req.params.userId; const id = req.params.userId;
const userid = await User.findOne({ where: { userId: id } }); const userid = await User.findOne({ where: { userId: id } });
...@@ -66,8 +72,26 @@ const compareId = async (req, res) => { ...@@ -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 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); const userMbnum = String(req.body.userMbnum);
try { try {
...@@ -75,9 +99,10 @@ const signup = async (req, res) => { ...@@ -75,9 +99,10 @@ const signup = async (req, res) => {
if (mbnum) { if (mbnum) {
return res.status(422).send(`이미 있는 휴대폰번호입니다.`); 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({ const newUser = await User.create({
userId: userId, userId: userId,
email: userEmail,
nickname: userNickName, nickname: userNickName,
birth: userBirthday, birth: userBirthday,
phoneNumber: userMbnum, phoneNumber: userMbnum,
...@@ -91,10 +116,25 @@ const signup = async (req, res) => { ...@@ -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 { export default {
login, login,
logout, logout,
compareId, 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