diff --git a/package-lock.json b/package-lock.json index 741e29e..a2dc787 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "axios": "^1.4.0", "bootstrap": "^5.3.0", "frappe-gantt": "^0.6.1", + "http-proxy-middleware": "^2.0.6", "moment": "^2.29.4", "react": "^18.2.0", "react-beautiful-dnd": "^13.1.1", diff --git a/package.json b/package.json index 5eefd85..c182d2e 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "axios": "^1.4.0", "bootstrap": "^5.3.0", "frappe-gantt": "^0.6.1", + "http-proxy-middleware": "^2.0.6", "moment": "^2.29.4", "react": "^18.2.0", "react-beautiful-dnd": "^13.1.1", diff --git a/src/App.tsx b/src/App.tsx index ebe616b..dd04b71 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,12 +3,15 @@ import { AuthenticationContextProvider } from "./service/authentication/authenti import AppRouter from "./navigation/AppRouter"; import "bootstrap/dist/css/bootstrap.min.css"; import { TeamsContextProvider } from "./service/teams/teams.context"; +import { ProjectsContextProvider } from "./service/projects/projects.context"; const App: React.FC = () => { return ( - + + + ); diff --git a/src/assets/images/ghLogo.png b/src/assets/images/ghLogo.png new file mode 100644 index 0000000..57bc3fe Binary files /dev/null and b/src/assets/images/ghLogo.png differ diff --git a/src/assets/images/profile.png b/src/assets/images/profile.png new file mode 100644 index 0000000..1c927a4 Binary files /dev/null and b/src/assets/images/profile.png differ diff --git a/src/components/Modal/EmailVerifyModal.css b/src/components/Modal/EmailVerifyModal.css new file mode 100644 index 0000000..4b735a3 --- /dev/null +++ b/src/components/Modal/EmailVerifyModal.css @@ -0,0 +1,11 @@ +.EmailVerifyModal .inputLabel { + margin-bottom: 16px; +} +.EmailVerifyModal .infoBox { + background-color: rgba(218, 218, 218, 0.33); + padding: 4%; + border-radius: 20px; + margin-top: 40px; +} +.EmailVerifyModal .infoText { +} diff --git a/src/components/Modal/EmailVerifyModal.js b/src/components/Modal/EmailVerifyModal.js new file mode 100644 index 0000000..f84dbd2 --- /dev/null +++ b/src/components/Modal/EmailVerifyModal.js @@ -0,0 +1,57 @@ +import React, { useContext, useState } from "react"; +import { Button, Modal, Form } from "react-bootstrap"; +import "./EmailVerifyModal.css"; +import { BsDot } from "react-icons/bs"; + +export const EmailVerifyModal = ({ show, handleClose, checkNumber, setCheckNumber, CheckEmailMessageHandler }) => { + return ( + + + 인증번호 + + +
+ + 이메일로 인증번호 전송이 완료되었습니다! + setCheckNumber(e.target.value)} /> + +
+
+

인증번호 문자를 못 받으셨나요?

+
+ +

+ 입력하신 인증정보가 일치하지 않을 경우, 인증번호 문자 +
는 발송되지 않습니다. +

+
+
+ +

+ 인증번호가 문자로 수신되지 않을 경우 정확한 정보로 재 +
시도해 주시기 바랍니다. +

+
+
+
+ + + + +
+ ); +}; diff --git a/src/navigation/AppRouter.tsx b/src/navigation/AppRouter.tsx index 8d6d44f..eb5c2ae 100644 --- a/src/navigation/AppRouter.tsx +++ b/src/navigation/AppRouter.tsx @@ -15,38 +15,38 @@ import MyIssues from "../pages/MyIssues/MyIssues"; import TeamInfo from "../pages/TeamInfo/TeamInfo"; import TeamSetting from "../pages/TeamSetting/TeamSetting"; import { ProjectAccess } from "../pages/ProjectSetting/ProjectAccess"; -import { ProjectSetting } from "../pages/ProjectSetting/projectSetting"; -import { ProjectsContextProvider } from "../service/projects/projects.context"; -import React from "react"; +import { ProjectSetting } from "../pages/ProjectSetting/ProjectSetting"; +import { Profile } from "../pages/Profile/Profile"; +import { GithubLogin } from "../pages/Login/GithubLogin"; const AppRouter = (): JSX.Element => { - return ( - - - - }> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - }> - } /> - } /> - } /> - - }> - } /> - } /> - } /> - } /> - - - - - - ); + return ( + + + }> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + }> + } /> + } /> + } /> + + }> + } /> + } /> + } /> + } /> + + + + + ); }; export default AppRouter; diff --git a/src/navigation/LeftTeamSection.css b/src/navigation/LeftTeamSection.css index f0bce8f..957cd26 100644 --- a/src/navigation/LeftTeamSection.css +++ b/src/navigation/LeftTeamSection.css @@ -1,39 +1,40 @@ .LeftTeamSection { - display: flex; - width: 100%; - background-color: #e9e3f5; + display: flex; + width: 100%; + height: 100%; + background-color: #e9e3f5; } .LeftTeamSection .container { - display: flex; - margin: 4%; - padding: 4%; - flex-direction: column; - align-items: center; - width: 200px; - height: fit-content; - border-radius: 50px; - background-color: white; - box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px; + display: flex; + margin: 4%; + padding: 4%; + flex-direction: column; + align-items: center; + width: 200px; + height: fit-content; + border-radius: 50px; + background-color: white; + box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px; } .LeftTeamSection .all-button, .LeftTeamSection .private-button { - width: 100px; - margin-top: 10px; + width: 100px; + margin-top: 10px; } .LeftTeamSection .teams { - display: flex; - flex-direction: column; - align-items: flex-start; - margin-top: 20px; + display: flex; + flex-direction: column; + align-items: flex-start; + margin-top: 20px; } .LeftTeamSection .teams-title { } .LeftTeamSection .teams Button { - margin-top: 10px; - width: 100px; + margin-top: 10px; + width: 100px; } diff --git a/src/navigation/TopNavBar.tsx b/src/navigation/TopNavBar.tsx index e384e1f..e20bafe 100644 --- a/src/navigation/TopNavBar.tsx +++ b/src/navigation/TopNavBar.tsx @@ -14,116 +14,122 @@ import Notification from "../components/Notification/Notification"; import MyWork from "../components/MyWork/MyWork"; interface LoggedInNavProps { - onNotificationClick: () => void; - onMyWorkClick: () => void; + onNotificationClick: () => void; + onMyWorkClick: () => void; } const LoggedInNav = ({ onNotificationClick, onMyWorkClick }: LoggedInNavProps) => { - const { OnLogout } = useContext(AuthenticationContext); - const navigate = useNavigate(); + const { OnLogout } = useContext(AuthenticationContext); + const navigate = useNavigate(); - return ( - <> - - - - - 알람 - 설정 - 프로필 - { - OnLogout(); - }} - > - 로그아웃 - - - - ); + return ( + <> + + + + + 알람 + 설정 + { + navigate("/profile"); + }} + > + 프로필 + + { + OnLogout(); + }} + > + 로그아웃 + + + + ); }; const LoggedOutNav = () => { - const navigate = useNavigate(); - return ( - <> - - - - - navigate("/login")}>Sign In - navigate("/registerform")}>Join - - - ); + const navigate = useNavigate(); + return ( + <> + + + + + navigate("/login")}>Sign In + navigate("/registerform")}>Join + + + ); }; export const TopNavBar = () => { - const { isLogin } = useContext(AuthenticationContext); - const [showNotification, setShowNotification] = useState(false); - const [showMyWork, setShowMyWork] = useState(false); - const navigate = useNavigate(); - const handleNotificationClick = () => { - setShowNotification(true); - }; + const { isLogin } = useContext(AuthenticationContext); + const [showNotification, setShowNotification] = useState(false); + const [showMyWork, setShowMyWork] = useState(false); + const navigate = useNavigate(); + const handleNotificationClick = () => { + setShowNotification(true); + }; - const handleCloseNotification = () => { - setShowNotification(false); - }; + const handleCloseNotification = () => { + setShowNotification(false); + }; - const handleMyWorkClick = () => { - setShowMyWork(true); - }; + const handleMyWorkClick = () => { + setShowMyWork(true); + }; - const handleCloseMywork = () => { - setShowMyWork(false); - }; + const handleCloseMywork = () => { + setShowMyWork(false); + }; - return ( -
- - - { - navigate("/"); - }} - style={{ cursor: "pointer" }} - > - - A-Log - - - {isLogin === true ? : } - - - - - -
- ); + return ( +
+ + + { + navigate("/"); + }} + style={{ cursor: "pointer" }} + > + + A-Log + + + {isLogin === true ? : } + + + + + +
+ ); }; diff --git a/src/pages/Login/GithubLogin.css b/src/pages/Login/GithubLogin.css new file mode 100644 index 0000000..a9d7662 --- /dev/null +++ b/src/pages/Login/GithubLogin.css @@ -0,0 +1,21 @@ +.GithubLogin { + margin-top: 10%; + width: 100%; + height: 100%; + display: flex; + justify-content: center; +} +.GithubLogin .container { + width: fit-content; + justify-content: center; +} +.GithubLogin .ghLogo { + width: 200px; +} +.GithubLogin .loadingWrapper { + margin-top: 40px; + display: flex; + align-items: center; + width: 170px; + justify-content: space-between; +} diff --git a/src/pages/Login/GithubLogin.js b/src/pages/Login/GithubLogin.js new file mode 100644 index 0000000..d3ff385 --- /dev/null +++ b/src/pages/Login/GithubLogin.js @@ -0,0 +1,70 @@ +import { useContext, useEffect } from "react"; +import { GithubAuth } from "../../service/authentication/github.service"; +import { useLocation, useNavigate } from "react-router-dom"; +import { AuthenticationContext } from "../../service/authentication/authentication.context"; +import { FloatingWrapper } from "../../components/FloatingWrapper"; +import { Spinner } from "react-bootstrap"; +import GithubLogo from "../../assets/images/ghLogo.png"; +import "./GithubLogin.css"; +export const GithubLogin = () => { + const location = useLocation(); + const navigate = useNavigate(); + const { OnGHLogin, isLogin } = useContext(AuthenticationContext); + + useEffect(() => { + if (isLogin === true) { + navigate("/"); + } + }, [isLogin]); + useEffect(() => { + if (isLogin === true) { + navigate("/"); + } + }, []); + useEffect(() => { + if (location.search) { + fetchGithubAuth(); + } + }, []); + + const fetchGithubAuth = async () => { + const code = urlArgs().code; + const accessToken = await GithubAuth(code); // await를 사용 + const loginres = await OnGHLogin(accessToken); + console.log(loginres); + if (loginres.type === "email") { + navigate("/registerform", { state: { email: loginres.result } }); + } else { + } + }; + + const urlArgs = () => { + var args = {}; + var query = location.search.substring(1); + var pairs = query.split("&"); + for (var i = 0; i < pairs.length; i++) { + var pos = pairs[i].indexOf("="); + if (pos === -1) { + continue; + } + var name = pairs[i].substring(0, pos); + var value = pairs[i].substring(pos + 1); + value = decodeURIComponent(value); + args[name] = value; + } + console.log(args); + return args; + }; + + return ( +
+ + +
+
깃허브 로그인중...
+ +
+
+
+ ); +}; diff --git a/src/pages/Login/Login.css b/src/pages/Login/Login.css index c6d9d18..0cad111 100644 --- a/src/pages/Login/Login.css +++ b/src/pages/Login/Login.css @@ -3,7 +3,8 @@ flex-direction: column; justify-content: center; align-items: center; - margin-top: 7%; + margin-top: 4%; + margin-bottom: 4%; } .Login .center { diff --git a/src/pages/Login/Login.js b/src/pages/Login/Login.js index 2ab1d30..5290fb5 100644 --- a/src/pages/Login/Login.js +++ b/src/pages/Login/Login.js @@ -2,12 +2,13 @@ import React, { useContext, useEffect, useState } from "react"; import Button from "react-bootstrap/Button"; import "./Login.css"; import logo from "../../assets/logo/alog-logo.png"; -import { GitHubLoginRequestHandler } from "../../service/authentication/authentication.service"; + import { useLocation, useNavigate } from "react-router-dom"; import { FloatingWrapper } from "../../components/FloatingWrapper"; import FadeIn from "../../animation/FadeIn"; import { TextButton } from "../../components/Buttons"; import { AuthenticationContext } from "../../service/authentication/authentication.context"; +import { GitHubLoginRequestHandler, GithubAuth } from "../../service/authentication/github.service"; const Login = () => { const location = useLocation(); @@ -18,7 +19,7 @@ const Login = () => { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); - const LoginHandler = (email, password) => { + const LoginHandler = () => { OnLogin(email, password); }; @@ -32,37 +33,10 @@ const Login = () => { navigate("/"); } }, []); - // 깃허브로 로그인후 동작하는 코드. - useEffect(() => { - if (location.search) { - function urlArgs() { - var args = {}; - var query = location.search.substring(1); - var pairs = query.split("&"); - for (var i = 0; i < pairs.length; i++) { - // '이름=값' 패턴을 찾는다. - var pos = pairs[i].indexOf("="); - // 찾을 수 없다면 스킵한다. - if (pos === -1) { - continue; - } - // 이름을 추출한다. - var name = pairs[i].substring(0, pos); - // 값을 추출한다. - var value = pairs[i].substring(pos + 1); - // 값을 해석한다. - value = decodeURIComponent(value); - // 프로퍼티로 저장한다. - args[name] = value; - } - // 추출된 전달인자들을 반환한다. - console.log(args); - navigate(`/registerform`, { state: { email: "asdf@gmail.com" } }); - return args; - } - urlArgs(); - } - }, []); + + const OnGithubLogin = () => { + GitHubLoginRequestHandler(); + }; return ( @@ -86,7 +60,7 @@ const Login = () => { - + */}
Password
diff --git a/src/service/authentication/authentication.context.js b/src/service/authentication/authentication.context.js index 1e6d1e2..69b474b 100644 --- a/src/service/authentication/authentication.context.js +++ b/src/service/authentication/authentication.context.js @@ -1,82 +1,132 @@ import React, { useState, createContext, useEffect } from "react"; -import { PostSendVerifyEmail, PostVerifyEmail, UsersCheckDuplicate, UsersLogin, UsersSignup, loginHandler } from "./authentication.service"; +import { + GetEmailWithGHToken, + PermitAllEmailLogin, + PostSendVerifyEmail, + PostVerifyEmail, + UsersCheckDuplicate, + UsersLogin, + UsersSignup, + loginHandler, + permitAllEmailLogin, +} from "./authentication.service"; export const AuthenticationContext = createContext(); export const AuthenticationContextProvider = ({ children }) => { - const [userToken, setUserToken] = useState(JSON.parse(sessionStorage.getItem("userToken"))); - const [isLogin, setIsLogin] = useState(JSON.parse(sessionStorage.getItem("isLogin"))); - const [userData, setUserData] = useState(null); + const [userToken, setUserToken] = useState(JSON.parse(sessionStorage.getItem("userToken"))); + const [isLogin, setIsLogin] = useState(JSON.parse(sessionStorage.getItem("isLogin"))); + const [userData, setUserData] = useState(JSON.parse(sessionStorage.getItem("userData"))); - const OnLogin = async (userEmail, userPw) => { - const res = await UsersLogin(userEmail, userPw); - console.log(res); - sessionStorage.setItem("isLogin", true); - setIsLogin(true); - alert("로그인 되었습니다!"); - }; + const OnLogin = async (userEmail, userPw) => { + const res = await UsersLogin(userEmail, userPw); + console.log(res); + if (res.data === "login failed") { + alert("이메일과 비밀번호를 다시 확인해주세요."); + } else { + setUserToken(res.data); + setUserData(JSON.parse(atob(res.data.split(".")[1]))); + sessionStorage.setItem("userData", JSON.stringify(atob(res.data.split(".")[1]))); + sessionStorage.setItem("userToken", JSON.stringify(res.data)); + sessionStorage.setItem("isLogin", true); + setIsLogin(true); + alert("로그인 되었습니다!"); + } + }; - const OnLogout = () => { - setUserToken(""); - window.location.reload(); - setIsLogin(false); - sessionStorage.removeItem("isLogin"); - alert("로그아웃 되었습니다!"); - }; + const OnLogout = () => { + setUserToken(""); + window.location.reload(); + setIsLogin(false); + sessionStorage.removeItem("isLogin"); + sessionStorage.removeItem("userData"); + sessionStorage.removeItem("userToken"); + alert("로그아웃 되었습니다!"); + }; - const OnRegister = async (email, userPW, userNN) => { - const res = await UsersSignup(email, userPW, userNN) - .then(alert(`회원가입이 완료되었습니다`)) - .catch((e) => alert(e)); - console.log(res); - }; + const OnRegister = async (email, userPW, userNN) => { + const res = await UsersSignup(email, userPW, userNN) + .then(alert(`회원가입이 완료되었습니다`)) + .catch((e) => alert(e)); + console.log(res); + }; - const OnDupNNCheck = async (userNN) => { - const res = await UsersCheckDuplicate(userNN) - .then((res) => { - console.log(res.data); - return res.data; - }) - .catch((e) => alert(e)); + const OnDupNNCheck = async (userNN) => { + const res = await UsersCheckDuplicate(userNN) + .then((res) => { + console.log(res.data); + return res.data; + }) + .catch((e) => alert(e)); - return res; - }; + return res; + }; - const OnEmailVerifySend = async (email) => { - const res = await PostSendVerifyEmail(email) - .then((res) => { - console.log(res.data); - alert(res.data); + const OnEmailVerifySend = async (email) => { + const res = await PostSendVerifyEmail(email) + .then((res) => { + console.log(res.data); + alert(res.data); + return res; + }) + .catch((e) => alert(e)); return res; - }) - .catch((e) => alert(e)); - return res; - }; - const OnEmailVerify = async (email, code) => { - const res = await PostVerifyEmail(email, code) - .then((res) => { - console.log(res); - alert(res.data); - if (res.data == "Email is Verified Successfully") { - return true; - } else return false; - }) - .catch((e) => alert(e)); - return res; - }; - return ( - - {children} - - ); + }; + const OnEmailVerify = async (email, code) => { + const res = await PostVerifyEmail(email, code) + .then((res) => { + console.log(res); + alert(res.data); + if (res.data == "Email is Verified Successfully") { + return true; + } else return false; + }) + .catch((e) => alert(e)); + return res; + }; + + const OnGHLogin = async (accessToken) => { + try { + const ghEmail = await GetEmailWithGHToken(accessToken); + console.log(ghEmail); + if (ghEmail === null) { + alert("이메일을 알 수 없는 깃허브 계정입니다"); + } + const emailCheck = await PermitAllEmailLogin(ghEmail); + console.log(emailCheck); + const res = emailCheck.data.split(" "); + if (res[0] === "email") { + alert("회원가입창으로 이동합니다 닉네임을 설정해주세요!"); + console.log("email"); + return { type: "email", result: res[1] }; + } else { + console.log("jwt : ", res[1]); + setUserToken(res[1]); + setUserData(JSON.parse(atob(res[1].split(".")[1]))); + sessionStorage.setItem("userData", JSON.stringify(atob(res[1].split(".")[1]))); + sessionStorage.setItem("userToken", JSON.stringify(res[1])); + sessionStorage.setItem("isLogin", true); + setIsLogin(true); + alert("로그인 되었습니다!"); + return { type: "jwt", result: res[1] }; + } + } catch {} + }; + return ( + + {children} + + ); }; diff --git a/src/service/authentication/authentication.service.tsx b/src/service/authentication/authentication.service.tsx index 7e385c3..f8619a6 100644 --- a/src/service/authentication/authentication.service.tsx +++ b/src/service/authentication/authentication.service.tsx @@ -1,100 +1,119 @@ import axios, { AxiosError, AxiosResponse } from "axios"; -const CLIENT_ID = process.env.REACT_APP_CLIENT_ID; -const USER_API_URL = process.env.REACT_APP_USER_API_URL; - -// 깃허브 로그인창으로 다이렉트 해주는 함수 -export const GitHubLoginRequestHandler = () => { - // TODO: GitHub로부터 사용자 인증을 위해 GitHub로 이동해야 합니다. 적절한 URL을 입력하세요. - // OAuth 인증이 완료되면 authorization code와 함께 callback url로 리디렉션 합니다. - return window.location.assign(`https://github.com/login/oauth/authorize?client_id=${CLIENT_ID}`); - //로그인 요청을 보내면 github auth server에서 redirect 로 callback, 그리고 auth code를 전달 -}; +const API_URL = process.env.REACT_APP_ALOG_API_URL; // EMAIL export const PostVerifyEmail = (email: string, code: string) => { - const verifyData = { - email: email, - code: code, - }; - console.log(verifyData); - const signUpResult: Promise = axios - .post(`${USER_API_URL}/api/users/emails/verify`, verifyData) - .then((res: AxiosResponse) => { - return res; - }) - .catch((err: AxiosError) => { - throw err; - }); - return signUpResult; + const verifyData = { + email: email, + code: code, + }; + console.log(verifyData); + const signUpResult: Promise = axios + .post(`${API_URL}/api/users/permit-all/emails/verify`, verifyData) + .then((res: AxiosResponse) => { + return res; + }) + .catch((err: AxiosError) => { + throw err; + }); + return signUpResult; }; export const PostSendVerifyEmail = (email: string) => { - const emailString = email.replace("@", "%40"); - const sendResult: Promise = axios - .post(`${USER_API_URL}/api/users/emails/send?EmailTo=${emailString}`) - .then((res: AxiosResponse) => { - return res; - }) - .catch((err: AxiosError) => { - throw err; - }); - return sendResult; + const emailString = email.replace("@", "%40"); + const sendResult: Promise = axios + .post(`${API_URL}/api/users/permit-all/emails/send?EmailTo=${emailString}`) + .then((res: AxiosResponse) => { + return res; + }) + .catch((err: AxiosError) => { + throw err; + }); + return sendResult; }; // USER AUTH export const UsersSignup = (email: string, userPw: string, userNN: string) => { - const SignUpData = { - userPw: userPw, - userNN: userNN, - email: email, - }; - const signUpResult: Promise = axios - .post(`${USER_API_URL}/api/users/signup`, SignUpData) - .then((res: AxiosResponse) => { - return res; - }) - .catch((err: AxiosError) => { - throw err; - }); - return signUpResult; + const SignUpData = { + userPw: userPw, + userNN: userNN, + email: email, + }; + const signUpResult: Promise = axios + // .post(`${API_URL}/api/users/signup`, SignUpData) + .post(`${API_URL}/api/users/permit-all/signup`, SignUpData) + .then((res: AxiosResponse) => { + return res; + }) + .catch((err: AxiosError) => { + throw err; + }); + return signUpResult; }; export const UsersLogin = (userEmail: string, userPassword: string): Promise => { - const loginData = { - userEmail: userEmail, - userPw: userPassword, - }; + const loginData = { + userEmail: userEmail, + userPw: userPassword, + }; - const loginResult: Promise = axios - .post(`${USER_API_URL}/api/users/login`, loginData) - .then((res: AxiosResponse) => { - return res; - }) - .catch((err: AxiosError) => { - throw err; - }); - return loginResult; + const loginResult: Promise = axios + .post(`${API_URL}/auth/permit-all/login`, loginData) + .then((res: AxiosResponse) => { + return res; + }) + .catch((err: AxiosError) => { + throw err; + }); + return loginResult; }; export const UsersInfo = () => { - return null; + return null; }; export const UsersCheckDuplicate = (userNN: string) => { - const checkDupResult: Promise = axios - .get(`${USER_API_URL}/api/users/duplicated/${userNN}`) - .then((res: AxiosResponse) => { - return res; - }) - .catch((err: AxiosError) => { - throw err; - }); - return checkDupResult; + const checkDupResult: Promise = axios + .get(`${API_URL}/api/users/permit-all/duplicated/${userNN}`) + .then((res: AxiosResponse) => { + return res; + }) + .catch((err: AxiosError) => { + throw err; + }); + return checkDupResult; }; export const UsersDelete = () => { - return null; + return null; +}; + +export const GetEmailWithGHToken = (accessToken: string) => { + const res: Promise = axios + .get(`${API_URL}/auth/permit-all/github/access-token?accessToken=${accessToken}`) + .then((res: AxiosResponse) => { + return res.data; + }) + .catch((err: AxiosError) => { + throw err; + }); + return res; +}; +export const PermitAllEmailLogin = (email: string) => { + const params = { + email: email, + }; + const res = axios + .get(`${API_URL}/auth/permit-all/email-login`, { params }) + .then((response) => { + console.log(response); + return response; + }) + .catch((error) => { + console.error(error); + }); + return res; }; diff --git a/src/service/authentication/github.service.tsx b/src/service/authentication/github.service.tsx new file mode 100644 index 0000000..d9fd24c --- /dev/null +++ b/src/service/authentication/github.service.tsx @@ -0,0 +1,53 @@ +import React from "react"; +import axios from "axios"; + +const CLIENT_ID = process.env.REACT_APP_CLIENT_ID!; +const CLIENT_SECRET = process.env.REACT_APP_CLIENT_SECRET!; + +const GITHUB_AUTH_CODE_SERVER = "/login/oauth/authorize"; +const GITHUB_AUTH_TOKEN_SERVER = "/login/oauth/access_token"; +const GITHUB_API_SERVER = "/user"; + +// 깃허브 로그인창으로 다이렉트 해주는 함수 +export const GitHubLoginRequestHandler = () => { + // TODO: GitHub로부터 사용자 인증을 위해 GitHub로 이동해야 합니다. 적절한 URL을 입력하세요. + // OAuth 인증이 완료되면 authorization code와 함께 callback url로 리디렉션 합니다. + return window.location.assign(`https://github.com/login/oauth/authorize?client_id=${CLIENT_ID}`); + //로그인 요청을 보내면 github auth server에서 redirect 로 callback, 그리고 auth code를 전달 +}; + +export const GithubAuth = async (code: string) => { + console.log(code); + const clientId = CLIENT_ID; + const clientSecret = CLIENT_SECRET; + + const body = new URLSearchParams({ + client_id: clientId, + client_secret: clientSecret, + code: code, + }); + + // 요청 헤더를 설정합니다. + const headers = { + Accept: "application/json", + "Content-Type": "application/x-www-form-urlencoded", + }; + + // axios.post 메소드를 사용하여 요청을 보냅니다. + const res = await axios + .post(`${GITHUB_AUTH_TOKEN_SERVER}`, body, { headers: headers }) + .then((response) => { + // 응답을 로그로 출력합니다. + console.log("response : ", response.data); + // 응답 데이터에서 access_token을 추출합니다. + const accessToken = response.data.access_token; + // 필요한 경우 추가 로직을 여기에 추가할 수 있습니다. + + return accessToken; + }) + .catch((error) => { + // 에러를 로그로 출력합니다. + console.error("error : ", error.message); + }); + return res; +}; diff --git a/src/setupProxy.js b/src/setupProxy.js new file mode 100644 index 0000000..4257182 --- /dev/null +++ b/src/setupProxy.js @@ -0,0 +1,18 @@ +const { createProxyMiddleware } = require("http-proxy-middleware"); + +// src/setupProxy.js + +module.exports = function (app) { + app.use( + createProxyMiddleware("/login", { + target: "https://github.com", + changeOrigin: true, + }) + ); + app.use( + createProxyMiddleware("/user", { + target: "https://api.github.com", + changeOrigin: true, + }) + ); +}; diff --git a/tsconfig.json b/tsconfig.json index 9d379a3..139d543 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,4 +1,24 @@ { +<<<<<<< HEAD + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx" + }, + "include": ["src"] +======= "compilerOptions": { "target": "es5", "lib": ["dom", "dom.iterable", "esnext"], @@ -17,4 +37,5 @@ "jsx": "react-jsx" }, "include": ["src"] +>>>>>>> 00b1bc3285f2d374a1b302a09a08a7d7255b3b16 }