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:
2
package-lock.json
generated
2
package-lock.json
generated
@@ -67,7 +67,7 @@
|
|||||||
"sharp": "0.33.5",
|
"sharp": "0.33.5",
|
||||||
"tailwind-merge": "^2.6.0",
|
"tailwind-merge": "^2.6.0",
|
||||||
"tailwindcss": "^3.4.17",
|
"tailwindcss": "^3.4.17",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.8.3",
|
||||||
"typescript-eslint": "^8.21.0",
|
"typescript-eslint": "^8.21.0",
|
||||||
"unist-util-visit": "^5.0.0"
|
"unist-util-visit": "^5.0.0"
|
||||||
},
|
},
|
||||||
|
@@ -15,10 +15,10 @@
|
|||||||
"astro": "astro",
|
"astro": "astro",
|
||||||
"check": "npm run check:astro && npm run check:eslint && npm run check:prettier",
|
"check": "npm run check:astro && npm run check:eslint && npm run check:prettier",
|
||||||
"check:astro": "astro check",
|
"check:astro": "astro check",
|
||||||
"check:eslint": "eslint .",
|
"check:eslint": "npx eslint .",
|
||||||
"check:prettier": "prettier --check .",
|
"check:prettier": "prettier --check .",
|
||||||
"fix": "npm run fix:eslint && npm run fix:prettier",
|
"fix": "npm run fix:eslint && npm run fix:prettier",
|
||||||
"fix:eslint": "eslint --fix .",
|
"fix:eslint": "npx eslint --fix .",
|
||||||
"fix:prettier": "prettier -w ."
|
"fix:prettier": "prettier -w ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
"sharp": "0.33.5",
|
"sharp": "0.33.5",
|
||||||
"tailwind-merge": "^2.6.0",
|
"tailwind-merge": "^2.6.0",
|
||||||
"tailwindcss": "^3.4.17",
|
"tailwindcss": "^3.4.17",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.8.3",
|
||||||
"typescript-eslint": "^8.21.0",
|
"typescript-eslint": "^8.21.0",
|
||||||
"unist-util-visit": "^5.0.0"
|
"unist-util-visit": "^5.0.0"
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
<form id="contact-form">
|
<form id="contact-form">
|
||||||
<input type="hidden" name="csrf_token" id="csrf_token" />
|
<input type="hidden" name="csrf_token" id="csrf_token" />
|
||||||
|
<input type="hidden" name="domain" id="domain" />
|
||||||
<label for="email">Email</label>
|
<label for="email">Email</label>
|
||||||
<input type="email" name="email" id="email" required aria-describedby="email-help" />
|
<input type="email" name="email" id="email" required aria-describedby="email-help" />
|
||||||
<div id="email-help" class="sr-only">Enter your email address</div>
|
<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 contactForm = document.getElementById('contact-form');
|
||||||
const feedbackDiv = document.getElementById('form-feedback');
|
const feedbackDiv = document.getElementById('form-feedback');
|
||||||
|
@@ -169,6 +169,7 @@ export const POST: APIRoute = async ({ request, clientAddress }) => {
|
|||||||
const message = formData.get('message')?.toString() || '';
|
const message = formData.get('message')?.toString() || '';
|
||||||
const disclaimer = formData.get('disclaimer')?.toString() === 'on';
|
const disclaimer = formData.get('disclaimer')?.toString() === 'on';
|
||||||
const csrfToken = formData.get('csrf_token')?.toString() || '';
|
const csrfToken = formData.get('csrf_token')?.toString() || '';
|
||||||
|
const domain = formData.get('domain')?.toString() || '';
|
||||||
|
|
||||||
console.log('Form data values:', {
|
console.log('Form data values:', {
|
||||||
name,
|
name,
|
||||||
@@ -176,6 +177,7 @@ export const POST: APIRoute = async ({ request, clientAddress }) => {
|
|||||||
messageLength: message.length,
|
messageLength: message.length,
|
||||||
disclaimer,
|
disclaimer,
|
||||||
csrfToken: csrfToken ? 'present' : 'missing',
|
csrfToken: csrfToken ? 'present' : 'missing',
|
||||||
|
domain,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Get user agent for logging and spam detection
|
// Get user agent for logging and spam detection
|
||||||
@@ -255,11 +257,11 @@ export const POST: APIRoute = async ({ request, clientAddress }) => {
|
|||||||
|
|
||||||
// Send emails
|
// Send emails
|
||||||
console.log('Attempting to send admin notification email');
|
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('Admin email sent result:', adminEmailSent);
|
||||||
|
|
||||||
console.log('Attempting to send user confirmation email');
|
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);
|
console.log('User email sent result:', userEmailSent);
|
||||||
|
|
||||||
// Check if emails were sent successfully
|
// Check if emails were sent successfully
|
||||||
|
@@ -140,14 +140,18 @@ export function logEmailAttempt(success: boolean, recipient: string, subject: st
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send an email
|
// 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
|
// Initialize transporter if not already done
|
||||||
if (!transporter) {
|
if (!transporter) {
|
||||||
initializeTransporter();
|
initializeTransporter();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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 = {
|
const mailOptions = {
|
||||||
from: fromAddress,
|
from: fromAddress,
|
||||||
@@ -197,7 +201,8 @@ export async function sendAdminNotification(
|
|||||||
email: string,
|
email: string,
|
||||||
message: string,
|
message: string,
|
||||||
ipAddress?: string,
|
ipAddress?: string,
|
||||||
userAgent?: string
|
userAgent?: string,
|
||||||
|
domain?: string
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
// Validate inputs
|
// Validate inputs
|
||||||
if (!name || name.trim() === '') {
|
if (!name || name.trim() === '') {
|
||||||
@@ -239,11 +244,11 @@ Time: ${new Date().toLocaleString()}
|
|||||||
This message was sent from the contact form on ${WEBSITE_NAME}
|
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
|
// 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
|
// Validate inputs
|
||||||
if (!name || name.trim() === '') {
|
if (!name || name.trim() === '') {
|
||||||
console.error('Cannot send user confirmation: name is empty');
|
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.
|
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
|
// Initialize the email system
|
||||||
|
Reference in New Issue
Block a user