From e6102b15bae5e45d4dad6251cfb1dd65c29cabdb Mon Sep 17 00:00:00 2001 From: Ashish Baravaliya Date: Wed, 27 Dec 2023 11:51:55 -0500 Subject: [PATCH 01/10] fix: sendmail debug --- src/pages/api/reset-password.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/api/reset-password.tsx b/src/pages/api/reset-password.tsx index 422885a..74bcdf6 100644 --- a/src/pages/api/reset-password.tsx +++ b/src/pages/api/reset-password.tsx @@ -57,6 +57,8 @@ export default async function handler( email, token: newToken, name: user.name, + }).catch((error) => { + console.error(error); }); return res .status(201) From 99caeec5287e638428be0aa500b0bb2b7585de76 Mon Sep 17 00:00:00 2001 From: Ashish Baravaliya Date: Wed, 27 Dec 2023 11:53:11 -0500 Subject: [PATCH 02/10] fix: sendmail debug --- src/pages/api/reset-password.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/api/reset-password.tsx b/src/pages/api/reset-password.tsx index 74bcdf6..9233a67 100644 --- a/src/pages/api/reset-password.tsx +++ b/src/pages/api/reset-password.tsx @@ -57,7 +57,7 @@ export default async function handler( email, token: newToken, name: user.name, - }).catch((error) => { + }).catch((error: any) => { console.error(error); }); return res From 9a92a1ee1207bd715398e3407d9d623ddb05fcc4 Mon Sep 17 00:00:00 2001 From: Ashish Baravaliya Date: Wed, 27 Dec 2023 11:58:34 -0500 Subject: [PATCH 03/10] fix: sendmail debug --- src/constants/email.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants/email.ts b/src/constants/email.ts index b28f04d..ed61515 100644 --- a/src/constants/email.ts +++ b/src/constants/email.ts @@ -1,4 +1,4 @@ -const web_url = process.env.NEXTAUTH_URL; +const web_url = "https://www.themeai.io"; export const getEmailHtml = ( type: "reset-password" | "activation" | "welcome", From 794ba9af36fde86886dd05ca2ecd28cb6142b94c Mon Sep 17 00:00:00 2001 From: Ashish Baravaliya Date: Wed, 27 Dec 2023 12:02:24 -0500 Subject: [PATCH 04/10] fix: sendmail debug --- src/pages/api/reset-password.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/api/reset-password.tsx b/src/pages/api/reset-password.tsx index 9233a67..0b29e8a 100644 --- a/src/pages/api/reset-password.tsx +++ b/src/pages/api/reset-password.tsx @@ -58,7 +58,7 @@ export default async function handler( token: newToken, name: user.name, }).catch((error: any) => { - console.error(error); + return res.status(201).json({ messsage: error.message }); }); return res .status(201) From 46c126190f4510c6e9e9d3b7815e2e741575adfa Mon Sep 17 00:00:00 2001 From: Ashish Baravaliya Date: Wed, 27 Dec 2023 12:06:31 -0500 Subject: [PATCH 05/10] fix: sendmail debug --- src/pages/api/reset-password.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/api/reset-password.tsx b/src/pages/api/reset-password.tsx index 0b29e8a..cef765d 100644 --- a/src/pages/api/reset-password.tsx +++ b/src/pages/api/reset-password.tsx @@ -58,7 +58,7 @@ export default async function handler( token: newToken, name: user.name, }).catch((error: any) => { - return res.status(201).json({ messsage: error.message }); + return res.status(400).json({ error: error.message }); }); return res .status(201) From 533b5ea219be6a3e96a6e8cbd58f3ad86570785b Mon Sep 17 00:00:00 2001 From: Ashish Baravaliya Date: Wed, 27 Dec 2023 12:12:38 -0500 Subject: [PATCH 06/10] fix: sendmail debug --- src/constants/website.tsx | 2 +- src/pages/api/reset-password.tsx | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/constants/website.tsx b/src/constants/website.tsx index cb60e6a..6db6d45 100644 --- a/src/constants/website.tsx +++ b/src/constants/website.tsx @@ -123,7 +123,7 @@ export const privacyPolicy: PrivacyPolicyProps[] = [ "Please contact us with any questions or comments about this Privacy Policy, Our Privacy Policy Toward Children, your personal information, and our third-party disclosure practices, at " } - contact@aithemes.io + contact@themeai.io .

diff --git a/src/pages/api/reset-password.tsx b/src/pages/api/reset-password.tsx index cef765d..8fde050 100644 --- a/src/pages/api/reset-password.tsx +++ b/src/pages/api/reset-password.tsx @@ -57,12 +57,15 @@ export default async function handler( email, token: newToken, name: user.name, - }).catch((error: any) => { - return res.status(400).json({ error: error.message }); - }); - return res - .status(201) - .json({ messsage: "Reset password mail has been sent" }); + }) + .then(() => { + return res + .status(201) + .json({ messsage: "Reset password mail has been sent" }); + }) + .catch((error: any) => { + return res.status(400).json({ error: error.message }); + }); } catch (error) { res.status(500).json({ error: "Failed to send reset password mail" }); } From b856e0e917420cdf5b589cdd2e194b4138e5d691 Mon Sep 17 00:00:00 2001 From: Ashish Baravaliya Date: Wed, 27 Dec 2023 12:21:02 -0500 Subject: [PATCH 07/10] fix: sendmail debug --- src/config/mailgun.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/config/mailgun.ts b/src/config/mailgun.ts index 04de4b2..bd3c82f 100644 --- a/src/config/mailgun.ts +++ b/src/config/mailgun.ts @@ -2,6 +2,7 @@ import Mailgun from "mailgun.js"; import FormData from "form-data"; import { getEmailHtml } from "@/constants/email"; import fs from "fs"; +import path from "path"; const mailgun: any = new Mailgun(FormData as any); @@ -23,7 +24,7 @@ export const sendEmail = ( ) => { const inlineImage = { filename: "logo.png", - data: fs.createReadStream("public/logo.png"), + data: fs.createReadStream(path.join(__dirname, "public", "logo.png")), cid: "logo.png", }; From 5709d8327bba10c62eb45bce3e7e3058498cddd8 Mon Sep 17 00:00:00 2001 From: Ashish Baravaliya Date: Wed, 27 Dec 2023 12:33:51 -0500 Subject: [PATCH 08/10] fix: sendmail debug --- src/config/mailgun.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/mailgun.ts b/src/config/mailgun.ts index bd3c82f..273aa98 100644 --- a/src/config/mailgun.ts +++ b/src/config/mailgun.ts @@ -24,7 +24,7 @@ export const sendEmail = ( ) => { const inlineImage = { filename: "logo.png", - data: fs.createReadStream(path.join(__dirname, "public", "logo.png")), + data: fs.createReadStream(path.join(process.cwd(), "public", "logo.png")), cid: "logo.png", }; From 665e23209dadefbac0d970b80b31aa5b88677f74 Mon Sep 17 00:00:00 2001 From: Ashish Baravaliya Date: Fri, 29 Dec 2023 11:26:54 -0500 Subject: [PATCH 09/10] feat: smtp added --- .github/workflows/pr-check.yml | 5 ++ __tests__/api/reset-password.test.ts | 11 +-- __tests__/api/send-verification-email.test.ts | 8 ++- package-lock.json | 69 ++++++------------- package.json | 5 +- src/components/export-theme-dialog.tsx | 4 +- src/components/ui/carousel.tsx | 13 +++- src/config/mail.ts | 43 ++++++++++++ src/config/mailgun.ts | 42 ----------- src/constants/email.ts | 2 +- src/constants/user.ts | 2 +- src/pages/api/reset-password.tsx | 38 +++++++--- src/pages/api/send-verification-email.ts | 24 +++++-- src/pages/api/themes.ts | 4 +- 14 files changed, 145 insertions(+), 125 deletions(-) create mode 100644 src/config/mail.ts delete mode 100644 src/config/mailgun.ts diff --git a/.github/workflows/pr-check.yml b/.github/workflows/pr-check.yml index 47aede0..73ffcf4 100644 --- a/.github/workflows/pr-check.yml +++ b/.github/workflows/pr-check.yml @@ -36,6 +36,11 @@ jobs: echo "EMAIL_LINK_EXPIRY=${{ secrets.EMAIL_LINK_EXPIRY }}" >> .env echo "THEMES_PER_PAGE=${{ secrets.THEMES_PER_PAGE }}" >> .env echo "NEXT_PUBLIC_TRACKING_ID=${{ secrets.TRACKING_ID }}" >> .env + echo "THEMEAI_ACCOUNT_ID=${{ secrets.THEMEAI_ACCOUNT_ID }}" >> .env + echo "MAIL_SMTP_HOST=${{ secrets.MAIL_SMTP_HOST }}" >> .env + echo "MAIL_SMTP_PORT=${{ secrets.MAIL_SMTP_PORT }}" >> .env + echo "MAIL_SMTP_USER=${{ secrets.MAIL_SMTP_USER }}" >> .env + echo "MAIL_SMTP_PASS=${{ secrets.MAIL_SMTP_PASS }}" >> .env - name: Build run: npm run build diff --git a/__tests__/api/reset-password.test.ts b/__tests__/api/reset-password.test.ts index 8b0a295..4218f51 100644 --- a/__tests__/api/reset-password.test.ts +++ b/__tests__/api/reset-password.test.ts @@ -1,4 +1,4 @@ -import { sendEmail } from "@/config/mailgun"; +import { sendEmail } from "@/config/mail"; import db from "@/db"; import handler from "@/pages/api/reset-password"; import { NextApiRequest, NextApiResponse } from "next"; @@ -53,13 +53,15 @@ describe("Reset Password API Endpoint", () => { (db.query.users.findFirst as jest.Mock).mockResolvedValue(null); (sendEmail as jest.Mock).mockResolvedValue({ id: "message-id", - message: "Verification mail has been sent", + message: + "Reset password mail has been sent. The reset password link is valid for 60 minutes.", }); await handler(req, res); expect(res.status).toHaveBeenCalledWith(201); expect(res.json).toHaveBeenCalledWith({ - messsage: "Reset password mail has been sent", + messsage: + "Reset password mail has been sent. The reset password link is valid for 60 minutes.", }); }); @@ -112,7 +114,8 @@ describe("Reset Password API Endpoint", () => { expect((db.insert as jest.Mock)().values).toHaveBeenCalled(); expect(res.status).toHaveBeenCalledWith(201); expect(res.json).toHaveBeenCalledWith({ - messsage: "Reset password mail has been sent", + messsage: + "Reset password mail has been sent. The reset password link is valid for 60 minutes.", }); }); diff --git a/__tests__/api/send-verification-email.test.ts b/__tests__/api/send-verification-email.test.ts index f34b744..db24030 100644 --- a/__tests__/api/send-verification-email.test.ts +++ b/__tests__/api/send-verification-email.test.ts @@ -1,4 +1,4 @@ -import { sendEmail } from "@/config/mailgun"; +import { sendEmail } from "@/config/mail"; import db from "@/db"; import handler from "@/pages/api/send-verification-email"; import { NextApiRequest, NextApiResponse } from "next"; @@ -111,7 +111,8 @@ describe("Send Verification Email API Endpoint", () => { }); (sendEmail as jest.Mock).mockResolvedValue({ id: "message-id", - message: "Verification mail has been sent", + message: + "Verification mail has been sent. The verification link is valid for 60 minutes.", }); await handler(req, res); @@ -120,7 +121,8 @@ describe("Send Verification Email API Endpoint", () => { expect((db.insert as jest.Mock)().values).toHaveBeenCalled(); expect(res.status).toHaveBeenCalledWith(201); expect(res.json).toHaveBeenCalledWith({ - messsage: "Verification mail has been sent", + messsage: + "Verification mail has been sent. The verification link is valid for 60 minutes.", }); }); diff --git a/package-lock.json b/package-lock.json index 4b0f63f..79630e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,11 +38,11 @@ "eslint-config-next": "13.4.13", "lorem-ipsum": "^2.0.8", "lucide-react": "0.263.1", - "mailgun.js": "^9.4.0", "moment": "^2.29.4", "next": "13.4.13", "next-auth": "^4.23.1", "nextjs-progressbar": "^0.0.16", + "nodemailer": "^6.9.7", "openai": "^4.16.1", "pg": "^8.11.3", "postcss": "8.4.27", @@ -63,6 +63,7 @@ "@testing-library/react": "^14.1.0", "@types/bcrypt": "^5.0.0", "@types/jest": "^29.5.8", + "@types/nodemailer": "^6.4.14", "@types/react-color": "^3.0.6", "@types/react-transition-group": "^4.4.6", "dotenv": "^16.3.1", @@ -3293,6 +3294,15 @@ "form-data": "^4.0.0" } }, + "node_modules/@types/nodemailer": { + "version": "6.4.14", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.14.tgz", + "integrity": "sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/nprogress": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@types/nprogress/-/nprogress-0.2.3.tgz", @@ -8042,21 +8052,6 @@ "lz-string": "bin/bin.js" } }, - "node_modules/mailgun.js": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-9.4.0.tgz", - "integrity": "sha512-BT+v4q0OEgmn5a8Nx0tgtHJ4OaerbVCo9gUskXVuF65HQd9hsz9AmUNXHAK4PtUlQDBA7wrPI9jiWVbfVuR8NQ==", - "dependencies": { - "axios": "^1.6.0", - "base-64": "^1.0.0", - "url-join": "^4.0.1" - } - }, - "node_modules/mailgun.js/node_modules/base-64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", - "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==" - }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -8458,8 +8453,6 @@ "version": "6.9.7", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.7.tgz", "integrity": "sha512-rUtR77ksqex/eZRLmQ21LKVH5nAAsVicAtAYudK7JgwenEDZ0UIQ1adUGqErz7sMkWYxWTTU1aeP2Jga6WQyJw==", - "optional": true, - "peer": true, "engines": { "node": ">=6.0.0" } @@ -10639,11 +10632,6 @@ "punycode": "^2.1.0" } }, - "node_modules/url-join": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" - }, "node_modules/use-callback-ref": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", @@ -13110,6 +13098,15 @@ "form-data": "^4.0.0" } }, + "@types/nodemailer": { + "version": "6.4.14", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.14.tgz", + "integrity": "sha512-fUWthHO9k9DSdPCSPRqcu6TWhYyxTBg382vlNIttSe9M7XfsT06y0f24KHXtbnijPGGRIcVvdKHTNikOI6qiHA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/nprogress": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@types/nprogress/-/nprogress-0.2.3.tgz", @@ -16563,23 +16560,6 @@ "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true }, - "mailgun.js": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/mailgun.js/-/mailgun.js-9.4.0.tgz", - "integrity": "sha512-BT+v4q0OEgmn5a8Nx0tgtHJ4OaerbVCo9gUskXVuF65HQd9hsz9AmUNXHAK4PtUlQDBA7wrPI9jiWVbfVuR8NQ==", - "requires": { - "axios": "^1.6.0", - "base-64": "^1.0.0", - "url-join": "^4.0.1" - }, - "dependencies": { - "base-64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", - "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==" - } - } - }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -16852,9 +16832,7 @@ "nodemailer": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.7.tgz", - "integrity": "sha512-rUtR77ksqex/eZRLmQ21LKVH5nAAsVicAtAYudK7JgwenEDZ0UIQ1adUGqErz7sMkWYxWTTU1aeP2Jga6WQyJw==", - "optional": true, - "peer": true + "integrity": "sha512-rUtR77ksqex/eZRLmQ21LKVH5nAAsVicAtAYudK7JgwenEDZ0UIQ1adUGqErz7sMkWYxWTTU1aeP2Jga6WQyJw==" }, "nopt": { "version": "5.0.0", @@ -18335,11 +18313,6 @@ "punycode": "^2.1.0" } }, - "url-join": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" - }, "use-callback-ref": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", diff --git a/package.json b/package.json index e8d3bb1..7094344 100644 --- a/package.json +++ b/package.json @@ -43,11 +43,11 @@ "eslint-config-next": "13.4.13", "lorem-ipsum": "^2.0.8", "lucide-react": "0.263.1", - "mailgun.js": "^9.4.0", "moment": "^2.29.4", "next": "13.4.13", "next-auth": "^4.23.1", "nextjs-progressbar": "^0.0.16", + "nodemailer": "^6.9.7", "openai": "^4.16.1", "pg": "^8.11.3", "postcss": "8.4.27", @@ -68,6 +68,7 @@ "@testing-library/react": "^14.1.0", "@types/bcrypt": "^5.0.0", "@types/jest": "^29.5.8", + "@types/nodemailer": "^6.4.14", "@types/react-color": "^3.0.6", "@types/react-transition-group": "^4.4.6", "dotenv": "^16.3.1", @@ -77,4 +78,4 @@ "ts-node": "^10.9.1", "typescript": "^5.2.2" } -} \ No newline at end of file +} diff --git a/src/components/export-theme-dialog.tsx b/src/components/export-theme-dialog.tsx index ab0a36d..7a79fce 100644 --- a/src/components/export-theme-dialog.tsx +++ b/src/components/export-theme-dialog.tsx @@ -353,7 +353,7 @@ export const ExportThemeDialog: React.FC = ({ : "Secondary Font"}
- + */}