diff --git a/.gitignore b/.gitignore index fd3dbb57..2615d450 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,8 @@ npm-debug.log* yarn-debug.log* yarn-error.log* +# env file +.env # local env files .env*.local diff --git a/package.json b/package.json index 4b7cd350..6727f2b3 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@tanstack/react-query-devtools": "^5.48.0", "@types/react-beautiful-dnd": "^13.1.8", "axios": "^1.7.2", + "js-sha256": "^0.11.0", "lodash": "^4.17.21", "next": "14.2.4", "react": "^18", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 52958cf3..1bb37783 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,9 @@ importers: axios: specifier: ^1.7.2 version: 1.7.2 + js-sha256: + specifier: ^0.11.0 + version: 0.11.0 lodash: specifier: ^4.17.21 version: 4.17.21 @@ -1482,6 +1485,9 @@ packages: resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} hasBin: true + js-sha256@0.11.0: + resolution: {integrity: sha512-6xNlKayMZvds9h1Y1VWc0fQHQ82BxTXizWPEtEeGvmOUYpBRy4gbWroHLpzowe6xiQhHpelCQiE7HEdznyBL9Q==} + js-sha3@0.8.0: resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} @@ -4046,6 +4052,8 @@ snapshots: jiti@1.21.6: {} + js-sha256@0.11.0: {} + js-sha3@0.8.0: {} js-tokens@4.0.0: {} diff --git a/src/containers/mypage/PwdChangeForm.tsx b/src/containers/mypage/PwdChangeForm.tsx index 88ef096b..7ff0c945 100644 --- a/src/containers/mypage/PwdChangeForm.tsx +++ b/src/containers/mypage/PwdChangeForm.tsx @@ -4,6 +4,7 @@ import { ChangeEvent, FormEventHandler, useState } from 'react'; import ActionButton from '@/components/Button/ActionButton'; import PwdInput from '@/components/Input/PwdInput'; import { putPassword } from '@/services/putService'; +import hashPassword from '@/utils/hashPassword'; interface PasswordChangeForm { password: string; @@ -78,7 +79,7 @@ export default function PwdChangeForm() { const putData = async () => { const { password, newPassword } = inputData; try { - await putPassword({ password, newPassword }); + await putPassword({ password: hashPassword(password), newPassword: hashPassword(newPassword) }); // NOTE: 전체 페이지 리로드보다 시간이 훨씬 적게 걸려서 값만 비우도록 했습니다. setInputData(INITIAL_INPUT_DATA); alert('비밀번호가 변경되었습니다.'); diff --git a/src/containers/signin&signup/SignInForm.tsx b/src/containers/signin&signup/SignInForm.tsx index afc6b29b..9c2ce793 100644 --- a/src/containers/signin&signup/SignInForm.tsx +++ b/src/containers/signin&signup/SignInForm.tsx @@ -10,6 +10,7 @@ import TextInputWithLabel from '@/containers/signin&signup/TextInputWithLabel'; import useModal from '@/hooks/useModal'; import { useSignIn } from '@/hooks/useSignIn'; import { setError } from '@/store/reducers/userSlice'; +import hashPassword from '@/utils/hashPassword'; export type TSignInInputs = { email: string; @@ -37,21 +38,25 @@ export default function SignInForm() { const { openNotificationModal } = useModal(); const onSubmit = (data: TSignInInputs) => { - mutation.mutate(data, { - onSuccess: () => { - router.push('/mydashboard'); // 로그인 성공 시 리다이렉트 + const { email, password } = data; + mutation.mutate( + { email, password: hashPassword(password) }, + { + onSuccess: () => { + router.push('/mydashboard'); // 로그인 성공 시 리다이렉트 + }, + onError: (error) => { + if (error instanceof AxiosError) { + dispatch(setError(error.response?.data.message)); + openNotificationModal({ text: error.response?.data.message }); + } else { + const unknownError = '알 수 없는 오류가 발생했습니다.'; + dispatch(setError(unknownError)); + openNotificationModal({ text: unknownError }); + } + }, }, - onError: (error) => { - if (error instanceof AxiosError) { - dispatch(setError(error.response?.data.message)); - openNotificationModal({ text: error.response?.data.message }); - } else { - const unknownError = '알 수 없는 오류가 발생했습니다.'; - dispatch(setError(unknownError)); - openNotificationModal({ text: unknownError }); - } - }, - }); + ); }; return ( diff --git a/src/containers/signin&signup/SignUpForm.tsx b/src/containers/signin&signup/SignUpForm.tsx index ff18c98d..5f7f18a6 100644 --- a/src/containers/signin&signup/SignUpForm.tsx +++ b/src/containers/signin&signup/SignUpForm.tsx @@ -9,6 +9,7 @@ import PwdInputWithLabel from '@/containers/signin&signup/PwdInputWithLabel'; import TextInputWithLabel from '@/containers/signin&signup/TextInputWithLabel'; import useModal from '@/hooks/useModal'; import { postSignUp } from '@/services/postService'; +import hashPassword from '@/utils/hashPassword'; export type TSignUpInputs = { email: string; @@ -54,8 +55,9 @@ export default function SignUpForm() { }; const onSubmit = async (data: TSignUpInputs) => { + const { password } = data; try { - await postSignUp(data); + await postSignUp({ ...data, password: hashPassword(password) }); openNotificationModal({ text: '가입이 완료되었습니다!', onClick: handleSignUpSuccess }); } catch (error) { if (error instanceof AxiosError && error.response?.status === 409) { diff --git a/src/utils/hashPassword.ts b/src/utils/hashPassword.ts new file mode 100644 index 00000000..3acca716 --- /dev/null +++ b/src/utils/hashPassword.ts @@ -0,0 +1,8 @@ +import { sha256 } from 'js-sha256'; + +const hashPassword = (password: string) => { + const key = String(process.env.NEXT_PUBLIC_SHA256_KEY); + return sha256.hmac(key, password); +}; + +export default hashPassword;