Compare commits
	
		
			3 Commits
		
	
	
		
			5c139e83f5
			...
			4656df7fca
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 4656df7fca | |||
| c96525e1fc | |||
| 4406de6986 | 
| @@ -1,4 +1,80 @@ | ||||
| "use server"; | ||||
|  | ||||
| import { createTransport } from "nodemailer"; | ||||
|  | ||||
| export async function getReCaptchaSiteKey() { | ||||
|   return process.env.RECAPTCHA_SITE_KEY; | ||||
| } | ||||
|  | ||||
| const RECAPTCHA_SERVER_KEY = process.env.RECAPTCHA_SERVER_KEY; | ||||
|  | ||||
| export type SubmitContactReturn = { error: string } | { success: true }; | ||||
|  | ||||
| export default async function SubmitContact( | ||||
|   prevState: unknown, | ||||
|   data: FormData | ||||
| ): Promise<SubmitContactReturn> { | ||||
|   if (!RECAPTCHA_SERVER_KEY) { | ||||
|     console.error( | ||||
|       "RECAPTCHA_SERVER_KEY is not set. Please check your environment variables." | ||||
|     ); | ||||
|     throw new Error("Server error: RECAPTCHA not configure correctly."); | ||||
|   } | ||||
|  | ||||
|   const name = data.get("name"); | ||||
|   const email = data.get("email"); | ||||
|   const message = data.get("message"); | ||||
|   const recaptcha = data.get("g-recaptcha-response"); | ||||
|  | ||||
|   if (!name || !email || !message) { | ||||
|     return { error: "All fields are required." }; | ||||
|   } | ||||
|  | ||||
|   if (!recaptcha) { | ||||
|     return { error: "Please complete the reCAPTCHA." }; | ||||
|   } | ||||
|  | ||||
|   try { | ||||
|     const recaptchaResponse = await fetch( | ||||
|       `https://www.google.com/recaptcha/api/siteverify`, | ||||
|       { | ||||
|         method: "POST", | ||||
|         headers: { | ||||
|           "Content-Type": "application/x-www-form-urlencoded", | ||||
|         }, | ||||
|         body: `secret=${RECAPTCHA_SERVER_KEY}&response=${recaptcha}`, | ||||
|       } | ||||
|     ); | ||||
|     const recaptchaData = await recaptchaResponse.json(); | ||||
|     if (!recaptchaData.success) { | ||||
|       return { error: "reCAPTCHA verification failed." }; | ||||
|     } | ||||
|   } catch (e) { | ||||
|     console.error(e); | ||||
|     return { error: "Could not reach reCAPTCHA for verification." }; | ||||
|   } | ||||
|  | ||||
|   try { | ||||
|     const transporter = createTransport({ | ||||
|       host: process.env.MAIL_HOST ?? "localhost", | ||||
|       port: process.env.MAIL_PORT ? parseInt(process.env.MAIL_PORT) : undefined, | ||||
|       secure: true, | ||||
|       auth: { | ||||
|         user: process.env.MAIL_USER, | ||||
|         pass: process.env.MAIL_PASS, | ||||
|       }, | ||||
|     }); | ||||
|     await transporter.sendMail({ | ||||
|       from: process.env.MAIL_FROM, | ||||
|       to: process.env.MAIL_TO, | ||||
|       subject: `From ${name}`, | ||||
|       replyTo: email.toString(), | ||||
|       text: `Name:${name}\nEmail: ${email}\nMessage:\n ${message}`, | ||||
|     }); | ||||
|   } catch (e) { | ||||
|     console.error(e); | ||||
|     return { error: "Failed to send email." }; | ||||
|   } | ||||
|  | ||||
|   return { success: true }; | ||||
| } | ||||
|   | ||||
| @@ -1,9 +1,8 @@ | ||||
| "use client"; | ||||
|  | ||||
| import SubmitContact from "@/components/contact"; | ||||
| import { useActionState, useEffect, useState } from "react"; | ||||
| import ReCAPTCHA from "react-google-recaptcha"; | ||||
| import { getReCaptchaSiteKey } from "./action"; | ||||
| import SubmitContact, { getReCaptchaSiteKey } from "./action"; | ||||
|  | ||||
| export default function ContactPage() { | ||||
|   const [recaptchaSiteKey, setRecaptchaSiteKey] = useState<string | undefined>( | ||||
|   | ||||
| @@ -1,5 +1,3 @@ | ||||
| /* eslint-disable react/no-unescaped-entities */ | ||||
|  | ||||
| "use client"; | ||||
|  | ||||
| import React from "react"; | ||||
|   | ||||
| @@ -1,76 +0,0 @@ | ||||
| "use server"; | ||||
|  | ||||
| import { createTransport } from "nodemailer"; | ||||
|  | ||||
| const RECAPTCHA_SECRET_KEY = process.env.RECAPTCHA_SECRET_KEY; | ||||
|  | ||||
| export type SubmitContactReturn = { error: string } | { success: true }; | ||||
|  | ||||
| export default async function SubmitContact( | ||||
|   prevState: unknown, | ||||
|   data: FormData | ||||
| ): Promise<SubmitContactReturn> { | ||||
|   if (!RECAPTCHA_SECRET_KEY) { | ||||
|     console.error( | ||||
|       "RECAPTCHA_SECRET_KEY is not set. Please check your environment variables." | ||||
|     ); | ||||
|     throw new Error("Server error: RECAPTCHA not configure correctly."); | ||||
|   } | ||||
|  | ||||
|   const name = data.get("name"); | ||||
|   const email = data.get("email"); | ||||
|   const message = data.get("message"); | ||||
|   const recaptcha = data.get("g-recaptcha-response"); | ||||
|  | ||||
|   if (!name || !email || !message) { | ||||
|     return { error: "All fields are required." }; | ||||
|   } | ||||
|  | ||||
|   if (!recaptcha) { | ||||
|     return { error: "Please complete the reCAPTCHA." }; | ||||
|   } | ||||
|  | ||||
|   try { | ||||
|     const recaptchaResponse = await fetch( | ||||
|       `https://www.google.com/recaptcha/api/siteverify`, | ||||
|       { | ||||
|         method: "POST", | ||||
|         headers: { | ||||
|           "Content-Type": "application/x-www-form-urlencoded", | ||||
|         }, | ||||
|         body: `secret=${RECAPTCHA_SECRET_KEY}&response=${recaptcha}`, | ||||
|       } | ||||
|     ); | ||||
|     const recaptchaData = await recaptchaResponse.json(); | ||||
|     if (!recaptchaData.success) { | ||||
|       return { error: "reCAPTCHA verification failed." }; | ||||
|     } | ||||
|   } catch (e) { | ||||
|     console.error(e); | ||||
|     return { error: "Could not reach reCAPTCHA for verification." }; | ||||
|   } | ||||
|  | ||||
|   try { | ||||
|     const transporter = createTransport({ | ||||
|       host: process.env.MAIL_HOST ?? "localhost", | ||||
|       port: process.env.MAIL_PORT ? parseInt(process.env.MAIL_PORT) : undefined, | ||||
|       secure: true, | ||||
|       auth: { | ||||
|         user: process.env.MAIL_USER, | ||||
|         pass: process.env.MAIL_PASS, | ||||
|       }, | ||||
|     }); | ||||
|     await transporter.sendMail({ | ||||
|       from: process.env.MAIL_FROM, | ||||
|       to: process.env.MAIL_TO, | ||||
|       subject: `From ${name}`, | ||||
|       replyTo: email.toString(), | ||||
|       text: `Name:${name}\nEmail: ${email}\nMessage:\n ${message}`, | ||||
|     }); | ||||
|   } catch (e) { | ||||
|     console.error(e); | ||||
|     return { error: "Failed to send email." }; | ||||
|   } | ||||
|  | ||||
|   return { success: true }; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user