From 6a059a9a599600e229aa99843c3d50d1c9125011 Mon Sep 17 00:00:00 2001 From: zenn Date: Tue, 12 May 2026 13:34:21 +0900 Subject: [PATCH] =?UTF-8?q?=ED=97=A4=EB=8D=94=20=EA=B2=80=EC=83=89=20?= =?UTF-8?q?=EC=A4=91=EC=95=99=20=EC=A0=95=EB=A0=AC=C2=B7Resend=20=EC=9D=B4?= =?UTF-8?q?=EB=A9=94=EC=9D=BC=20OTP=C2=B7=EB=B9=84=EB=B0=80=EB=B2=88?= =?UTF-8?q?=ED=98=B8=20=EC=B0=BE=EA=B8=B0=20(v0.0.99)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- .env.example | 5 + components/site/SiteHeader.vue | 18 +- db/migrations/018_email_otp_challenges.sql | 15 ++ docs/deploy.md | 13 + docs/history.md | 6 + docs/map.md | 16 +- docs/spec.md | 10 +- docs/update.md | 7 + nuxt.config.js | 3 + package.json | 2 +- pages/forgot-password.vue | 233 ++++++++++++++++++ pages/signin.vue | 5 + pages/signup.vue | 111 ++++++++- server/api/auth/bootstrap-status.get.js | 16 +- server/api/auth/email-otp/request.post.js | 164 ++++++++++++ server/api/auth/login.post.js | 3 +- .../api/auth/password-reset/confirm.post.js | 65 +++++ server/api/auth/signup.post.js | 56 ++++- server/repositories/email-otp-repository.js | 164 ++++++++++++ server/repositories/member-repository.js | 21 +- server/utils/email-otp.js | 43 ++++ server/utils/resend-mail.js | 42 ++++ 22 files changed, 984 insertions(+), 34 deletions(-) create mode 100644 db/migrations/018_email_otp_challenges.sql create mode 100644 pages/forgot-password.vue create mode 100644 server/api/auth/email-otp/request.post.js create mode 100644 server/api/auth/password-reset/confirm.post.js create mode 100644 server/repositories/email-otp-repository.js create mode 100644 server/utils/email-otp.js create mode 100644 server/utils/resend-mail.js diff --git a/.env.example b/.env.example index e7456eb..d591d30 100644 --- a/.env.example +++ b/.env.example @@ -24,5 +24,10 @@ AVATAR_WEBP_QUALITY=82 NUXT_PUBLIC_SITE_URL=https://sori.studio NUXT_PUBLIC_SITE_TITLE=sori.studio +# Transactional email (Resend, optional — 회원가입 OTP·비밀번호 찾기) +# RESEND_API_KEY= +# RESEND_FROM_EMAIL=noreply@yourdomain.com +# EMAIL_OTP_PEPPER=optional-extra-pepper + # Server APP_PORT=43118 diff --git a/components/site/SiteHeader.vue b/components/site/SiteHeader.vue index 106af7b..69a175b 100644 --- a/components/site/SiteHeader.vue +++ b/components/site/SiteHeader.vue @@ -152,8 +152,9 @@ onBeforeUnmount(() => {