diff --git a/.gitignore b/.gitignore index 06f0c25..a8e3b74 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,5 @@ yarn-error.log* next-env.d.ts .env -.env.production \ No newline at end of file +.env.production +package-lock.json \ No newline at end of file diff --git a/src/app/[protected]/respondForm/page.tsx b/src/app/[protected]/respondForm/page.tsx index b0a00af..6920657 100644 --- a/src/app/[protected]/respondForm/page.tsx +++ b/src/app/[protected]/respondForm/page.tsx @@ -54,7 +54,6 @@ const RespondForm = () => { const handleSave = async () => { mutation.mutate({ id: formId, - userId: session.data?.user?.id || null, formResponses: formFields.map((f, index) => ({ fieldResponse: f.response, formFieldId: f.id, diff --git a/src/app/api/formResponses/route.ts b/src/app/api/formResponses/route.ts index f61e907..e33c299 100644 --- a/src/app/api/formResponses/route.ts +++ b/src/app/api/formResponses/route.ts @@ -1,10 +1,12 @@ -import { NextRequest, NextResponse } from 'next/server'; +import { NextResponse } from 'next/server'; import { prisma } from '../../../prisma'; import { auth } from '@/auth'; export const GET = auth(async function GET(req) { if (!req.auth) return NextResponse.json({ message: "Not authenticated" }, { status: 401 }) + const userId = req.auth.user?.id + try { const formId = req.nextUrl.searchParams.get('id') @@ -12,6 +14,10 @@ export const GET = auth(async function GET(req) { return NextResponse.json({ error: 'Form not found' }, { status: 404 }); } + if (!userId) { + return NextResponse.json({ error: 'Server error' }, { status: 500 }); + } + const response = await prisma.formResponse.findUnique({ where: { id: formId }, select: { @@ -21,7 +27,11 @@ export const GET = auth(async function GET(req) { fieldResponse: true } }, - form: true + form: { + include: { + formCreators: true + } + } } }); @@ -29,6 +39,11 @@ export const GET = auth(async function GET(req) { return NextResponse.json({ error: 'Response not found' }, { status: 404 }); } + const isOwner = response.form.formCreators.some((fc: any) => fc.userId === userId); + if (!isOwner) { + return NextResponse.json({ error: 'Not authorized to view this response' }, { status: 403 }); + } + const data = { title: response.form.title, formFields: response.formFieldResponses.map((fr: any) => ({ @@ -46,8 +61,9 @@ export const GET = auth(async function GET(req) { } }) -export async function POST(req: NextRequest) { - const { id, userId, formResponses } = await req.json(); +export const POST = auth(async function POST(req) { + const { id, formResponses } = await req.json(); + const userId = req.auth?.user?.id ?? null; try { if (!id) { @@ -85,4 +101,4 @@ export async function POST(req: NextRequest) { } finally { await prisma.$disconnect(); } -} \ No newline at end of file +}) \ No newline at end of file diff --git a/src/app/api/forms/route.ts b/src/app/api/forms/route.ts index af69a2b..48349d8 100644 --- a/src/app/api/forms/route.ts +++ b/src/app/api/forms/route.ts @@ -121,6 +121,7 @@ export const POST = auth(async function POST(req) { export const PUT = auth(async function PUT(req) { if (!req.auth) return NextResponse.json({ message: "Not authenticated" }, { status: 401 }) + const userId = req.auth.user?.id const { id, title, formFields } = await req.json(); try { @@ -128,6 +129,18 @@ export const PUT = auth(async function PUT(req) { return NextResponse.json({ error: 'Form ID is required' }, { status: 400 }); } + if (!userId) { + return NextResponse.json({ error: 'Server error' }, { status: 500 }); + } + + const formCreator = await prisma.formCreator.findUnique({ + where: { userId_formId: { userId, formId: id } } + }); + + if (!formCreator) { + return NextResponse.json({ error: 'Not authorized to edit this form' }, { status: 403 }); + } + const updatedForm = await prisma.form.update({ where: { id: id }, data: { @@ -176,6 +189,7 @@ export const PUT = auth(async function PUT(req) { export const DELETE = auth(async function DELETE(req) { if (!req.auth) return NextResponse.json({ message: "Not authenticated" }, { status: 401 }) + const userId = req.auth.user?.id const formId = req.nextUrl.searchParams.get('id') try { @@ -183,6 +197,18 @@ export const DELETE = auth(async function DELETE(req) { return NextResponse.json({ error: 'Form not found' }, { status: 404 }); } + if (!userId) { + return NextResponse.json({ error: 'Server error' }, { status: 500 }); + } + + const formCreator = await prisma.formCreator.findUnique({ + where: { userId_formId: { userId, formId } } + }); + + if (!formCreator) { + return NextResponse.json({ error: 'Not authorized to delete this form' }, { status: 403 }); + } + await prisma.form.delete({ where: { id: formId diff --git a/src/app/api/sendgrid/route.ts b/src/app/api/sendgrid/route.ts index 51344cf..2e8f8a2 100644 --- a/src/app/api/sendgrid/route.ts +++ b/src/app/api/sendgrid/route.ts @@ -1,17 +1,34 @@ -import { NextResponse, NextRequest } from 'next/server'; +import { NextResponse } from 'next/server'; +import { auth } from '@/auth'; import sendgrid from '@sendgrid/mail'; sendgrid.setApiKey(String(process.env.SENDGRID_API_KEY)); -export const POST = async function POST(req: NextRequest) { +function escapeHtml(text: string): string { + return text + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} + +export const POST = auth(async function POST(req) { + if (!req.auth) return NextResponse.json({ message: "Not authenticated" }, { status: 401 }) + const { subject, fullname, email, message} = await req.json(); + const safeSubject = escapeHtml(subject); + const safeFullname = escapeHtml(fullname); + const safeEmail = escapeHtml(email); + const safeMessage = escapeHtml(message); + try { await sendgrid.send({ - to: 'easyform@gmail.com', // Your email where you'll receive emails - from: 'easyform@ziecon.com', // your website email address here - subject: `[Lead from website] : ${subject}`, + to: 'easyform@gmail.com', + from: 'easyform@ziecon.com', + subject: `[Lead from website] : ${safeSubject}`, html: ` @@ -22,18 +39,16 @@ export const POST = async function POST(req: NextRequest) { - -
-

You've got a new mail from ${fullname}, their email is: ✉️${email}

+

You've got a new mail from ${safeFullname}, their email is: ✉️${safeEmail}

Message:

-

${message}

+

${safeMessage}

@@ -44,4 +59,4 @@ export const POST = async function POST(req: NextRequest) { } catch (error: any) { return NextResponse.json({ error: error.message }, { status: error.statusCode || 500 }); } -} \ No newline at end of file +}) \ No newline at end of file diff --git a/src/app/respondFormWithPublicLink/page.tsx b/src/app/respondFormWithPublicLink/page.tsx index 2f023d6..306d183 100644 --- a/src/app/respondFormWithPublicLink/page.tsx +++ b/src/app/respondFormWithPublicLink/page.tsx @@ -54,7 +54,6 @@ const RespondFormWithPublicLink = () => { const handleSave = async () => { mutation.mutate({ id: formId, - userId: session.data?.user?.id || null, formResponses: formFields.map((f, index) => ({ fieldResponse: f.response, formFieldId: f.id,