From cad6fb6966c2a53c5dcf3bbc9fe43da19cd3670a Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Mon, 26 Aug 2024 05:05:45 +0000 Subject: [PATCH 01/18] chore: Update npm dependencies --- package-lock.json | 21 +++++++++++++++++++++ package.json | 1 + 2 files changed, 22 insertions(+) diff --git a/package-lock.json b/package-lock.json index 7eb16d7a..3854fdda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "express": "^4.18.2", + "fetch-ax": "^1.0.2", "jotai": "^2.7.0", "lucide-react": "^0.336.0", "next": "14.1.0", @@ -12757,6 +12758,26 @@ "pend": "~1.2.0" } }, + "node_modules/fetch-ax": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fetch-ax/-/fetch-ax-1.0.2.tgz", + "integrity": "sha512-9KsPTg3oXVJXgFrJaArl9PAMo5JIXNPiCLWDwav/7KcHbGctWZ13lvm/MIQ6e7/tukOu+4zWIkDrBi/Uu9VyhA==", + "dependencies": { + "typescript": "^5.4.5" + } + }, + "node_modules/fetch-ax/node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/fetch-retry": { "version": "5.0.6", "resolved": "https://registry.npmjs.org/fetch-retry/-/fetch-retry-5.0.6.tgz", diff --git a/package.json b/package.json index 68e0cc1b..8bde7e32 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "express": "^4.18.2", + "fetch-ax": "^1.0.2", "jotai": "^2.7.0", "lucide-react": "^0.336.0", "next": "14.1.0", From 27a90c52645dbb038637a468e3fd5ccabef149d8 Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Sat, 7 Sep 2024 04:02:49 +0000 Subject: [PATCH 02/18] chore: Update fetch-ax dependency to version 1.0.4 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3854fdda..a00f9ccf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "express": "^4.18.2", - "fetch-ax": "^1.0.2", + "fetch-ax": "^1.0.4", "jotai": "^2.7.0", "lucide-react": "^0.336.0", "next": "14.1.0", @@ -12759,9 +12759,9 @@ } }, "node_modules/fetch-ax": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/fetch-ax/-/fetch-ax-1.0.2.tgz", - "integrity": "sha512-9KsPTg3oXVJXgFrJaArl9PAMo5JIXNPiCLWDwav/7KcHbGctWZ13lvm/MIQ6e7/tukOu+4zWIkDrBi/Uu9VyhA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/fetch-ax/-/fetch-ax-1.0.4.tgz", + "integrity": "sha512-wyqnuyiQblC6gkzf7SL0XcodpX4CL84QsX2XRrZsj5ltXN2FZ5et2GzRXxF2d+ahJd2AirMsAZTeTmu49jC17A==", "dependencies": { "typescript": "^5.4.5" } diff --git a/package.json b/package.json index 8bde7e32..2afc73e5 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "express": "^4.18.2", - "fetch-ax": "^1.0.2", + "fetch-ax": "^1.0.4", "jotai": "^2.7.0", "lucide-react": "^0.336.0", "next": "14.1.0", From f3e2475f9e06f92b72294af88714af23b8724461 Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Sun, 22 Sep 2024 08:59:16 +0000 Subject: [PATCH 03/18] chore: update fetch-ax dependency to version 1.0.10 --- package-lock.json | 23 ++++------------------- package.json | 2 +- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index a00f9ccf..508228b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "express": "^4.18.2", - "fetch-ax": "^1.0.4", + "fetch-ax": "^1.0.10", "jotai": "^2.7.0", "lucide-react": "^0.336.0", "next": "14.1.0", @@ -12759,24 +12759,9 @@ } }, "node_modules/fetch-ax": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/fetch-ax/-/fetch-ax-1.0.4.tgz", - "integrity": "sha512-wyqnuyiQblC6gkzf7SL0XcodpX4CL84QsX2XRrZsj5ltXN2FZ5et2GzRXxF2d+ahJd2AirMsAZTeTmu49jC17A==", - "dependencies": { - "typescript": "^5.4.5" - } - }, - "node_modules/fetch-ax/node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fetch-ax/-/fetch-ax-1.0.10.tgz", + "integrity": "sha512-9qXCkrOBDDNodVQmZJFQ3b3A3J6OMr6XFFQXgFuXiwEmcifxZPx2GR80++OVbF7M5EjkgQnZYiiwDOsYHuBoXQ==" }, "node_modules/fetch-retry": { "version": "5.0.6", diff --git a/package.json b/package.json index 2afc73e5..66ab23e6 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "express": "^4.18.2", - "fetch-ax": "^1.0.4", + "fetch-ax": "^1.0.10", "jotai": "^2.7.0", "lucide-react": "^0.336.0", "next": "14.1.0", From 9c4268e2a7c23c832858e1b8240d5fc94f2ec461 Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Sun, 22 Sep 2024 09:03:38 +0000 Subject: [PATCH 04/18] =?UTF-8?q?feat:=20fetchAx=20=EC=A0=84=EC=9A=A9=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=ED=95=B8=EB=93=A4=EB=9F=AC=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/utils/http/http-error-handler.ts | 46 ++++++++++++++++++++++++++++ app/utils/http/http-error.ts | 4 +-- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/app/utils/http/http-error-handler.ts b/app/utils/http/http-error-handler.ts index 3a86eef4..5f3a5a46 100644 --- a/app/utils/http/http-error-handler.ts +++ b/app/utils/http/http-error-handler.ts @@ -7,6 +7,7 @@ import { UnauthorizedError, InternetServerError, } from './http-error'; +import { FetchAxError } from 'fetch-ax'; export interface ErrorResponseData { status: number; @@ -54,3 +55,48 @@ export const httpErrorHandler = (response: Response, result: ErrorResponseData) } } }; + +interface ErrorData { + errorCode: string; +} + +export const fetchAxErrorHandler = (error: FetchAxError) => { + const status = error.statusCode; + const message = error.response.data.errorCode; // 여기서 errorcode를 message로 변환 필요 + const response = error.response; + + switch (status) { + case HttpStatusCode.Unauthorized: + throw new UnauthorizedError({ + message, + response, + }); + + case HttpStatusCode.BadRequest: + throw new BadRequestError({ + message, + response, + }); + + case HttpStatusCode.Forbidden: + throw new ForbiddenError({ + message, + response, + }); + + case HttpStatusCode.NotFound: + throw new NotFoundError({ + message, + response, + }); + + case HttpStatusCode.InternalServerError: + throw new InternetServerError({ + message, + response, + }); + + default: + throw new HttpError(status, message, response); + } +}; diff --git a/app/utils/http/http-error.ts b/app/utils/http/http-error.ts index a605703a..31fec692 100644 --- a/app/utils/http/http-error.ts +++ b/app/utils/http/http-error.ts @@ -1,7 +1,7 @@ type ErrorConstrutor = { message?: string; statusCode?: number; - response?: Response; + response?: Partial; }; // Refactor: fetch가 NetworkError랑 TimeoutError 또 자동으로 에러로 던져서 처리가 더 애매하다. @@ -23,7 +23,7 @@ export class HttpError extends Error { constructor( readonly statusCode?: number, message?: string, - readonly response?: Response, + readonly response?: Partial, ) { super(message); } From d43f21fafa47fff54c55770d07f488766d6f7afc Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Sun, 22 Sep 2024 09:04:13 +0000 Subject: [PATCH 05/18] =?UTF-8?q?fix:=20=ED=95=9C=EA=B8=80=20=EB=A9=94?= =?UTF-8?q?=EC=8B=9C=EC=A7=80=20=EC=82=AC=EC=9A=A9=20=EC=8B=9C=20=EA=B0=84?= =?UTF-8?q?=ED=98=88=EC=A0=81=EC=9C=BC=EB=A1=9C=20=ED=97=88=EC=8A=A4?= =?UTF-8?q?=ED=82=A4=EC=97=90=EC=84=9C=20=EC=97=90=EB=9F=AC=EA=B0=80=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=ED=95=98=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .husky/prepare-commit-msg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.husky/prepare-commit-msg b/.husky/prepare-commit-msg index 9b8879a1..6af55186 100755 --- a/.husky/prepare-commit-msg +++ b/.husky/prepare-commit-msg @@ -5,7 +5,7 @@ commit_msg_file=$1 commit_msg=$(cat "$1") second_line=$(echo "$commit_msg" | sed -n '2p') -commit_msg_title_regex='(feat|fix|refactor|chore|test|docs|style|rename|setting|remove|build): .{1,100}?$' +commit_msg_title_regex='(feat|fix|refactor|chore|test|docs|style|rename|setting|remove|build): .{1,100}?' # 제목 From aca8d064eeb608317177a885f5f88291dc4246bc Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Sun, 22 Sep 2024 09:06:19 +0000 Subject: [PATCH 06/18] =?UTF-8?q?feat:=20auth=20=EB=A1=9C=EC=A7=81=20fetch?= =?UTF-8?q?-ax=EB=A1=9C=20=EA=B5=90=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/business/services/user/user.command.ts | 31 ++++++++++------------ 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/app/business/services/user/user.command.ts b/app/business/services/user/user.command.ts index 38c46841..03a6033b 100644 --- a/app/business/services/user/user.command.ts +++ b/app/business/services/user/user.command.ts @@ -9,7 +9,7 @@ import { UserDeleteRequestBody, ResetPasswordRequestBody, } from './user.type'; -import { httpErrorHandler } from '@/app/utils/http/http-error-handler'; +import { fetchAxErrorHandler, httpErrorHandler } from '@/app/utils/http/http-error-handler'; import { BadRequestError, UnauthorizedError } from '@/app/utils/http/http-error'; import { SignUpFormSchema, @@ -21,7 +21,17 @@ import { import { cookies } from 'next/headers'; import { isValidation } from '@/app/utils/zod/validation.util'; import { redirect } from 'next/navigation'; -import { auth } from './user.query'; +import fetchAx, { FetchAxError } from 'fetch-ax'; + +const instance = fetchAx.create({ + headers: { + 'Content-Type': 'application/json', + // Authorization: `Bearer ${cookies().get('accessToken')?.value}`, 서버라서 안되지 않을까? 공유 인스턴스 처럼.. 근데 그러면 기존에는 어캐 디는거야> + }, + responseRejectedInterceptor: (error) => { + fetchAxErrorHandler(error); + }, +}); function deleteCookies() { cookies().delete('accessToken'); @@ -54,7 +64,6 @@ export async function deleteUser(prevState: FormState, formData: FormData): Prom httpErrorHandler(response, result); } } catch (error) { - console.log(error); if (error instanceof BadRequestError) { // 잘못된 요청 처리 로직 return { @@ -90,19 +99,8 @@ export async function authenticate(prevState: FormState, formData: FormData): Pr const body: SignInRequestBody = { ...validatedFields.data, }; - try { - const response = await fetch(`${API_PATH.auth}/sign-in`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(body), - }); - - const result = await response.json(); - - httpErrorHandler(response, result); + const result = await instance.post(`${API_PATH.auth}/sign-in`, body); if (isValidation(result, SignInResponseSchema)) { cookies().set('accessToken', result.accessToken, { @@ -117,8 +115,7 @@ export async function authenticate(prevState: FormState, formData: FormData): Pr }); } } catch (error) { - // 명세와 다르게 에러가 발생할 경우 BadRequestError가 아니라 UnauthorizedError가 발생 - if (error instanceof UnauthorizedError) { + if (error instanceof UnauthorizedError || error instanceof BadRequestError) { // 잘못된 요청 처리 로직 return { isSuccess: false, From 8dcf8064d87674c407fbf0bb5ffd7e8c39916fbb Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Sun, 22 Sep 2024 09:10:23 +0000 Subject: [PATCH 07/18] =?UTF-8?q?feat:=20fetch-ax=20instance=EB=A5=BC=20?= =?UTF-8?q?=EC=83=88=EB=A1=9C=EC=9A=B4=20=ED=8C=8C=EC=9D=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/business/services/user/user.command.ts | 14 ++------------ app/utils/http/instance.ts | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 12 deletions(-) create mode 100644 app/utils/http/instance.ts diff --git a/app/business/services/user/user.command.ts b/app/business/services/user/user.command.ts index 03a6033b..5828c947 100644 --- a/app/business/services/user/user.command.ts +++ b/app/business/services/user/user.command.ts @@ -9,7 +9,7 @@ import { UserDeleteRequestBody, ResetPasswordRequestBody, } from './user.type'; -import { fetchAxErrorHandler, httpErrorHandler } from '@/app/utils/http/http-error-handler'; +import { httpErrorHandler } from '@/app/utils/http/http-error-handler'; import { BadRequestError, UnauthorizedError } from '@/app/utils/http/http-error'; import { SignUpFormSchema, @@ -21,17 +21,7 @@ import { import { cookies } from 'next/headers'; import { isValidation } from '@/app/utils/zod/validation.util'; import { redirect } from 'next/navigation'; -import fetchAx, { FetchAxError } from 'fetch-ax'; - -const instance = fetchAx.create({ - headers: { - 'Content-Type': 'application/json', - // Authorization: `Bearer ${cookies().get('accessToken')?.value}`, 서버라서 안되지 않을까? 공유 인스턴스 처럼.. 근데 그러면 기존에는 어캐 디는거야> - }, - responseRejectedInterceptor: (error) => { - fetchAxErrorHandler(error); - }, -}); +import { instance } from '@/app/utils/http/instance'; function deleteCookies() { cookies().delete('accessToken'); diff --git a/app/utils/http/instance.ts b/app/utils/http/instance.ts new file mode 100644 index 00000000..ec3ebf19 --- /dev/null +++ b/app/utils/http/instance.ts @@ -0,0 +1,21 @@ +import fetchAx, { FetchAxError } from 'fetch-ax'; +import { fetchAxErrorHandler } from './http-error-handler'; +import { cookies } from 'next/headers'; + +export const instance = fetchAx.create({ + headers: { + 'Content-Type': 'application/json', + // Authorization: `Bearer ${cookies().get('accessToken')?.value}`, 서버라서 안되지 않을까? 공유 인스턴스 처럼.. 근데 그러면 기존에는 어캐 디는거야> + }, + responseRejectedInterceptor: (error) => { + fetchAxErrorHandler(error); + }, + requestInterceptor: (config) => { + const accessToken = cookies().get('accessToken')?.value; + // if (accessToken) { + // config.headers; + // } + console.log(accessToken); + return config; + }, +}); From 3763599b474e6f504415d225dac5b30a7bbd4839 Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Sun, 22 Sep 2024 10:53:04 +0000 Subject: [PATCH 08/18] =?UTF-8?q?fix:=20fetch-ax=EC=9D=98=20data=EB=A5=BC?= =?UTF-8?q?=20=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/business/services/user/user.command.ts | 8 ++++---- app/utils/api/setup-url.util.ts | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/business/services/user/user.command.ts b/app/business/services/user/user.command.ts index 5828c947..04a5c9a9 100644 --- a/app/business/services/user/user.command.ts +++ b/app/business/services/user/user.command.ts @@ -90,15 +90,15 @@ export async function authenticate(prevState: FormState, formData: FormData): Pr ...validatedFields.data, }; try { - const result = await instance.post(`${API_PATH.auth}/sign-in`, body); + const { data } = await instance.post(`${API_PATH.auth}/sign-in`, body); - if (isValidation(result, SignInResponseSchema)) { - cookies().set('accessToken', result.accessToken, { + if (isValidation(data, SignInResponseSchema)) { + cookies().set('accessToken', data.accessToken, { httpOnly: true, secure: process.env.NODE_ENV === 'production', path: '/', }); - cookies().set('refreshToken', result.refreshToken, { + cookies().set('refreshToken', data.refreshToken, { httpOnly: true, secure: process.env.NODE_ENV === 'production', path: '/', diff --git a/app/utils/api/setup-url.util.ts b/app/utils/api/setup-url.util.ts index f990052b..1bd67792 100644 --- a/app/utils/api/setup-url.util.ts +++ b/app/utils/api/setup-url.util.ts @@ -1,6 +1,6 @@ const API_URLS = { - BASE_URL: process.env.NEXT_PUBLIC_API_PATH ?? "", - PARSE_API_URL: process.env.NEXT_PUBLIC_PARSE_API_PATH ?? "", + BASE_URL: process.env.NEXT_PUBLIC_API_PATH ?? 'http://localhost:9090', + PARSE_API_URL: process.env.NEXT_PUBLIC_PARSE_API_PATH ?? 'http://localhost:9090/parsePDFtoText', }; const MOCK_API_URLS = { From 2c3ef24d5343adba388e45ffd8da25d62c1f5fd2 Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Sun, 22 Sep 2024 10:53:50 +0000 Subject: [PATCH 09/18] =?UTF-8?q?feat:=20fetch-ax=20instance=EC=97=90=20?= =?UTF-8?q?=EC=9D=B8=ED=84=B0=EC=85=89=ED=84=B0=EB=A1=9C=20cookie=EB=A5=BC?= =?UTF-8?q?=20=EA=B0=80=EC=A0=B8=EC=98=A4=EB=8F=84=EB=A1=9D=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/utils/http/instance.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/utils/http/instance.ts b/app/utils/http/instance.ts index ec3ebf19..910c73d5 100644 --- a/app/utils/http/instance.ts +++ b/app/utils/http/instance.ts @@ -5,17 +5,18 @@ import { cookies } from 'next/headers'; export const instance = fetchAx.create({ headers: { 'Content-Type': 'application/json', - // Authorization: `Bearer ${cookies().get('accessToken')?.value}`, 서버라서 안되지 않을까? 공유 인스턴스 처럼.. 근데 그러면 기존에는 어캐 디는거야> }, responseRejectedInterceptor: (error) => { fetchAxErrorHandler(error); }, requestInterceptor: (config) => { const accessToken = cookies().get('accessToken')?.value; - // if (accessToken) { - // config.headers; - // } - console.log(accessToken); + if (accessToken) { + config.headers = { + ...config.headers, + Authorization: `Bearer ${accessToken}`, + }; + } return config; }, }); From d1118cbc8bf38a2622023ede772e822665dbca95 Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Sun, 22 Sep 2024 10:54:27 +0000 Subject: [PATCH 10/18] =?UTF-8?q?feat:=20fetchUser=EB=A5=BC=20fetch-ax=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=A7=88?= =?UTF-8?q?=EC=9D=B4=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/business/services/user/user.query.ts | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/app/business/services/user/user.query.ts b/app/business/services/user/user.query.ts index 81ae96d1..fcb47867 100644 --- a/app/business/services/user/user.query.ts +++ b/app/business/services/user/user.query.ts @@ -1,9 +1,7 @@ 'use server'; import { BadRequestError, UnauthorizedError } from '@/app/utils/http/http-error'; -import { httpErrorHandler } from '@/app/utils/http/http-error-handler'; import { isValidation } from '@/app/utils/zod/validation.util'; -import { cookies } from 'next/headers'; import { API_PATH } from '../../api-path'; import { InitUserInfoResponse, UserInfoResponse } from './user.type'; import { @@ -13,6 +11,7 @@ import { FindIdResponseSchema, } from './user.validation'; import { FormState } from '@/app/ui/view/molecule/form/form-root'; +import { instance } from '@/app/utils/http/instance'; export async function auth(): Promise { try { @@ -28,17 +27,11 @@ export async function auth(): Promise { try { - const response = await fetch(`${API_PATH.user}/me`, { - headers: { - Authorization: `Bearer ${cookies().get('accessToken')?.value}`, - }, - }); - const result = await response.json(); - - httpErrorHandler(response, result); + console.log(`${API_PATH.user}/me`); + const { data } = await instance.get(`${API_PATH.user}/me`); - if (isValidation(result, UserInfoResponseSchema) || isValidation(result, InitUserInfoResponseSchema)) { - return result; + if (isValidation(data, UserInfoResponseSchema) || isValidation(data, InitUserInfoResponseSchema)) { + return data; } else { throw 'Invalid user info response schema.'; } From 43456407870f82daeeacb5361813241f53beb7ff Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Sun, 22 Sep 2024 11:02:18 +0000 Subject: [PATCH 11/18] =?UTF-8?q?feat:=20=EC=95=84=EC=9D=B4=EB=94=94=20?= =?UTF-8?q?=EC=B0=BE=EA=B8=B0=20fetch-ax=EB=A1=9C=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/business/services/user/user.query.ts | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/app/business/services/user/user.query.ts b/app/business/services/user/user.query.ts index e96b7e4f..4c8b7f9e 100644 --- a/app/business/services/user/user.query.ts +++ b/app/business/services/user/user.query.ts @@ -55,28 +55,22 @@ export async function findUserToStudentNumber(prevState: FormState, formData: Fo try { const { studentNumber } = validatedFields.data; - const response = await fetch(`${API_PATH.user}/${studentNumber}/auth-id`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - }); + const response = await instance.get(`${API_PATH.user}/${studentNumber}/auth-id`); - const result = await response.json(); if (response.status === 200) return { isSuccess: true, isFailure: false, validationError: {}, message: '', - value: result, + value: response.data, }; else return { isSuccess: false, isFailure: true, validationError: {}, - message: result.message, + message: response.data, }; } catch (error) { if (error instanceof BadRequestError) { From 89de6b66a1e5e1f992a46d257c770ae36b7a400e Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Sun, 22 Sep 2024 11:05:07 +0000 Subject: [PATCH 12/18] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20fetch-ax=EB=A1=9C=20=EB=A7=88?= =?UTF-8?q?=EC=9D=B4=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/business/services/user/user.query.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/app/business/services/user/user.query.ts b/app/business/services/user/user.query.ts index 4c8b7f9e..e1d96331 100644 --- a/app/business/services/user/user.query.ts +++ b/app/business/services/user/user.query.ts @@ -103,15 +103,9 @@ export async function validateUser(prevState: FormState, formData: FormData): Pr try { const { studentNumber, authId } = validatedFields.data; - const response = await fetch(`${API_PATH.user}/${studentNumber}/validate?auth-id=${authId}`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - }); - const result = await response.json(); + const { data } = await instance.get(`${API_PATH.user}/${studentNumber}/validate?auth-id=${authId}`); - if (result.passedUserValidation) + if (data.passedUserValidation) return { isSuccess: true, isFailure: false, From b16ec7dd0622129d5ee9683fd3b9c7ca82923dbe Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Sun, 22 Sep 2024 11:17:53 +0000 Subject: [PATCH 13/18] =?UTF-8?q?feat:=20ATK=20=EC=9E=AC=EC=9A=94=EC=B2=AD?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20fetch-ax=EB=A1=9C=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/business/services/user/user.command.ts | 25 +++++++++++----------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/app/business/services/user/user.command.ts b/app/business/services/user/user.command.ts index 70b6a6bb..14fc8a70 100644 --- a/app/business/services/user/user.command.ts +++ b/app/business/services/user/user.command.ts @@ -9,7 +9,7 @@ import { UserDeleteRequestBody, ResetPasswordRequestBody, } from './user.type'; -import { httpErrorHandler } from '@/app/utils/http/http-error-handler'; +import { fetchAxErrorHandler, httpErrorHandler } from '@/app/utils/http/http-error-handler'; import { BadRequestError, UnauthorizedError } from '@/app/utils/http/http-error'; import { SignUpFormSchema, @@ -24,6 +24,7 @@ import { isValidation } from '@/app/utils/zod/validation.util'; import { redirect } from 'next/navigation'; import { fetchUser } from './user.query'; import { instance } from '@/app/utils/http/instance'; +import fetchAX from 'fetch-ax'; function deleteCookies() { cookies().delete('accessToken'); @@ -142,20 +143,18 @@ export async function authenticate(prevState: FormState, formData: FormData): Pr export async function refreshToken(): Promise { const refreshToken = cookies().get('refreshToken')?.value; try { - const response = await fetch(`${API_PATH.auth}/token`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', + const { data } = await fetchAX.post( + `${API_PATH.auth}/token`, + { refreshToken }, + { + responseRejectedInterceptor: (error) => { + fetchAxErrorHandler(error); + }, }, - body: JSON.stringify({ refreshToken }), - }); - - const result = await response.json(); - - httpErrorHandler(response, result); + ); - if (isValidation(result, ValidateTokenResponseSchema)) { - return result; + if (isValidation(data, ValidateTokenResponseSchema)) { + return data; } else { throw 'Invalid token response schema.'; } From 7abd6bef0b4e8e1a97f070d45cbf32c66264a3ee Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Sun, 22 Sep 2024 11:25:44 +0000 Subject: [PATCH 14/18] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EB=A1=9C=EC=A7=81=20fetch-ax=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/business/services/user/user.command.ts | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/app/business/services/user/user.command.ts b/app/business/services/user/user.command.ts index 14fc8a70..b31cdafd 100644 --- a/app/business/services/user/user.command.ts +++ b/app/business/services/user/user.command.ts @@ -194,18 +194,9 @@ export async function createUser(prevState: FormState, formData: FormData): Prom }; try { - const response = await fetch(`${API_PATH.user}/sign-up`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(body), + await instance.post(`${API_PATH.user}/sign-up`, body, { + responseType: 'text', }); - - if (response.status !== 200) { - const result = await response.json(); - httpErrorHandler(response, result); - } } catch (error) { if (error instanceof BadRequestError) { // 잘못된 요청 처리 로직 From 4d401f0ddc08ab910bff58b086465ad8aefe00f8 Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Sun, 22 Sep 2024 11:32:29 +0000 Subject: [PATCH 15/18] =?UTF-8?q?feat:=20=EB=B9=84=EB=B0=80=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EB=B3=80=EA=B2=BD=20=EB=A1=9C=EC=A7=81=20fetch-ax?= =?UTF-8?q?=20=EB=A7=88=EC=9D=B4=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/business/services/user/user.command.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/business/services/user/user.command.ts b/app/business/services/user/user.command.ts index b31cdafd..04fddef0 100644 --- a/app/business/services/user/user.command.ts +++ b/app/business/services/user/user.command.ts @@ -241,12 +241,8 @@ export async function resetPassword(prevState: FormState, formData: FormData): P passwordCheck, }; try { - const response = await fetch(`${API_PATH.user}/password`, { - method: 'PATCH', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(body), + instance.patch(`${API_PATH.user}/password`, body, { + responseType: 'text', }); return { From ae8508474972bd25b43ed8f8609d4f6ccfd345b5 Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Sun, 22 Sep 2024 11:35:07 +0000 Subject: [PATCH 16/18] =?UTF-8?q?feat:=20=EA=B3=84=EC=A0=95=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EB=A1=9C=EC=A7=81=20fetch-ax=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=EA=B7=B8=EB=A0=88=EC=9D=B4=EC=85=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/business/services/user/user.command.ts | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/app/business/services/user/user.command.ts b/app/business/services/user/user.command.ts index 04fddef0..9161b1fa 100644 --- a/app/business/services/user/user.command.ts +++ b/app/business/services/user/user.command.ts @@ -43,19 +43,9 @@ export async function deleteUser(prevState: FormState, formData: FormData): Prom password: formData.get('password') as string, }; - const response = await fetch(`${API_PATH.user}/me`, { - method: 'DELETE', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${cookies().get('accessToken')?.value}`, - }, - body: JSON.stringify(body), + await instance.delete(`${API_PATH.user}/me`, { + data: body, }); - - if (response.status !== 200) { - const result = await response.json(); - httpErrorHandler(response, result); - } } catch (error) { if (error instanceof BadRequestError) { // 잘못된 요청 처리 로직 @@ -241,7 +231,7 @@ export async function resetPassword(prevState: FormState, formData: FormData): P passwordCheck, }; try { - instance.patch(`${API_PATH.user}/password`, body, { + await instance.patch(`${API_PATH.user}/password`, body, { responseType: 'text', }); From 5d3f63a90d37cd416ea06aa4e29580ee7931d9cb Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Wed, 25 Sep 2024 14:59:06 +0000 Subject: [PATCH 17/18] =?UTF-8?q?fix:=20=ED=81=AC=EB=A1=9C=EB=A7=88?= =?UTF-8?q?=ED=8B=B1=EC=9D=B4=20=EA=B9=A8=EC=A7=80=EB=8A=94=20=ED=98=84?= =?UTF-8?q?=EC=83=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/business/services/user/user.query.ts | 2 +- app/ui/user/sign-up-form/sign-up-form.stories.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/business/services/user/user.query.ts b/app/business/services/user/user.query.ts index e1d96331..44d7b7f5 100644 --- a/app/business/services/user/user.query.ts +++ b/app/business/services/user/user.query.ts @@ -78,7 +78,7 @@ export async function findUserToStudentNumber(prevState: FormState, formData: Fo isSuccess: false, isFailure: true, validationError: {}, - message: error.message, + message: '해당 사용자를 찾을 수 없습니다.', }; } else { throw error; diff --git a/app/ui/user/sign-up-form/sign-up-form.stories.tsx b/app/ui/user/sign-up-form/sign-up-form.stories.tsx index ea609777..ff48dfad 100644 --- a/app/ui/user/sign-up-form/sign-up-form.stories.tsx +++ b/app/ui/user/sign-up-form/sign-up-form.stories.tsx @@ -90,7 +90,7 @@ export const FailureSenarioWithDuplicatedStudentNumber: Story = { await step('회원가입에 실패한다.', async () => { await waitFor(() => { expect(args.onSuccess).not.toHaveBeenCalled(); - expect(canvas.getByText('이미 가입된 학번입니다.')).toBeInTheDocument(); + expect(canvas.getByText('Bad Request')).toBeInTheDocument(); }); }); }, From c3c1db2a52fed9eb675c1d17312a778fa6ed61d0 Mon Sep 17 00:00:00 2001 From: SeonghunYang Date: Wed, 25 Sep 2024 15:05:07 +0000 Subject: [PATCH 18/18] =?UTF-8?q?refactor:=20instance=20=ED=8F=B4=EB=8D=94?= =?UTF-8?q?=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/business/services/user/user.command.ts | 2 +- app/business/services/user/user.query.ts | 2 +- app/utils/{http => api}/instance.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename app/utils/{http => api}/instance.ts (89%) diff --git a/app/business/services/user/user.command.ts b/app/business/services/user/user.command.ts index 07fa39dc..72cc370c 100644 --- a/app/business/services/user/user.command.ts +++ b/app/business/services/user/user.command.ts @@ -23,8 +23,8 @@ import { cookies } from 'next/headers'; import { isValidation } from '@/app/utils/zod/validation.util'; import { redirect } from 'next/navigation'; import { fetchUser } from './user.query'; -import { instance } from '@/app/utils/http/instance'; import fetchAX from 'fetch-ax'; +import { instance } from '@/app/utils/api/instance'; function deleteCookies() { cookies().delete('accessToken'); diff --git a/app/business/services/user/user.query.ts b/app/business/services/user/user.query.ts index 44d7b7f5..feab0b4e 100644 --- a/app/business/services/user/user.query.ts +++ b/app/business/services/user/user.query.ts @@ -11,7 +11,7 @@ import { FindIdResponseSchema, } from './user.validation'; import { FormState } from '@/app/ui/view/molecule/form/form-root'; -import { instance } from '@/app/utils/http/instance'; +import { instance } from '@/app/utils/api/instance'; export async function auth(): Promise { try { diff --git a/app/utils/http/instance.ts b/app/utils/api/instance.ts similarity index 89% rename from app/utils/http/instance.ts rename to app/utils/api/instance.ts index 910c73d5..037e70bd 100644 --- a/app/utils/http/instance.ts +++ b/app/utils/api/instance.ts @@ -1,6 +1,6 @@ import fetchAx, { FetchAxError } from 'fetch-ax'; -import { fetchAxErrorHandler } from './http-error-handler'; import { cookies } from 'next/headers'; +import { fetchAxErrorHandler } from '../http/http-error-handler'; export const instance = fetchAx.create({ headers: {