Skip to content

Commit 3e7dc71

Browse files
committed
fix(forms): Patch CORS issues for contact form and job application submissions
- Add doOptions handler to Google Apps Script for proper CORS preflight handling - Simplify frontend API calls to use GET method by default to avoid preflight issues - Update both contact form and job application submission methods - Deploy backend with updated CORS configuration
1 parent a132eb0 commit 3e7dc71

File tree

2 files changed

+9
-131
lines changed

2 files changed

+9
-131
lines changed

backend/thinkREDBot.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ function doGet(e) {
3636
}
3737
}
3838

39+
// Handle OPTIONS requests for CORS preflight
40+
function doOptions(e) {
41+
return createCorsResponse({ success: true, message: 'CORS preflight OK' });
42+
}
43+
3944
function doPost(e) {
4045
try {
41-
// Handle preflight OPTIONS request in POST method
42-
if (e.parameter && e.parameter.method === 'OPTIONS') {
43-
return createCorsResponse({ success: true, message: 'CORS preflight OK' });
44-
}
45-
4646
const payload = JSON.parse(e.postData.contents);
4747
switch (payload.action) {
4848
case 'submitContactForm':

frontend/src/utils/api.ts

Lines changed: 4 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -41,60 +41,9 @@ export const submitContactForm = async (
4141
formData: ContactFormData
4242
): Promise<void> => {
4343
try {
44-
const response = await fetch(API_ENDPOINT, {
45-
method: 'POST',
46-
headers: {
47-
'Content-Type': 'application/json',
48-
},
49-
mode: 'cors',
50-
body: JSON.stringify({
51-
action: 'submitContactForm',
52-
data: formData,
53-
}),
54-
});
55-
56-
if (!response.ok) {
57-
throw new Error(`HTTP error! status: ${response.status}`);
58-
}
59-
60-
const result = await response.json();
61-
62-
if (result.error) {
63-
throw new Error(result.error);
64-
}
65-
66-
// Log successful submission
67-
logFormSubmission('contactForm', true);
44+
// Use GET method as primary approach for Google Apps Script to avoid CORS preflight issues
45+
await submitContactFormFallback(formData);
6846
} catch (error) {
69-
// Check if it's a CORS preflight error (common with Google Apps Script)
70-
if (
71-
error instanceof TypeError ||
72-
(error instanceof Error &&
73-
(error.message.includes('Failed to fetch') ||
74-
error.message.includes('CORS') ||
75-
error.message.includes('405')))
76-
) {
77-
// Try fallback GET method
78-
try {
79-
await submitContactFormFallback(formData);
80-
return;
81-
} catch (fallbackError) {
82-
// Log error for debugging in development
83-
if (process.env.NODE_ENV === 'development') {
84-
// eslint-disable-next-line no-console
85-
console.error('Both POST and fallback GET failed:', {
86-
originalError: error,
87-
fallbackError,
88-
});
89-
}
90-
91-
// Throw the fallback error as it's likely more informative
92-
throw new Error(
93-
'Unable to submit form. Please check your internet connection or try again later.'
94-
);
95-
}
96-
}
97-
9847
// Log error for debugging in development
9948
if (process.env.NODE_ENV === 'development') {
10049
// eslint-disable-next-line no-console
@@ -178,80 +127,9 @@ export const submitJobApplication = async (
178127
applicationData: JobApplicationData
179128
): Promise<void> => {
180129
try {
181-
// Convert files to base64
182-
const resumeBase64 = await fileToBase64(applicationData.resumeFile);
183-
184-
let coverLetterBase64: string | undefined;
185-
if (applicationData.coverLetterFile) {
186-
coverLetterBase64 = await fileToBase64(applicationData.coverLetterFile);
187-
}
188-
189-
const payload = {
190-
action: 'submitJobApplication',
191-
data: {
192-
jobId: applicationData.jobId,
193-
applicationId: applicationData.applicationId,
194-
name: applicationData.name,
195-
email: applicationData.email,
196-
phone: applicationData.phone,
197-
resumeBase64,
198-
coverLetterBase64,
199-
},
200-
};
201-
202-
const response = await fetch(API_ENDPOINT, {
203-
method: 'POST',
204-
headers: {
205-
'Content-Type': 'application/json',
206-
},
207-
body: JSON.stringify(payload),
208-
});
209-
210-
if (!response.ok) {
211-
throw new Error(`HTTP error! status: ${response.status}`);
212-
}
213-
214-
const result = await response.json();
215-
216-
if (result.error) {
217-
throw new Error(result.error);
218-
}
219-
220-
// Log successful submission
221-
logFormSubmission('jobApplication', true);
130+
// Use GET method as primary approach for Google Apps Script to avoid CORS preflight issues
131+
await submitJobApplicationFallback(applicationData);
222132
} catch (error) {
223-
// Check if it's a CORS preflight error (common with Google Apps Script)
224-
if (
225-
error instanceof TypeError ||
226-
(error instanceof Error &&
227-
(error.message.includes('Failed to fetch') ||
228-
error.message.includes('CORS') ||
229-
error.message.includes('405')))
230-
) {
231-
// Try fallback GET method
232-
try {
233-
await submitJobApplicationFallback(applicationData);
234-
return;
235-
} catch (fallbackError) {
236-
// Log error for debugging in development
237-
if (process.env.NODE_ENV === 'development') {
238-
// eslint-disable-next-line no-console
239-
console.error(
240-
'Both POST and fallback GET failed for job application:',
241-
{
242-
originalError: error,
243-
fallbackError,
244-
}
245-
);
246-
}
247-
248-
// Throw the fallback error as it's likely more informative
249-
throw new Error(
250-
'Unable to submit application. Please check your internet connection or try again later.'
251-
);
252-
}
253-
}
254-
255133
// Log error for debugging in development
256134
if (process.env.NODE_ENV === 'development') {
257135
// eslint-disable-next-line no-console

0 commit comments

Comments
 (0)