From 0c1aaa879a712c6603999e31e5007e4a376e053d Mon Sep 17 00:00:00 2001 From: hagaitski Date: Thu, 15 Aug 2024 18:15:42 +0900 Subject: [PATCH] =?UTF-8?q?docker-compose=E3=81=A7e2e=E7=92=B0=E5=A2=83?= =?UTF-8?q?=E6=A7=8B=E7=AF=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile.e2e | 19 +++++ docker-compose.e2e.yaml | 29 +++++++ src/pages/api/auth/[...nextauth].ts | 128 ++++++++++++++++++---------- 3 files changed, 133 insertions(+), 43 deletions(-) create mode 100644 Dockerfile.e2e create mode 100644 docker-compose.e2e.yaml diff --git a/Dockerfile.e2e b/Dockerfile.e2e new file mode 100644 index 00000000..34cd08e5 --- /dev/null +++ b/Dockerfile.e2e @@ -0,0 +1,19 @@ +# ベースイメージを指定(例:Node.jsの公式イメージの最新LTS版) +FROM node:20 + +# 作業ディレクトリを作成 +WORKDIR /app + +# アプリケーションのソースコードをコピー +COPY . . + +RUN git clean -xdf + +# 依存関係をインストール +RUN npm install + +# アプリケーションを起動 +CMD ["npm", "run", "dev"] + +# ポート番号を指定(例:3000) +EXPOSE 3000 diff --git a/docker-compose.e2e.yaml b/docker-compose.e2e.yaml new file mode 100644 index 00000000..6e3179ad --- /dev/null +++ b/docker-compose.e2e.yaml @@ -0,0 +1,29 @@ +services: + db: + image: postgres:16-alpine + restart: always + environment: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + POSTGRES_DB: postgres + ports: + - 5432:5432 + nextjs: + build: + context: . + dockerfile: Dockerfile.e2e + ports: + - 3000:3000 + depends_on: + - db + environment: + SUPABASE_POSTGRES_URL_NON_POOLING: postgres://postgres:postgres@db:5432/postgres + SUPABASE_POSTGRES_PRISMA_URL: postgres://postgres:postgres@db:5432/postgres?pgbouncer=true + MOCK_LOGIN: 1 + RANKING_WEIGHT: '{"questionLogsLength": -0.1,"correctSolutionsLength": 0.3,"evaluationTotal": 0.9,"questionExamplesLength": 0.4,"random": 2,"timeFromPublished": -0.2}' + NEXTAUTH_SECRET: 'secret' + OPENAI_API_KEY: ${OPENAI_API_KEY} + ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY} + EDGE_CONFIG: ${EDGE_CONFIG} + + diff --git a/src/pages/api/auth/[...nextauth].ts b/src/pages/api/auth/[...nextauth].ts index f8d12c66..7c34b50e 100644 --- a/src/pages/api/auth/[...nextauth].ts +++ b/src/pages/api/auth/[...nextauth].ts @@ -2,52 +2,94 @@ import { generateId } from "@/common/util/id"; import { neverReach } from "@/common/util/never"; import { prisma } from "@/libs/prisma"; import NextAuth, { type NextAuthOptions } from "next-auth"; +import CredentialsProvider from "next-auth/providers/credentials"; import GoogleProvider from "next-auth/providers/google"; -if ( - !process.env.GOOGLE_ID || - !process.env.GOOGLE_SECRET || - !process.env.NEXTAUTH_SECRET -) { - throw new Error("Google OAuth is not configured"); -} - -export const authConfig: NextAuthOptions = { - providers: [ - GoogleProvider({ - clientId: process.env.GOOGLE_ID, - clientSecret: process.env.GOOGLE_SECRET, - }), - ], - secret: process.env.NEXTAUTH_SECRET, - callbacks: { - async jwt({ token, account }) { - if (account?.providerAccountId && !token?.userId) { - // 初回ログイン時のみuserが存在します - const user = await prisma.user.upsert({ - where: { oauthId: account.providerAccountId }, - update: {}, - create: { - id: generateId(), - oauthId: account.providerAccountId, +export const authConfig: NextAuthOptions = + process.env.GOOGLE_ID && process.env.GOOGLE_SECRET + ? { + providers: [ + GoogleProvider({ + clientId: process.env.GOOGLE_ID, + clientSecret: process.env.GOOGLE_SECRET, + }), + ], + secret: process.env.NEXTAUTH_SECRET, + callbacks: { + async jwt({ token, account }) { + if (account?.providerAccountId && !token?.userId) { + // 初回ログイン時のみuserが存在します + const user = await prisma.user.upsert({ + where: { oauthId: account.providerAccountId }, + update: {}, + create: { + id: generateId(), + oauthId: account.providerAccountId, + }, + }); + const userId: string = user.id; + token.userId = userId; // userオブジェクトに保存されているカスタム値をトークンに追加します + } + return token; + }, + async session({ session, token }) { + // トークンからセッションにカスタム値を追加します + session.custom = { + userId: + typeof token.userId === "string" + ? token.userId + : neverReach("token.userId is not string"), + }; + return session; }, - }); - const userId: string = user.id; - token.userId = userId; // userオブジェクトに保存されているカスタム値をトークンに追加します + }, } - return token; - }, - async session({ session, token }) { - // トークンからセッションにカスタム値を追加します - session.custom = { - userId: - typeof token.userId === "string" - ? token.userId - : neverReach("token.userId is not string"), - }; - return session; - }, - }, -}; + : process.env.MOCK_LOGIN + ? { + providers: [ + CredentialsProvider({ + credentials: { + id: { label: "id", type: "text", placeholder: "User Id" }, + }, + authorize: function (credentials) { + return credentials?.id + ? { + id: credentials.id, + email: "example@example.com", + } + : null; + }, + }), + ], + secret: "secret", + callbacks: { + async jwt({ user, token }) { + if (user) { + // 初回ログイン時のみuserが存在します + const createdUser = await prisma.user.upsert({ + where: { oauthId: user.id }, + update: {}, + create: { + id: user.id, + }, + }); + const userId: string = createdUser.id; + token.userId = userId; // userオブジ + } + return token; + }, + async session({ session, token }) { + // トークンからセッションにカスタム値を追加します + session.custom = { + userId: + typeof token.userId === "string" + ? token.userId + : neverReach("token.userId is not string"), + }; + return session; + }, + }, + } + : neverReach("Google OAuth is not configured"); export default NextAuth(authConfig);