diff --git a/package-lock.json b/package-lock.json index 59872b4..bdbdc74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "handlebars": "^4.7.7", "jsonwebtoken": "^8.5.1", "mjml": "^4.11.0", + "nanoid": "^3.3.3", "nodemailer": "^6.7.0", "redis": "^3.1.2" }, @@ -2503,16 +2504,27 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "node_modules/mocha/node_modules/nanoid": { + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", + "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "node_modules/nanoid": { - "version": "3.1.25", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", - "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", - "dev": true, + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -5520,6 +5532,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true + }, + "nanoid": { + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", + "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", + "dev": true } } }, @@ -5529,10 +5547,9 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "nanoid": { - "version": "3.1.25", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", - "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", - "dev": true + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", + "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==" }, "negotiator": { "version": "0.6.2", diff --git a/package.json b/package.json index 9b40eca..dc7fbad 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "handlebars": "^4.7.7", "jsonwebtoken": "^8.5.1", "mjml": "^4.11.0", + "nanoid": "^3.3.3", "nodemailer": "^6.7.0", "redis": "^3.1.2" }, diff --git a/prisma/schema.prisma b/prisma/schema.prisma index cabd3e2..f06c9b0 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -101,6 +101,8 @@ model Participant { email String gender Gender + verified Boolean @default(false) + group Group @relation(fields: [groupId], references: [id]) groupId Int team Team @relation(name: "participants", fields: [teamId], references: [id]) diff --git a/src/Controllers/user_auth.controller.ts b/src/Controllers/user_auth.controller.ts new file mode 100644 index 0000000..cd8c94a --- /dev/null +++ b/src/Controllers/user_auth.controller.ts @@ -0,0 +1,56 @@ +import { Request, Response } from "express"; +import prisma from "../lib/prisma"; +import { mailClient } from "../lib/redis"; +import { nanoid } from "nanoid"; +import { verificationMail } from "../lib/mail"; + +export const register = async (req: Request, res: Response) => { + //TODO: Implemnt user endpoint and use following code to send verification mail + + const user = { + //Supposed to come from database + id: "10", + email: "test@test.com", + }; + + const usid = nanoid(); + + (await mailClient).set(usid, user.id); + + verificationMail(user.email, "eventname", usid); + + //Send status code +}; + +export const verifyEmail = async (req: Request, res: Response) => { + const { code } = req.body || {}; + + if (!(typeof code === "string")) { + return res.status(400).json({ + type: "error", + payload: { + message: "Invalid Request parameter", + }, + }); + } + + const acc = await mailClient.get(code); + + if (!acc) { + return res.status(404).json({ + type: "error", + payload: { + message: "Invalid token. It might be expired", + }, + }); + } + + prisma.participant.update({ + where: { + id: parseInt(acc), + }, + data: { + verified: true, + }, + }); +}; diff --git a/src/lib/mail.ts b/src/lib/mail.ts index a6f9d4b..4572b1e 100644 --- a/src/lib/mail.ts +++ b/src/lib/mail.ts @@ -1,6 +1,6 @@ import { writeFile } from "fs"; import Handlebars, { template } from "handlebars"; -import { emailClient } from "./redis"; +import { mailClient } from "./redis"; import nodemailer from "nodemailer"; import SMTPTransport from "nodemailer/lib/smtp-transport"; @@ -64,9 +64,6 @@ export const verificationMail = async (to: string, eventName: string, verificati const compiled = message(data); sendMail(mailAccount.user, to, "Verify Email", undefined, compiled); - - //TODO: Implement verification codes - //TODO: Write endpoints to verify codes }; export default { sendMail }; diff --git a/src/lib/redis.ts b/src/lib/redis.ts index afe01f5..b685446 100644 --- a/src/lib/redis.ts +++ b/src/lib/redis.ts @@ -3,6 +3,7 @@ import { promisify } from "util"; const REDIS_INDICES = { auth: 0, + mail: 1, }; const REDIS_HOST = process.env.REDIS_HOST || "redis"; @@ -24,4 +25,13 @@ const auth = redis.createClient({ host: REDIS_HOST, port: REDIS_PORT }); auth.select(REDIS_INDICES.auth); +// ----------------- // +// Redis mail client // +// ----------------- // + +const mail = redis.createClient({ host: REDIS_HOST, port: REDIS_PORT }); + +mail.select(REDIS_INDICES.mail); + export const authClient = createAsyncClient(auth); +export const mailClient = createAsyncClient(mail);