Skip to content

Commit

Permalink
[BBB-137] ✨Feat: 회원가입 진행 시 종단간 암호화 적용
Browse files Browse the repository at this point in the history
  • Loading branch information
platinouss committed Oct 17, 2024
1 parent 69826e4 commit 9cbba5a
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 21 deletions.
45 changes: 44 additions & 1 deletion app/users/signup/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,59 @@
'use client';

import SignupForm from '@/components/users/signup/signup-form';
import { useEffect, useState } from 'react';
import { PublicKeyInfo } from '@/types/encryption/public-key-info';
import { getPublicKeyInfo } from '@/components/encryption/getPublicKeyInfo';
import { toast } from 'react-toastify';
import { handleEncryptedSignup } from '@/components/encryption/encryptionSignup';

export default function Signup() {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [baekjoonId, setBaekjoonId] = useState('');
const [introduce, setIntroduce] = useState('');
const [publicKeyInfo, setPublicKeyInfo] = useState<PublicKeyInfo | null>(
null
);

useEffect(() => {
try {
getPublicKeyInfo(setPublicKeyInfo).then(() => {
if (publicKeyInfo != null && username != '' && password != '') {
handleEncryptedSignup(
{ username, password, baekjoonId, introduce },
publicKeyInfo
);
}
});
} catch (error) {
toast.error((error as Error).message);
}
}, []);

const handleChangeSignupInfo = (
username: string,
password: string,
baekjoonId: string,
introduce: string
) => {
setUsername(username);
setPassword(password);
setBaekjoonId(baekjoonId);
setIntroduce(introduce);
};

return (
<div className="flex flex-col h-screen">
<main className="flex-1 flex justify-center items-center bg-gray-100 dark:bg-gray-50">
<div className="bg-white dark:bg-white rounded-lg shadow-lg p-8 w-full max-w-md">
<h1 className="text-black text-2xl font-bold mb-6 text-center">
회원가입
</h1>
<SignupForm />
<SignupForm
publicKeyInfo={publicKeyInfo}
handleChangeSignupInfo={() => handleChangeSignupInfo}
/>
</div>
</main>
</div>
Expand Down
11 changes: 11 additions & 0 deletions components/encryption/encryptionSignup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { PublicKeyInfo } from '@/types/encryption/public-key-info';
import { encryptData } from '@/components/encryption/getPublicKeyInfo';
import { signup } from '@/lib/api/users/signup';

export const handleEncryptedSignup = async (
signupInfo: Record<string, string>,
publicKeyInfo: PublicKeyInfo
) => {
const encryptedData = encryptData(signupInfo, publicKeyInfo);
return await signup(publicKeyInfo.id, publicKeyInfo.version, encryptedData);
};
32 changes: 24 additions & 8 deletions components/users/signup/signup-form.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
'use client';

import { Button } from '@/components/ui/button/button';
import { Input } from '@/components/ui/input/input';
import { Textarea } from '@/components/ui/textarea/textarea';
import { signup } from '@/lib/api/users/signup';
import { zodResolver } from '@hookform/resolvers/zod';
import { useRouter } from 'next/navigation';
import { FieldValues, useForm } from 'react-hook-form';
import { toast } from 'react-toastify';
import { z } from 'zod';
import { handleEncryptedSignup } from '@/components/encryption/encryptionSignup';
import { SignupFormProps } from '@/types/user/signup-form-props';

export default function SignupForm() {
export default function SignupForm({
publicKeyInfo,
handleChangeSignupInfo
}: SignupFormProps) {
const router = useRouter();
const signupSchema = z
.object({
Expand Down Expand Up @@ -39,10 +41,24 @@ export default function SignupForm() {
});

const onSubmit = async (data: FieldValues) => {
const response = await signup(data);
if (response.status === 200) {
toast.success('회원가입이 완료되었습니다.');
router.push('/login');
try {
handleChangeSignupInfo(
data.username,
data.password,
data.baekjoonId,
data.introduce
);
if (publicKeyInfo == null) {
toast.error('로그인 진행 중입니다. 잠시만 기다려주세요.');
return;
}
const response = await handleEncryptedSignup(data, publicKeyInfo);
if (response.status === 200) {
toast.success('회원가입이 완료되었습니다.');
router.push('/login');
}
} catch (error) {
toast.error((error as Error).message);
}
};

Expand Down
39 changes: 27 additions & 12 deletions lib/api/users/signup.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
import axios from 'axios';
import { FieldValues } from 'react-hook-form';
import axios, { AxiosError } from 'axios';

/**
* 회원가입 API
* body : username, password, baekjoonId, introduce
*/
export async function signup({
username,
password,
baekjoonId,
introduce
}: FieldValues) {
return await axios.post(
`${process.env.NEXT_PUBLIC_API_SERVER_URL}/api/v1/users/signup`,
{ username, password, baekjoonId, introduce }
);
export async function signup(
id: number,
version: number,
encryptedData: string
) {
try {
return await axios.post(
`${process.env.NEXT_PUBLIC_API_SERVER_URL}/api/v1/users/signup`,
{
id,
version,
encryptedData
},
{
headers: {
'Content-Type': 'application/json'
}
}
);
} catch (error) {
const axiosError = error as AxiosError;
if (axiosError.response?.status === 409) {
throw new Error('이미 존재하는 아이디입니다.');
}
throw new Error('회원가입에 실패했습니다.');
}
}
11 changes: 11 additions & 0 deletions types/user/signup-form-props.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { PublicKeyInfo } from '@/types/encryption/public-key-info';

export interface SignupFormProps {
publicKeyInfo: PublicKeyInfo | null;
handleChangeSignupInfo: (
username: string,
password: string,
baekjoonId: string,
introduce: string
) => void;
}

0 comments on commit 9cbba5a

Please sign in to comment.