Update TypeScript version and enhance ContactForm and email handling

- Upgraded TypeScript dependency from 5.7.3 to 5.8.3 for improved type checking and features.
- Modified ContactForm component to include a hidden input for the domain, capturing the current hostname.
- Updated API contact handling to log and utilize the domain information in email notifications.
- Refactored email sending functions to conditionally include the domain in the sender's address for better context.
This commit is contained in:
2025-06-26 23:40:44 +02:00
parent 559bd3e983
commit 246edb3952
5 changed files with 31 additions and 13 deletions

2
package-lock.json generated
View File

@@ -67,7 +67,7 @@
"sharp": "0.33.5",
"tailwind-merge": "^2.6.0",
"tailwindcss": "^3.4.17",
"typescript": "^5.7.3",
"typescript": "^5.8.3",
"typescript-eslint": "^8.21.0",
"unist-util-visit": "^5.0.0"
},

View File

@@ -15,10 +15,10 @@
"astro": "astro",
"check": "npm run check:astro && npm run check:eslint && npm run check:prettier",
"check:astro": "astro check",
"check:eslint": "eslint .",
"check:eslint": "npx eslint .",
"check:prettier": "prettier --check .",
"fix": "npm run fix:eslint && npm run fix:prettier",
"fix:eslint": "eslint --fix .",
"fix:eslint": "npx eslint --fix .",
"fix:prettier": "prettier -w ."
},
"dependencies": {
@@ -81,7 +81,7 @@
"sharp": "0.33.5",
"tailwind-merge": "^2.6.0",
"tailwindcss": "^3.4.17",
"typescript": "^5.7.3",
"typescript": "^5.8.3",
"typescript-eslint": "^8.21.0",
"unist-util-visit": "^5.0.0"
}

View File

@@ -1,5 +1,6 @@
<form id="contact-form">
<input type="hidden" name="csrf_token" id="csrf_token" />
<input type="hidden" name="domain" id="domain" />
<label for="email">Email</label>
<input type="email" name="email" id="email" required aria-describedby="email-help" />
<div id="email-help" class="sr-only">Enter your email address</div>
@@ -43,7 +44,17 @@ async function fetchCsrfToken() {
}
}
document.addEventListener('DOMContentLoaded', fetchCsrfToken);
function setDomainHiddenField() {
const domainInput = document.getElementById('domain');
if (domainInput) {
(domainInput as HTMLInputElement).value = window.location.hostname;
}
}
document.addEventListener('DOMContentLoaded', () => {
fetchCsrfToken();
setDomainHiddenField();
});
const contactForm = document.getElementById('contact-form');
const feedbackDiv = document.getElementById('form-feedback');

View File

@@ -169,6 +169,7 @@ export const POST: APIRoute = async ({ request, clientAddress }) => {
const message = formData.get('message')?.toString() || '';
const disclaimer = formData.get('disclaimer')?.toString() === 'on';
const csrfToken = formData.get('csrf_token')?.toString() || '';
const domain = formData.get('domain')?.toString() || '';
console.log('Form data values:', {
name,
@@ -176,6 +177,7 @@ export const POST: APIRoute = async ({ request, clientAddress }) => {
messageLength: message.length,
disclaimer,
csrfToken: csrfToken ? 'present' : 'missing',
domain,
});
// Get user agent for logging and spam detection
@@ -255,11 +257,11 @@ export const POST: APIRoute = async ({ request, clientAddress }) => {
// Send emails
console.log('Attempting to send admin notification email');
const adminEmailSent = await sendAdminNotification(name, email, message, ipAddress, userAgent);
const adminEmailSent = await sendAdminNotification(name, email, message, ipAddress, userAgent, domain);
console.log('Admin email sent result:', adminEmailSent);
console.log('Attempting to send user confirmation email');
const userEmailSent = await sendUserConfirmation(name, email, message);
const userEmailSent = await sendUserConfirmation(name, email, message, domain);
console.log('User email sent result:', userEmailSent);
// Check if emails were sent successfully

View File

@@ -140,14 +140,18 @@ export function logEmailAttempt(success: boolean, recipient: string, subject: st
}
// Send an email
export async function sendEmail(to: string, subject: string, html: string, text: string): Promise<boolean> {
export async function sendEmail(to: string, subject: string, html: string, text: string, domain?: string): Promise<boolean> {
// Initialize transporter if not already done
if (!transporter) {
initializeTransporter();
}
try {
const fromAddress = isProduction ? `"${WEBSITE_NAME}" <${SMTP_USER || 'noreply@' + WEBSITE_NAME}>` : `"${WEBSITE_NAME}" <${ADMIN_EMAIL}>`;
const fromAddress = isProduction
? domain
? `"${WEBSITE_NAME}" <${SMTP_USER || 'info'}@${domain}>`
: `"${WEBSITE_NAME}" <${SMTP_USER || 'noreply@' + WEBSITE_NAME}>`
: `"${WEBSITE_NAME}" <${ADMIN_EMAIL}>`;
const mailOptions = {
from: fromAddress,
@@ -197,7 +201,8 @@ export async function sendAdminNotification(
email: string,
message: string,
ipAddress?: string,
userAgent?: string
userAgent?: string,
domain?: string
): Promise<boolean> {
// Validate inputs
if (!name || name.trim() === '') {
@@ -239,11 +244,11 @@ Time: ${new Date().toLocaleString()}
This message was sent from the contact form on ${WEBSITE_NAME}
`;
return sendEmail(ADMIN_EMAIL, subject, html, text);
return sendEmail(ADMIN_EMAIL, subject, html, text, domain);
}
// Send user confirmation email
export async function sendUserConfirmation(name: string, email: string, message: string): Promise<boolean> {
export async function sendUserConfirmation(name: string, email: string, message: string, domain?: string): Promise<boolean> {
// Validate inputs
if (!name || name.trim() === '') {
console.error('Cannot send user confirmation: name is empty');
@@ -280,7 +285,7 @@ ${WEBSITE_NAME} Team
This is an automated message, please do not reply directly to this email.
`;
return sendEmail(email, subject, html, text);
return sendEmail(email, subject, html, text, domain);
}
// Initialize the email system