Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ yarn-error.log*
next-env.d.ts

.env
.env.production
.env.production
package-lock.json
1 change: 0 additions & 1 deletion src/app/[protected]/respondForm/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
26 changes: 21 additions & 5 deletions src/app/api/formResponses/route.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
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')

if (!formId) {
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: {
Expand All @@ -21,14 +27,23 @@ export const GET = auth(async function GET(req) {
fieldResponse: true
}
},
form: true
form: {
include: {
formCreators: true
}
}
}
});

if (!response) {
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) => ({
Expand All @@ -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) {
Expand Down Expand Up @@ -85,4 +101,4 @@ export async function POST(req: NextRequest) {
} finally {
await prisma.$disconnect();
}
}
})
26 changes: 26 additions & 0 deletions src/app/api/forms/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,26 @@ 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 {
if (!id) {
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: {
Expand Down Expand Up @@ -176,13 +189,26 @@ 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 {
if (!formId) {
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
Expand Down
35 changes: 25 additions & 10 deletions src/app/api/sendgrid/route.ts
Original file line number Diff line number Diff line change
@@ -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, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
}

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: `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en">
<head>
Expand All @@ -22,18 +39,16 @@ export const POST = async function POST(req: NextRequest) {
<meta name="author" content="SitePoint">
<meta http-equiv="Content-Type" content="text/html charset=UTF-8" />

<link rel="stylesheet" href="css/styles.css?v=1.0">

</head>

<body>
<div class="img-container" style="display: flex;justify-content: center;align-items: center;border-radius: 5px;overflow: hidden; font-family: 'helvetica', 'ui-sans';">
</div>
<div class="container" style="margin-left: 20px;margin-right: 20px;">
<h3>You've got a new mail from ${fullname}, their email is: ✉️${email} </h3>
<h3>You've got a new mail from ${safeFullname}, their email is: ✉️${safeEmail} </h3>
<div style="font-size: 16px;">
<p>Message:</p>
<p>${message}</p>
<p>${safeMessage}</p>
</div>
</body>
</html>
Expand All @@ -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 });
}
}
})
1 change: 0 additions & 1 deletion src/app/respondFormWithPublicLink/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down