init
This commit is contained in:
16
backend/.env.example
Normal file
16
backend/.env.example
Normal file
@@ -0,0 +1,16 @@
|
||||
# Server Configuration
|
||||
PORT=3001
|
||||
NODE_ENV=development
|
||||
|
||||
# Email Configuration
|
||||
SMTP_HOST=smtp.mail.me.com
|
||||
SMTP_PORT=587
|
||||
SMTP_USER=your-email@me.com
|
||||
SMTP_PASS=your-app-specific-password
|
||||
SMTP_FROM=your-email@me.com
|
||||
SMTP_TO=your-email@me.com
|
||||
|
||||
# Security
|
||||
CORS_ORIGIN=https://knck.pl
|
||||
RATE_LIMIT_WINDOW_MS=900000 # 15 minutes
|
||||
RATE_LIMIT_MAX_REQUESTS=5 # 5 requests per window
|
||||
18
backend/Dockerfile
Normal file
18
backend/Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
||||
FROM node:20-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm ci --only=production
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3001
|
||||
|
||||
# Start the application
|
||||
CMD ["npm", "start"]
|
||||
22
backend/package.json
Normal file
22
backend/package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "knck-contact-backend",
|
||||
"version": "1.0.0",
|
||||
"description": "Contact form backend for knck.pl",
|
||||
"main": "src/index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "node src/index.js",
|
||||
"dev": "nodemon src/index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^4.18.3",
|
||||
"express-rate-limit": "^7.1.5",
|
||||
"helmet": "^7.1.0",
|
||||
"nodemailer": "^6.9.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodemon": "^3.1.0"
|
||||
}
|
||||
}
|
||||
89
backend/src/index.js
Normal file
89
backend/src/index.js
Normal file
@@ -0,0 +1,89 @@
|
||||
import express from 'express';
|
||||
import cors from 'cors';
|
||||
import helmet from 'helmet';
|
||||
import rateLimit from 'express-rate-limit';
|
||||
import dotenv from 'dotenv';
|
||||
import nodemailer from 'nodemailer';
|
||||
|
||||
// Load environment variables
|
||||
dotenv.config();
|
||||
|
||||
const app = express();
|
||||
const port = process.env.PORT || 3001;
|
||||
|
||||
// Middleware
|
||||
app.use(helmet());
|
||||
app.use(express.json());
|
||||
app.use(cors({
|
||||
origin: process.env.CORS_ORIGIN,
|
||||
methods: ['POST']
|
||||
}));
|
||||
|
||||
// Rate limiting
|
||||
const limiter = rateLimit({
|
||||
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 900000, // 15 minutes
|
||||
max: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS) || 5 // 5 requests per window
|
||||
});
|
||||
app.use('/api/contact', limiter);
|
||||
|
||||
// Email transporter setup
|
||||
const transporter = nodemailer.createTransport({
|
||||
host: process.env.SMTP_HOST,
|
||||
port: parseInt(process.env.SMTP_PORT),
|
||||
secure: false,
|
||||
auth: {
|
||||
user: process.env.SMTP_USER,
|
||||
pass: process.env.SMTP_PASS
|
||||
}
|
||||
});
|
||||
|
||||
// Contact form endpoint
|
||||
app.post('/api/contact', async (req, res) => {
|
||||
try {
|
||||
const { name, email, message } = req.body;
|
||||
|
||||
// Validate input
|
||||
if (!name || !email || !message) {
|
||||
return res.status(400).json({ error: 'Missing required fields' });
|
||||
}
|
||||
|
||||
// Email content
|
||||
const mailOptions = {
|
||||
from: process.env.SMTP_FROM,
|
||||
to: process.env.SMTP_TO,
|
||||
subject: `New Contact Form Submission from ${name}`,
|
||||
text: `
|
||||
Name: ${name}
|
||||
Email: ${email}
|
||||
|
||||
Message:
|
||||
${message}
|
||||
`,
|
||||
html: `
|
||||
<h2>New Contact Form Submission</h2>
|
||||
<p><strong>Name:</strong> ${name}</p>
|
||||
<p><strong>Email:</strong> ${email}</p>
|
||||
<p><strong>Message:</strong></p>
|
||||
<p>${message.replace(/\n/g, '<br>')}</p>
|
||||
`
|
||||
};
|
||||
|
||||
// Send email
|
||||
await transporter.sendMail(mailOptions);
|
||||
|
||||
res.status(200).json({ message: 'Email sent successfully' });
|
||||
} catch (error) {
|
||||
console.error('Error sending email:', error);
|
||||
res.status(500).json({ error: 'Failed to send email' });
|
||||
}
|
||||
});
|
||||
|
||||
// Health check endpoint
|
||||
app.get('/health', (req, res) => {
|
||||
res.status(200).json({ status: 'ok' });
|
||||
});
|
||||
|
||||
// Start server
|
||||
app.listen(port, () => {
|
||||
console.log(`Server running on port ${port}`);
|
||||
});
|
||||
Reference in New Issue
Block a user