diff --git a/api/.env b/api/.env deleted file mode 100644 index d32fc87..0000000 --- a/api/.env +++ /dev/null @@ -1 +0,0 @@ -MONGO_URI=mongodb+srv://User2:kanersdoghouse@bare-bones.pxrwg.mongodb.net/FlatFairDB?retryWrites=true&w=majority&appName=Bare-Bones diff --git a/api/assets/pww-logo.png b/api/assets/pww-logo.png new file mode 100644 index 0000000..c0f5a06 Binary files /dev/null and b/api/assets/pww-logo.png differ diff --git a/api/package-lock.json b/api/package-lock.json index 2078384..a3dc1d6 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "@sendgrid/mail": "^8.1.4", "axios": "^1.7.7", "cors": "^2.8.5", "dotenv": "^16.4.5", @@ -22,7 +23,7 @@ "devDependencies": { "@types/cors": "^2.8.17", "@types/express": "^4.17.21", - "@types/node": "^22.5.4", + "@types/node": "^22.8.1", "@types/uuid": "^10.0.0", "body-parser": "^1.20.3", "prettier": "^3.3.3", @@ -70,6 +71,41 @@ "sparse-bitfield": "^3.0.3" } }, + "node_modules/@sendgrid/client": { + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-8.1.4.tgz", + "integrity": "sha512-VxZoQ82MpxmjSXLR3ZAE2OWxvQIW2k2G24UeRPr/SYX8HqWLV/8UBN15T2WmjjnEb5XSmFImTJOKDzzSeKr9YQ==", + "dependencies": { + "@sendgrid/helpers": "^8.0.0", + "axios": "^1.7.4" + }, + "engines": { + "node": ">=12.*" + } + }, + "node_modules/@sendgrid/helpers": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-8.0.0.tgz", + "integrity": "sha512-Ze7WuW2Xzy5GT5WRx+yEv89fsg/pgy3T1E3FS0QEx0/VvRmigMZ5qyVGhJz4SxomegDkzXv/i0aFPpHKN8qdAA==", + "dependencies": { + "deepmerge": "^4.2.2" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/@sendgrid/mail": { + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-8.1.4.tgz", + "integrity": "sha512-MUpIZykD9ARie8LElYCqbcBhGGMaA/E6I7fEcG7Hc2An26QJyLtwOaKQ3taGp8xO8BICPJrSKuYV4bDeAJKFGQ==", + "dependencies": { + "@sendgrid/client": "^8.1.4", + "@sendgrid/helpers": "^8.0.0" + }, + "engines": { + "node": ">=12.*" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -155,11 +191,11 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.5.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", - "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", + "version": "22.8.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.1.tgz", + "integrity": "sha512-k6Gi8Yyo8EtrNtkHXutUu2corfDf9su95VYVP10aGYMMROM6SAItZi0w1XszA6RtWTHSVp5OeFof37w0IEqCQg==", "dependencies": { - "undici-types": "~6.19.2" + "undici-types": "~6.19.8" } }, "node_modules/@types/qs": { @@ -490,6 +526,14 @@ "ms": "2.0.0" } }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -1991,6 +2035,32 @@ "sparse-bitfield": "^3.0.3" } }, + "@sendgrid/client": { + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-8.1.4.tgz", + "integrity": "sha512-VxZoQ82MpxmjSXLR3ZAE2OWxvQIW2k2G24UeRPr/SYX8HqWLV/8UBN15T2WmjjnEb5XSmFImTJOKDzzSeKr9YQ==", + "requires": { + "@sendgrid/helpers": "^8.0.0", + "axios": "^1.7.4" + } + }, + "@sendgrid/helpers": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-8.0.0.tgz", + "integrity": "sha512-Ze7WuW2Xzy5GT5WRx+yEv89fsg/pgy3T1E3FS0QEx0/VvRmigMZ5qyVGhJz4SxomegDkzXv/i0aFPpHKN8qdAA==", + "requires": { + "deepmerge": "^4.2.2" + } + }, + "@sendgrid/mail": { + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-8.1.4.tgz", + "integrity": "sha512-MUpIZykD9ARie8LElYCqbcBhGGMaA/E6I7fEcG7Hc2An26QJyLtwOaKQ3taGp8xO8BICPJrSKuYV4bDeAJKFGQ==", + "requires": { + "@sendgrid/client": "^8.1.4", + "@sendgrid/helpers": "^8.0.0" + } + }, "@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -2076,11 +2146,11 @@ "dev": true }, "@types/node": { - "version": "22.5.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz", - "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", + "version": "22.8.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.1.tgz", + "integrity": "sha512-k6Gi8Yyo8EtrNtkHXutUu2corfDf9su95VYVP10aGYMMROM6SAItZi0w1XszA6RtWTHSVp5OeFof37w0IEqCQg==", "requires": { - "undici-types": "~6.19.2" + "undici-types": "~6.19.8" } }, "@types/qs": { @@ -2347,6 +2417,11 @@ "ms": "2.0.0" } }, + "deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==" + }, "define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", diff --git a/api/package.json b/api/package.json index e7d9129..07fd610 100644 --- a/api/package.json +++ b/api/package.json @@ -15,6 +15,7 @@ "author": "", "license": "ISC", "dependencies": { + "@sendgrid/mail": "^8.1.4", "axios": "^1.7.7", "cors": "^2.8.5", "dotenv": "^16.4.5", @@ -28,7 +29,7 @@ "devDependencies": { "@types/cors": "^2.8.17", "@types/express": "^4.17.21", - "@types/node": "^22.5.4", + "@types/node": "^22.8.1", "@types/uuid": "^10.0.0", "body-parser": "^1.20.3", "prettier": "^3.3.3", diff --git a/api/src/routes/user.ts b/api/src/routes/user.ts index b482219..0c938fb 100644 --- a/api/src/routes/user.ts +++ b/api/src/routes/user.ts @@ -1,7 +1,10 @@ -import express from "express" +import express from "express"; +import sgMail from "@sendgrid/mail"; -const router = express.Router() -const axios = require("axios").default +const router = express.Router(); +const axios = require("axios").default; + +router.use(express.json()); router.post("/test", async (req: any, res: any) => { console.log("Received group data:") @@ -10,4 +13,32 @@ router.post("/test", async (req: any, res: any) => { return res.status(200).json(name) }) -export default router +router.post("/send-email", async (req: any, res: any) => { + try { + const SENDGRID_API_KEY = process.env.SEND_GRID_API_KEY || ""; + const SEND_GRID_TEST_EMAIL = process.env.SEND_GRID_TEST_EMAIL || ""; + + if (SENDGRID_API_KEY === "" || SEND_GRID_TEST_EMAIL === "") { + throw new Error("SendGrid API key or test email is missing"); + } + + const { email, name } = req.body; + + sgMail.setApiKey(SENDGRID_API_KEY); + + await sgMail.send({ + to: email, + from: SEND_GRID_TEST_EMAIL, + templateId: "d-7e26b82cf8624bafa4077b6ed73b52bf", + dynamicTemplateData: { + name: name, + }, + }); + + return res.status(200).json({ message: "Email successfully sent" }); + } catch (err) { + return res.status(400).json({ message: "Email sending failed" }); + } +}); + +export default router; diff --git a/api/src/server.ts b/api/src/server.ts index 7543d60..ad15349 100644 --- a/api/src/server.ts +++ b/api/src/server.ts @@ -1,6 +1,6 @@ -import express from "express" +import express from "express"; import bodyParser from "body-parser" -import connectDB from "./config/db" +import connectDB from "./config/db"; import * as routes from "./routes/index"