From 887bce9e22bd7696bea50c73f5aa63f5ddcb4190 Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Tue, 30 Jul 2024 01:30:08 +0900 Subject: [PATCH 01/21] =?UTF-8?q?=F0=9F=94=A8=20settings:=20Next-Auth=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=84=A4=EC=B9=98=20=EB=B0=8F=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=EB=B3=80=EC=88=98=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=82=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.local.example | 1 + package.json | 2 + pnpm-lock.yaml | 104 +++++++++++++++++++++++++++++++++++++++++++++ src/env/index.ts | 13 +++--- 4 files changed, 114 insertions(+), 6 deletions(-) diff --git a/.env.local.example b/.env.local.example index e69de29..7afc07f 100644 --- a/.env.local.example +++ b/.env.local.example @@ -0,0 +1 @@ +NEXT_AUTH_SECRET=iU1JAytRolXU3hNTid9yBLy+Un91a1EzanGxWnXcnLwi \ No newline at end of file diff --git a/package.json b/package.json index 220773a..98f6879 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,8 @@ "@tanstack/react-query-devtools": "^5.50.1", "clsx": "^2.1.1", "next": "14.2.4", + "next-auth": "5.0.0-beta.20", + "path-to-regexp": "^7.1.0", "react": "^18", "react-dom": "^18", "tailwind-merge": "^2.4.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7c53ecb..e4528ff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,12 @@ importers: next: specifier: 14.2.4 version: 14.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next-auth: + specifier: 5.0.0-beta.20 + version: 5.0.0-beta.20(next@14.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + path-to-regexp: + specifier: ^7.1.0 + version: 7.1.0 react: specifier: ^18 version: 18.3.1 @@ -130,6 +136,20 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} + '@auth/core@0.34.2': + resolution: {integrity: sha512-KywHKRgLiF3l7PLyL73fjLSIBe1YNcA6sMeew4yMP6cfCWGXZrkkXd32AjRi1hlJ9nvovUBGZHvbn+LijO6ZeQ==} + peerDependencies: + '@simplewebauthn/browser': ^9.0.1 + '@simplewebauthn/server': ^9.0.2 + nodemailer: ^6.8.0 + peerDependenciesMeta: + '@simplewebauthn/browser': + optional: true + '@simplewebauthn/server': + optional: true + nodemailer: + optional: true + '@babel/code-frame@7.24.7': resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} engines: {node: '>=6.9.0'} @@ -287,6 +307,9 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@panva/hkdf@1.2.1': + resolution: {integrity: sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -518,6 +541,9 @@ packages: '@types/conventional-commits-parser@5.0.0': resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + '@types/eslint@8.56.10': resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==} @@ -927,6 +953,10 @@ packages: conventional-commit-types@3.0.0: resolution: {integrity: sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==} + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + cosmiconfig-typescript-loader@5.0.0: resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} engines: {node: '>=v16'} @@ -1670,6 +1700,9 @@ packages: resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} hasBin: true + jose@5.6.3: + resolution: {integrity: sha512-1Jh//hEEwMhNYPDDLwXHa2ePWgWiFNNUadVmguAAw2IJ6sj9mNxV5tGXJNqlMkJAybF6Lgw1mISDxTePP/187g==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1833,6 +1866,22 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + next-auth@5.0.0-beta.20: + resolution: {integrity: sha512-+48SjV9k9AtUU3JbEIa4PXNjKIewfFjVGL7Xs2RKkuQ5QqegDNIQiIG8sLk6/qo7RTScQYIGKgeQ5IuQRtrTQg==} + peerDependencies: + '@simplewebauthn/browser': ^9.0.1 + '@simplewebauthn/server': ^9.0.2 + next: ^14.0.0-0 || ^15.0.0-0 + nodemailer: ^6.6.5 + react: ^18.2.0 || ^19.0.0-0 + peerDependenciesMeta: + '@simplewebauthn/browser': + optional: true + '@simplewebauthn/server': + optional: true + nodemailer: + optional: true + next@14.2.4: resolution: {integrity: sha512-R8/V7vugY+822rsQGQCjoLhMuC9oFj9SOi4Cl4b2wjDrseD0LRZ10W7R6Czo4w9ZznVSshKjuIomsRjvm9EKJQ==} engines: {node: '>=18.17.0'} @@ -1862,6 +1911,9 @@ packages: resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} engines: {node: '>=0.10.0'} + oauth4webapi@2.11.1: + resolution: {integrity: sha512-aNzOnL98bL6izG97zgnZs1PFEyO4WDVRhz2Pd066NPak44w5ESLRCYmJIyey8avSBPOMtBjhF3ZDDm7bIb7UOg==} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -1975,6 +2027,10 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-to-regexp@7.1.0: + resolution: {integrity: sha512-ZToe+MbUF4lBqk6dV8GKot4DKfzrxXsplOddH8zN3YK+qw9/McvP7+4ICjZvOne0jQhN4eJwHsX6tT0Ns19fvw==} + engines: {node: '>=16'} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -2043,6 +2099,14 @@ packages: resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==} engines: {node: ^10 || ^12 || >=14} + preact-render-to-string@5.2.3: + resolution: {integrity: sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==} + peerDependencies: + preact: '>=10' + + preact@10.11.3: + resolution: {integrity: sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -2056,6 +2120,9 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-format@3.8.0: + resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==} + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -2523,6 +2590,16 @@ snapshots: '@alloc/quick-lru@5.2.0': {} + '@auth/core@0.34.2': + dependencies: + '@panva/hkdf': 1.2.1 + '@types/cookie': 0.6.0 + cookie: 0.6.0 + jose: 5.6.3 + oauth4webapi: 2.11.1 + preact: 10.11.3 + preact-render-to-string: 5.2.3(preact@10.11.3) + '@babel/code-frame@7.24.7': dependencies: '@babel/highlight': 7.24.7 @@ -2688,6 +2765,8 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 + '@panva/hkdf@1.2.1': {} + '@pkgjs/parseargs@0.11.0': optional: true @@ -2884,6 +2963,8 @@ snapshots: '@types/node': 20.14.10 optional: true + '@types/cookie@0.6.0': {} + '@types/eslint@8.56.10': dependencies: '@types/estree': 1.0.5 @@ -3377,6 +3458,8 @@ snapshots: conventional-commit-types@3.0.0: {} + cookie@0.6.0: {} + cosmiconfig-typescript-loader@5.0.0(@types/node@20.14.10)(cosmiconfig@9.0.0(typescript@5.5.3))(typescript@5.5.3): dependencies: '@types/node': 20.14.10 @@ -4336,6 +4419,8 @@ snapshots: jiti@1.21.6: {} + jose@5.6.3: {} + js-tokens@4.0.0: {} js-yaml@4.1.0: @@ -4477,6 +4562,12 @@ snapshots: natural-compare@1.4.0: {} + next-auth@5.0.0-beta.20(next@14.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): + dependencies: + '@auth/core': 0.34.2 + next: 14.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + next@14.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@next/env': 14.2.4 @@ -4508,6 +4599,8 @@ snapshots: normalize-range@0.1.2: {} + oauth4webapi@2.11.1: {} + object-assign@4.1.1: {} object-hash@3.0.0: {} @@ -4633,6 +4726,8 @@ snapshots: lru-cache: 10.4.0 minipass: 7.1.2 + path-to-regexp@7.1.0: {} + path-type@4.0.0: {} picocolors@1.0.1: {} @@ -4688,6 +4783,13 @@ snapshots: picocolors: 1.0.1 source-map-js: 1.2.0 + preact-render-to-string@5.2.3(preact@10.11.3): + dependencies: + preact: 10.11.3 + pretty-format: 3.8.0 + + preact@10.11.3: {} + prelude-ls@1.2.1: {} prettier-linter-helpers@1.0.0: @@ -4696,6 +4798,8 @@ snapshots: prettier@3.3.2: {} + pretty-format@3.8.0: {} + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 diff --git a/src/env/index.ts b/src/env/index.ts index 1d34f4e..bcb9d02 100644 --- a/src/env/index.ts +++ b/src/env/index.ts @@ -1,23 +1,24 @@ // https://env.t3.gg/docs/nextjs import { createEnv } from "@t3-oss/env-nextjs"; -import { ZodError } from "zod"; +import { z, ZodError } from "zod"; export const env = createEnv({ - server: {}, + server: { + NEXT_AUTH_SECRET: z.string().base64("NEXT_AUTH_SECRET Should be Base64"), + }, client: { // NEXT_PUBLIC_twitterUrl: z.string().min(1), }, runtimeEnv: { - // NEXT_PUBLIC_twitterUrl: process.env.twitterUrl, + NEXT_AUTH_SECRET: process.env.NEXT_AUTH_SECRET, }, onValidationError: (error: ZodError) => { - console.error( - "❌ 유효하지 않은 환경변수들 입니다:", - error.flatten().fieldErrors, + error.issues.forEach((v) => + console.error("환경변수 유효성 검사 에러메시지 :", v.message), ); throw new Error("Invalid environment variables"); }, From 6f19a63b1d30aeabf9ada8f35796311bb059f081 Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Tue, 30 Jul 2024 01:38:33 +0900 Subject: [PATCH 02/21] =?UTF-8?q?=F0=9F=94=A8=20settings:=20auth=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20alias=20=EC=84=A4=EC=A0=95=20#10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tsconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index 9e2d0b2..fad0446 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,7 +19,7 @@ ], "paths": { "@/*": ["./src/*"], - "@env": ["./src/env/index.ts"] + "@/auth": ["./auth.ts"] } }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], From 8cfda3e17529b850933d6edf4fc1517172ebde03 Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Tue, 30 Jul 2024 01:39:54 +0900 Subject: [PATCH 03/21] =?UTF-8?q?=F0=9F=94=A8=20settings:=20next-auth=20?= =?UTF-8?q?=EA=B8=B0=EB=B3=B8=20config=20=ED=8C=8C=EC=9D=BC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20#10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- auth.ts | 5 +++++ src/app/api/auth/[...nextauth]/route.ts | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 auth.ts create mode 100644 src/app/api/auth/[...nextauth]/route.ts diff --git a/auth.ts b/auth.ts new file mode 100644 index 0000000..3be7be6 --- /dev/null +++ b/auth.ts @@ -0,0 +1,5 @@ +import NextAuth from "next-auth"; + +export const { handlers, signIn, signOut, auth } = NextAuth({ + providers: [], +}); diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts new file mode 100644 index 0000000..7c62e2d --- /dev/null +++ b/src/app/api/auth/[...nextauth]/route.ts @@ -0,0 +1,2 @@ +import { handlers } from "@/auth"; +export const { GET, POST } = handlers; From 2451d58b1075a7f8c2f38f803570244dbf99756f Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Wed, 31 Jul 2024 00:20:35 +0900 Subject: [PATCH 04/21] =?UTF-8?q?=F0=9F=94=A8=20settings:=20=EC=B9=B4?= =?UTF-8?q?=EC=B9=B4=EC=98=A4,=20Next-Auth=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=EB=B3=80=EC=88=98=20=EC=9C=A0=ED=9A=A8?= =?UTF-8?q?=EC=84=B1=20=EA=B2=80=EC=82=AC=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20#10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/env/index.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/env/index.ts b/src/env/index.ts index bcb9d02..2adc2b2 100644 --- a/src/env/index.ts +++ b/src/env/index.ts @@ -5,7 +5,9 @@ import { z, ZodError } from "zod"; export const env = createEnv({ server: { - NEXT_AUTH_SECRET: z.string().base64("NEXT_AUTH_SECRET Should be Base64"), + AUTH_SECRET: z.string().base64("AUTH_SECRET should be base64"), + AUTH_KAKAO_ID: z.string(), + AUTH_KAKAO_SECRET: z.string().base64("AUTH_KAKAO_SECRET should be base64"), }, client: { @@ -13,14 +15,16 @@ export const env = createEnv({ }, runtimeEnv: { - NEXT_AUTH_SECRET: process.env.NEXT_AUTH_SECRET, + AUTH_SECRET: process.env.AUTH_SECRET, + AUTH_KAKAO_ID: process.env.AUTH_KAKAO_ID, + AUTH_KAKAO_SECRET: process.env.AUTH_KAKAO_SECRET, }, onValidationError: (error: ZodError) => { - error.issues.forEach((v) => - console.error("환경변수 유효성 검사 에러메시지 :", v.message), + console.table( + error.issues.map((v) => ({ name: v.path[0], message: v.message })), ); - throw new Error("Invalid environment variables"); + throw new Error("환경변수 유효성 검사 에러"); }, // Called when server variables are accessed on the client. onInvalidAccess: (variable: string) => { From ac5333a93a02a1cd8e2e41c63c373c5d9e6322d1 Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Wed, 31 Jul 2024 00:33:23 +0900 Subject: [PATCH 05/21] =?UTF-8?q?=F0=9F=94=A8=20settings:=20middleware=20?= =?UTF-8?q?=EC=84=B8=ED=8C=85=20#10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/middleware.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/middleware.ts diff --git a/src/middleware.ts b/src/middleware.ts new file mode 100644 index 0000000..a372a03 --- /dev/null +++ b/src/middleware.ts @@ -0,0 +1,11 @@ +export { auth as middleware } from "@/auth"; + +// Or like this if you need to do something here. +// export default auth((req) => { +// console.log(req.auth) // { session: { user: { ... } } } +// }) + +// Read more: https://nextjs.org/docs/app/building-your-application/routing/middleware#matcher +export const config = { + matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"], +}; From f56c508709666920caef424368bfe1296f707c1e Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Wed, 31 Jul 2024 00:34:20 +0900 Subject: [PATCH 06/21] =?UTF-8?q?=E2=9C=A8=20feat:=20auth.js=20signIn=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?=EC=84=B8=ED=8C=85=20#10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- auth.ts | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 4 deletions(-) diff --git a/auth.ts b/auth.ts index 3be7be6..70a9e47 100644 --- a/auth.ts +++ b/auth.ts @@ -1,5 +1,87 @@ -import NextAuth from "next-auth"; +// ? Reference https://github.dev/nextauthjs/next-auth-example/blob/main/app/api/protected/route.ts +// ? Reference https://www.heropy.dev/p/MI1Khc -export const { handlers, signIn, signOut, auth } = NextAuth({ - providers: [], -}); +import NextAuth, { Account, NextAuthConfig, Session, User } from "next-auth"; +import { AdapterUser } from "next-auth/adapters"; +import { JWT } from "next-auth/jwt"; +import { ProviderType } from "next-auth/providers"; +import Kakao from "next-auth/providers/kakao"; + +const config = { + providers: [Kakao], + // ? 사용자 지정 로그인, 로그아웃 및 오류 페이지를 만들 때 사용할 URL을 지정합니다. 지정한 페이지는 해당 기본 제공 페이지를 재정의합니다. + pages: { + signIn: "/signIn", + }, + callbacks: { + // * protected page 설정 + authorized({ request, auth }) { + const { pathname } = request.nextUrl; + if (pathname === "/mypage") return !!auth; + return true; + }, + // * callbackUrl이 있다면 callbackUrl로 리다이렉트 + redirect: async ({ url, baseUrl }: { url: string; baseUrl: string }) => { + if (url.startsWith("/")) return `${baseUrl}${url}`; + if (url) { + const { search, origin } = new URL(url); + const callbackUrl = new URLSearchParams(search).get("callbackUrl"); + if (callbackUrl) + return callbackUrl.startsWith("/") + ? `${baseUrl}${callbackUrl}` + : callbackUrl; + if (origin === baseUrl) return url; + } + return baseUrl; + }, + // ? 이 콜백은 JSON 웹 토큰이 생성되거나(즉, 로그인할 때) 업데이트될 때마다(즉, 클라이언트에서 세션에 액세스할 때마다) 호출됩니다. + // ? 여기서 반환하는 모든 내용은 JWT에 저장되어 세션 콜백으로 전달됩니다. 여기에서 클라이언트에 반환할 항목을 제어할 수 있습니다. + // ? 그 외의 모든 내용은 프런트엔드에서 보관됩니다. JWT는 기본적으로 AUTH_SECRET 환경 변수를 통해 암호화됩니다. + jwt: async ({ + token, + account, + }: { + token: JWT; + user?: User | AdapterUser; + account?: Account | null; + }) => { + token.accessToken = account?.access_token; + return token; + }, + // ? 로그인한 사용자의 활성 세션입니다. + session: async ({ session, token }: { session: Session; token: JWT }) => { + if (token?.accessToken) { + session.accessToken = token.accessToken; + } + return session; + }, + }, + // ? 인증 및 데이터베이스 작업에 대한 디버그 메시지를 사용하려면 디버그를 true로 설정합니다. + debug: process.env.NODE_ENV !== "production" ? true : false, +} satisfies NextAuthConfig; + +export const { signIn, signOut, handlers, auth } = NextAuth(config); + +declare module "next-auth" { + // * 카카오 Account 응답에 맞게 수정 + interface Account { + access_token?: string; + token_type?: string; + refresh_token?: string; + expires_in?: number; + refresh_token_expires_in?: number; + expires_at?: number; + provider: string; + type: ProviderType; + providerAccountId: string; + } + // * 세션이 accessToken 필드값 추가 ( 필요에 따라 더 추가 ) + interface Session { + accessToken?: string; + } +} +declare module "next-auth/jwt" { + interface JWT { + accessToken?: string; + } +} From 7bee4949c74a8dfa374a338f197c6fefa089ea08 Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Wed, 31 Jul 2024 00:37:33 +0900 Subject: [PATCH 07/21] =?UTF-8?q?=E2=9C=85=20test:=20=EB=A1=9C=EA=B7=B8?= =?UTF-8?q?=EC=9D=B8=20=EB=A6=AC=EB=8B=A4=EC=9D=B4=EB=A0=89=ED=8A=B8=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20#10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/signIn/page.tsx | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/app/signIn/page.tsx diff --git a/src/app/signIn/page.tsx b/src/app/signIn/page.tsx new file mode 100644 index 0000000..24edcf8 --- /dev/null +++ b/src/app/signIn/page.tsx @@ -0,0 +1,20 @@ +import { signIn } from "@/auth"; + +const page = () => { + return ( +
{ + "use server"; + + await signIn("kakao"); + }} + className="flex h-screen w-full items-center justify-center" + > + +
+ ); +}; + +export default page; From 078509d8d3da917f024157a0583767c19b62d8a4 Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Wed, 31 Jul 2024 01:05:21 +0900 Subject: [PATCH 08/21] =?UTF-8?q?=F0=9F=93=9D=20docs:=20.env.local.example?= =?UTF-8?q?=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20#10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.local.example | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.env.local.example b/.env.local.example index 7afc07f..da0ef5f 100644 --- a/.env.local.example +++ b/.env.local.example @@ -1 +1,3 @@ -NEXT_AUTH_SECRET=iU1JAytRolXU3hNTid9yBLy+Un91a1EzanGxWnXcnLwi \ No newline at end of file +AUTH_SECRET=openssl rand -base64 32 +AUTH_KAKAO_ID= +AUTH_KAKAO_SECRET=openssl rand -base64 32 \ No newline at end of file From 48c079f9d518d458a7f490db518a12fa65a0566b Mon Sep 17 00:00:00 2001 From: Jeongmin Lee Date: Tue, 20 Aug 2024 03:09:16 +0900 Subject: [PATCH 09/21] =?UTF-8?q?=E2=9C=A8=20feat:=20=EC=B9=B4=EC=B9=B4?= =?UTF-8?q?=EC=98=A4=20=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=8B=9C?= =?UTF-8?q?=EC=9E=91=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20#10?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 3 +- pnpm-lock.yaml | 296 ++++++++++++++++++++++++++++++++++++++++-- src/app/layout.tsx | 7 +- src/lib/KakaoInit.tsx | 21 +++ 4 files changed, 314 insertions(+), 13 deletions(-) create mode 100644 src/lib/KakaoInit.tsx diff --git a/package.json b/package.json index e736fdd..a2e98a1 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@radix-ui/react-progress": "^1.1.0", "@tanstack/react-query": "^5.50.1", "@tanstack/react-query-devtools": "^5.50.1", + "@types/kakao-js-sdk": "^1.39.5", "canvas-confetti": "^1.9.3", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", @@ -29,8 +30,8 @@ "framer-motion": "^11.3.24", "next": "14.2.4", "next-auth": "5.0.0-beta.20", - "path-to-regexp": "^7.1.0", "nuqs": "^1.17.8", + "path-to-regexp": "^7.1.0", "react": "^18", "react-daum-postcode": "^3.1.3", "react-dom": "^18", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e7bab88..85f877d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,6 +26,9 @@ importers: '@tanstack/react-query-devtools': specifier: ^5.50.1 version: 5.50.1(@tanstack/react-query@5.50.1(react@18.3.1))(react@18.3.1) + '@types/kakao-js-sdk': + specifier: ^1.39.5 + version: 1.39.5 canvas-confetti: specifier: ^1.9.3 version: 1.9.3 @@ -44,12 +47,12 @@ importers: next: specifier: 14.2.4 version: 14.2.4(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next-auth: + specifier: 5.0.0-beta.20 + version: 5.0.0-beta.20(next@14.2.4(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) nuqs: specifier: ^1.17.8 version: 1.17.8(next@14.2.4(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) - next-auth: - specifier: 5.0.0-beta.20 - version: 5.0.0-beta.20(next@14.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) path-to-regexp: specifier: ^7.1.0 version: 7.1.0 @@ -220,6 +223,24 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@auth/core@0.34.2': + resolution: {integrity: sha512-KywHKRgLiF3l7PLyL73fjLSIBe1YNcA6sMeew4yMP6cfCWGXZrkkXd32AjRi1hlJ9nvovUBGZHvbn+LijO6ZeQ==} + peerDependencies: + '@simplewebauthn/browser': ^9.0.1 + '@simplewebauthn/server': ^9.0.2 + nodemailer: ^6.8.0 + peerDependenciesMeta: + '@simplewebauthn/browser': + optional: true + '@simplewebauthn/server': + optional: true + nodemailer: + optional: true + '@babel/code-frame@7.24.7': resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} engines: {node: '>=6.9.0'} @@ -1347,6 +1368,18 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + + '@open-draft/logger@0.3.0': + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + + '@open-draft/until@2.1.0': + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + + '@panva/hkdf@1.2.1': + resolution: {integrity: sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -2032,6 +2065,24 @@ packages: '@types/conventional-commits-parser@5.0.0': resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + + '@types/cross-spawn@6.0.6': + resolution: {integrity: sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA==} + + '@types/doctrine@0.0.9': + resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} + + '@types/emscripten@1.39.13': + resolution: {integrity: sha512-cFq+fO/isvhvmuP/+Sl4K4jtU6E23DoivtbO4r50e3odaxAiVdbfSYRDdJ4gCdxx+3aRjhphS5ZMwIH4hFy/Cw==} + + '@types/escodegen@0.0.6': + resolution: {integrity: sha512-AjwI4MvWx3HAOaZqYsjKWyEObT9lcVV0Y0V8nXo6cXzN8ZiMxVhf6F3d/UNvXVGKrEzL/Dluc5p+y9GkzlTWig==} + + '@types/eslint-scope@3.7.7': + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + '@types/eslint@8.56.10': resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==} @@ -2062,6 +2113,9 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/kakao-js-sdk@1.39.5': + resolution: {integrity: sha512-+u+sfAq2ZcBM4yF3zE/FDxaNq85DeLkKh8K6jP9GQwGdbIJ/IGwoAQEfkbG5tL5XHOP30b3KeHmxDFG2n1E96Q==} + '@types/lodash@4.17.7': resolution: {integrity: sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==} @@ -2654,6 +2708,11 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + browserslist@4.23.3: + resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -2703,6 +2762,9 @@ packages: caniuse-lite@1.0.30001640: resolution: {integrity: sha512-lA4VMpW0PSUrFnkmVuEKBUovSWKhj7puyCg8StBChgu298N1AtuF1sKWEvfDuimSEDbhlb/KqPKC3fs1HbuQUA==} + caniuse-lite@1.0.30001651: + resolution: {integrity: sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==} + canvas-confetti@1.9.3: resolution: {integrity: sha512-rFfTURMvmVEX1gyXFgn5QMn81bYk70qa0HLzcIOSVEyl57n6o9ItHeBtUSWdvKAPY0xlvBHno4/v3QPrT83q9g==} @@ -2902,6 +2964,32 @@ packages: conventional-commit-types@3.0.0: resolution: {integrity: sha512-SmmCYnOniSsAa9GqWOeLqc179lfr5TRu5b4QFDkbsrJ5TZjPJx85wtOr3zn+1dbeNiXDKGPbZ72IKbPhLXh/Lg==} + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + + core-js-compat@3.38.0: + resolution: {integrity: sha512-75LAicdLa4OJVwFxFbQR3NdnZjNgX6ILpVcVzcC4T2smerB5lELMrJQQQoWV6TiuC/vlaFqgU2tKQx9w5s0e0A==} + + core-js-pure@3.38.0: + resolution: {integrity: sha512-8balb/HAXo06aHP58mZMtXgD8vcnXz9tUDePgqBgJgKdmTlMt+jw3ujqniuBDQXMvTzxnMpxHFeuSM3g1jWQuQ==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cosmiconfig-typescript-loader@5.0.0: resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} engines: {node: '>=v16'} @@ -3186,6 +3274,9 @@ packages: electron-to-chromium@1.4.827: resolution: {integrity: sha512-VY+J0e4SFcNfQy19MEoMdaIcZLmDCprqvBtkii1WTCTQHpRvf5N8+3kTYCgL/PcntvwQvmMJWTuDPsq+IlhWKQ==} + electron-to-chromium@1.5.11: + resolution: {integrity: sha512-R1CccCDYqndR25CaXFd6hp/u9RaaMcftMkphmvuepXr5b1vfLkRml6aWVeBhXJ7rbevHkKEMJtz8XqPf7ffmew==} + elliptic@6.5.6: resolution: {integrity: sha512-mpzdtpeCLuS3BmE3pO3Cpp5bbjlOPY2Q0PgoF+Od1XZrHLYI28Xe3ossCmYCQt11FQKEYd9+PF8jymTvtWJSHQ==} @@ -4539,6 +4630,29 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + next-auth@5.0.0-beta.20: + resolution: {integrity: sha512-+48SjV9k9AtUU3JbEIa4PXNjKIewfFjVGL7Xs2RKkuQ5QqegDNIQiIG8sLk6/qo7RTScQYIGKgeQ5IuQRtrTQg==} + peerDependencies: + '@simplewebauthn/browser': ^9.0.1 + '@simplewebauthn/server': ^9.0.2 + next: ^14.0.0-0 || ^15.0.0-0 + nodemailer: ^6.6.5 + react: ^18.2.0 || ^19.0.0-0 + peerDependenciesMeta: + '@simplewebauthn/browser': + optional: true + '@simplewebauthn/server': + optional: true + nodemailer: + optional: true + next@14.2.4: resolution: {integrity: sha512-R8/V7vugY+822rsQGQCjoLhMuC9oFj9SOi4Cl4b2wjDrseD0LRZ10W7R6Czo4w9ZznVSshKjuIomsRjvm9EKJQ==} engines: {node: '>=18.17.0'} @@ -4579,6 +4693,9 @@ packages: node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -4587,6 +4704,30 @@ packages: resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} engines: {node: '>=0.10.0'} + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nuqs@1.17.8: + resolution: {integrity: sha512-JqsnzO+hJyjJE7ebuhpHMLA2iGY48e2xr0oJQFhj7kjUmDABL2XOup47rxF5TL/5b9jEsmU2t0lAKin1VdK1/A==} + peerDependencies: + next: '>=13.4 <14.0.2 || ^14.0.3' + + nypm@0.3.9: + resolution: {integrity: sha512-BI2SdqqTHg2d4wJh8P9A1W+bslg33vOE9IZDY6eR2QC+Pu1iNBVZUqczrd43rJb+fMzHU7ltAYKsEFY/kHMFcw==} + engines: {node: ^14.16.0 || >=16.10.0} + hasBin: true + + oauth4webapi@2.11.1: + resolution: {integrity: sha512-aNzOnL98bL6izG97zgnZs1PFEyO4WDVRhz2Pd066NPak44w5ESLRCYmJIyey8avSBPOMtBjhF3ZDDm7bIb7UOg==} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -4776,6 +4917,16 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + + path-to-regexp@6.2.2: + resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} + + path-to-regexp@7.1.0: + resolution: {integrity: sha512-ZToe+MbUF4lBqk6dV8GKot4DKfzrxXsplOddH8zN3YK+qw9/McvP7+4ICjZvOne0jQhN4eJwHsX6tT0Ns19fvw==} + engines: {node: '>=16'} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -4943,6 +5094,31 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-error@4.0.0: + resolution: {integrity: sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==} + + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + pretty-format@3.8.0: + resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -6059,6 +6235,21 @@ snapshots: '@alloc/quick-lru@5.2.0': {} + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@auth/core@0.34.2': + dependencies: + '@panva/hkdf': 1.2.1 + '@types/cookie': 0.6.0 + cookie: 0.6.0 + jose: 5.6.3 + oauth4webapi: 2.11.1 + preact: 10.11.3 + preact-render-to-string: 5.2.3(preact@10.11.3) + '@babel/code-frame@7.24.7': dependencies: '@babel/highlight': 7.24.7 @@ -6861,7 +7052,7 @@ snapshots: babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.25.2) babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.25.2) babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.25.2) - core-js-compat: 3.37.1 + core-js-compat: 3.38.0 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -7325,6 +7516,17 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 + '@open-draft/deferred-promise@2.2.0': {} + + '@open-draft/logger@0.3.0': + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.3 + + '@open-draft/until@2.1.0': {} + + '@panva/hkdf@1.2.1': {} + '@pkgjs/parseargs@0.11.0': optional: true @@ -7333,7 +7535,7 @@ snapshots: '@pmmmwh/react-refresh-webpack-plugin@0.5.15(react-refresh@0.14.2)(type-fest@4.24.0)(webpack-hot-middleware@2.26.1)(webpack@5.93.0(esbuild@0.21.5))': dependencies: ansi-html: 0.0.9 - core-js-pure: 3.37.1 + core-js-pure: 3.38.0 error-stack-parser: 2.1.4 html-entities: 2.5.2 loader-utils: 2.0.4 @@ -8202,6 +8404,23 @@ snapshots: '@types/node': 20.14.10 optional: true + '@types/cookie@0.6.0': {} + + '@types/cross-spawn@6.0.6': + dependencies: + '@types/node': 20.14.10 + + '@types/doctrine@0.0.9': {} + + '@types/emscripten@1.39.13': {} + + '@types/escodegen@0.0.6': {} + + '@types/eslint-scope@3.7.7': + dependencies: + '@types/eslint': 8.56.10 + '@types/estree': 1.0.5 + '@types/eslint@8.56.10': dependencies: '@types/estree': 1.0.5 @@ -8237,6 +8456,8 @@ snapshots: '@types/json5@0.0.29': {} + '@types/kakao-js-sdk@1.39.5': {} + '@types/lodash@4.17.7': {} '@types/mdx@2.0.13': {} @@ -8868,7 +9089,7 @@ snapshots: dependencies: '@babel/core': 7.25.2 '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) - core-js-compat: 3.37.1 + core-js-compat: 3.38.0 transitivePeerDependencies: - supports-color @@ -8984,6 +9205,13 @@ snapshots: node-releases: 2.0.14 update-browserslist-db: 1.1.0(browserslist@4.23.2) + browserslist@4.23.3: + dependencies: + caniuse-lite: 1.0.30001651 + electron-to-chromium: 1.5.11 + node-releases: 2.0.18 + update-browserslist-db: 1.1.0(browserslist@4.23.3) + buffer-from@1.1.2: {} buffer-xor@1.0.3: {} @@ -9029,6 +9257,8 @@ snapshots: caniuse-lite@1.0.30001640: {} + caniuse-lite@1.0.30001651: {} + canvas-confetti@1.9.3: {} case-sensitive-paths-webpack-plugin@2.4.0: {} @@ -9219,6 +9449,24 @@ snapshots: conventional-commit-types@3.0.0: {} + convert-source-map@1.9.0: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.0.6: {} + + cookie@0.5.0: {} + + cookie@0.6.0: {} + + core-js-compat@3.38.0: + dependencies: + browserslist: 4.23.3 + + core-js-pure@3.38.0: {} + + core-util-is@1.0.3: {} + cosmiconfig-typescript-loader@5.0.0(@types/node@20.14.10)(cosmiconfig@9.0.0(typescript@5.5.3))(typescript@5.5.3): dependencies: '@types/node': 20.14.10 @@ -9557,6 +9805,8 @@ snapshots: electron-to-chromium@1.4.827: {} + electron-to-chromium@1.5.11: {} + elliptic@6.5.6: dependencies: bn.js: 4.12.0 @@ -11144,7 +11394,17 @@ snapshots: natural-compare@1.4.0: {} - next@14.2.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + negotiator@0.6.3: {} + + neo-async@2.6.2: {} + + next-auth@5.0.0-beta.20(next@14.2.4(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): + dependencies: + '@auth/core': 0.34.2 + next: 14.2.4(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + + next@14.2.4(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@next/env': 14.2.4 '@swc/helpers': 0.5.5 @@ -11213,12 +11473,12 @@ snapshots: node-releases@2.0.14: {} + node-releases@2.0.18: {} + normalize-path@3.0.0: {} normalize-range@0.1.2: {} - oauth4webapi@2.11.1: {} - npm-run-path@4.0.1: dependencies: path-key: 3.1.1 @@ -11245,6 +11505,8 @@ snapshots: pkg-types: 1.1.3 ufo: 1.5.4 + oauth4webapi@2.11.1: {} + object-assign@4.1.1: {} object-hash@3.0.0: {} @@ -11438,6 +11700,12 @@ snapshots: lru-cache: 10.4.0 minipass: 7.1.2 + path-to-regexp@0.1.7: {} + + path-to-regexp@6.2.2: {} + + path-to-regexp@7.1.0: {} + path-type@4.0.0: {} path-type@5.0.0: {} @@ -11584,8 +11852,6 @@ snapshots: prettier@3.3.2: {} - pretty-format@3.8.0: {} - pretty-error@4.0.0: dependencies: lodash: 4.17.21 @@ -11603,6 +11869,8 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 + pretty-format@3.8.0: {} + process-nextick-args@2.0.1: {} process@0.11.10: {} @@ -12637,6 +12905,12 @@ snapshots: escalade: 3.1.2 picocolors: 1.0.1 + update-browserslist-db@1.1.0(browserslist@4.23.3): + dependencies: + browserslist: 4.23.3 + escalade: 3.1.2 + picocolors: 1.0.1 + uri-js@4.4.1: dependencies: punycode: 2.3.1 diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 82c76ae..1eaf3e9 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -5,6 +5,7 @@ import type { Metadata } from "next"; import { ReactNode } from "react"; import MobileLayout from "@/layout/Mobile/MobileLayout"; +import KakaoInit from "@/lib/KakaoInit"; import { MSWProvider } from "@/lib/MSWProvider"; import ReactQueryProvider from "@/lib/ReactQueryProvider"; import { cn } from "@/utils/cn"; @@ -26,7 +27,11 @@ export default function RootLayout({ - {children} + + {children} + + + diff --git a/src/lib/KakaoInit.tsx b/src/lib/KakaoInit.tsx new file mode 100644 index 0000000..8b8db3a --- /dev/null +++ b/src/lib/KakaoInit.tsx @@ -0,0 +1,21 @@ +"use client"; + +import Script from "next/script"; + +import { env } from "@/env"; + +const KakaoInit = () => { + const onLoad = () => { + window.Kakao.init(env.NEXT_PUBLIC_CLIENT_ID); + }; + + return ( +