@marvalt/madapter 2.1.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +109 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +47 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +110 -4
- package/dist/index.esm.js.map +1 -1
- package/dist/react/components/MauticForm.d.ts.map +1 -1
- package/dist/react/components/TurnstileWidget.d.ts +47 -0
- package/dist/react/components/TurnstileWidget.d.ts.map +1 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/mautic-proxy.d.ts.map +1 -1
- package/dist/server/turnstile.d.ts +24 -0
- package/dist/server/turnstile.d.ts.map +1 -0
- package/dist/server.cjs +137 -0
- package/dist/server.cjs.map +1 -1
- package/dist/server.esm.js +137 -1
- package/dist/server.esm.js.map +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.cjs +13 -0
- package/templates/MAUTIC_SECURITY.md +308 -0
package/dist/index.cjs
CHANGED
|
@@ -2346,13 +2346,93 @@ const useMauticRemoveFromSegment = () => {
|
|
|
2346
2346
|
});
|
|
2347
2347
|
};
|
|
2348
2348
|
|
|
2349
|
+
const TurnstileWidget = ({ siteKey, onSuccess, onError, onExpire, theme = 'auto', size = 'normal', tabIndex, }) => {
|
|
2350
|
+
const widgetRef = React.useRef(null);
|
|
2351
|
+
const widgetId = React.useRef(null);
|
|
2352
|
+
const scriptLoaded = React.useRef(false);
|
|
2353
|
+
React.useEffect(() => {
|
|
2354
|
+
if (!widgetRef.current || !siteKey)
|
|
2355
|
+
return;
|
|
2356
|
+
const loadTurnstile = () => {
|
|
2357
|
+
if (window.turnstile && widgetRef.current && !widgetId.current) {
|
|
2358
|
+
try {
|
|
2359
|
+
widgetId.current = window.turnstile.render(widgetRef.current, {
|
|
2360
|
+
sitekey: siteKey,
|
|
2361
|
+
callback: onSuccess,
|
|
2362
|
+
'error-callback': onError,
|
|
2363
|
+
'expired-callback': onExpire,
|
|
2364
|
+
theme,
|
|
2365
|
+
size,
|
|
2366
|
+
tabindex: tabIndex,
|
|
2367
|
+
});
|
|
2368
|
+
}
|
|
2369
|
+
catch (error) {
|
|
2370
|
+
console.error('Failed to render Turnstile widget:', error);
|
|
2371
|
+
onError?.();
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
2374
|
+
};
|
|
2375
|
+
// Check if Turnstile is already loaded
|
|
2376
|
+
if (window.turnstile) {
|
|
2377
|
+
loadTurnstile();
|
|
2378
|
+
}
|
|
2379
|
+
else if (!scriptLoaded.current) {
|
|
2380
|
+
// Load Turnstile script
|
|
2381
|
+
scriptLoaded.current = true;
|
|
2382
|
+
const script = document.createElement('script');
|
|
2383
|
+
script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js';
|
|
2384
|
+
script.async = true;
|
|
2385
|
+
script.defer = true;
|
|
2386
|
+
script.onload = loadTurnstile;
|
|
2387
|
+
script.onerror = () => {
|
|
2388
|
+
console.error('Failed to load Turnstile script');
|
|
2389
|
+
onError?.();
|
|
2390
|
+
};
|
|
2391
|
+
document.head.appendChild(script);
|
|
2392
|
+
}
|
|
2393
|
+
return () => {
|
|
2394
|
+
if (widgetId.current && window.turnstile) {
|
|
2395
|
+
try {
|
|
2396
|
+
window.turnstile.remove(widgetId.current);
|
|
2397
|
+
}
|
|
2398
|
+
catch (error) {
|
|
2399
|
+
console.error('Failed to remove Turnstile widget:', error);
|
|
2400
|
+
}
|
|
2401
|
+
widgetId.current = null;
|
|
2402
|
+
}
|
|
2403
|
+
};
|
|
2404
|
+
}, [siteKey, onSuccess, onError, onExpire, theme, size, tabIndex]);
|
|
2405
|
+
return jsxRuntimeExports.jsx("div", { ref: widgetRef, className: "cf-turnstile" });
|
|
2406
|
+
};
|
|
2407
|
+
|
|
2349
2408
|
const MauticForm = ({ formId, title, description, className = '', form, onSubmit, onSuccess, onError, }) => {
|
|
2350
2409
|
const [formData, setFormData] = React.useState({});
|
|
2351
2410
|
const [errors, setErrors] = React.useState({});
|
|
2352
2411
|
const [isSubmitting, setIsSubmitting] = React.useState(false);
|
|
2353
2412
|
const [isSubmitted, setIsSubmitted] = React.useState(false);
|
|
2354
2413
|
const [showSuccessMessage, setShowSuccessMessage] = React.useState(false);
|
|
2414
|
+
const [turnstileToken, setTurnstileToken] = React.useState(null);
|
|
2355
2415
|
const submitMutation = useMauticFormSubmission();
|
|
2416
|
+
// Get Turnstile site key from environment
|
|
2417
|
+
const getTurnstilesiteKey = () => {
|
|
2418
|
+
// Check for Vite environment (browser)
|
|
2419
|
+
if (typeof window !== 'undefined' && window.import?.meta?.env) {
|
|
2420
|
+
return window.import.meta.env.VITE_TURNSTILE_SITE_KEY;
|
|
2421
|
+
}
|
|
2422
|
+
// Check for direct import.meta (Vite)
|
|
2423
|
+
try {
|
|
2424
|
+
// @ts-ignore - import.meta is a Vite-specific global
|
|
2425
|
+
if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)) }) !== 'undefined' && undefined) {
|
|
2426
|
+
// @ts-ignore
|
|
2427
|
+
return undefined.VITE_TURNSTILE_SITE_KEY;
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
catch (e) {
|
|
2431
|
+
// import.meta not available
|
|
2432
|
+
}
|
|
2433
|
+
return undefined;
|
|
2434
|
+
};
|
|
2435
|
+
const turnstilesiteKey = getTurnstilesiteKey();
|
|
2356
2436
|
React.useEffect(() => {
|
|
2357
2437
|
if (!form) {
|
|
2358
2438
|
console.warn(`Form ${formId} not found`);
|
|
@@ -2411,6 +2491,11 @@ const MauticForm = ({ formId, title, description, className = '', form, onSubmit
|
|
|
2411
2491
|
if (!validateForm()) {
|
|
2412
2492
|
return;
|
|
2413
2493
|
}
|
|
2494
|
+
// Check Turnstile token if enabled
|
|
2495
|
+
if (turnstilesiteKey && !turnstileToken) {
|
|
2496
|
+
setErrors(prev => ({ ...prev, _turnstile: 'Please complete the verification' }));
|
|
2497
|
+
return;
|
|
2498
|
+
}
|
|
2414
2499
|
setIsSubmitting(true);
|
|
2415
2500
|
setErrors({});
|
|
2416
2501
|
try {
|
|
@@ -2426,7 +2511,12 @@ const MauticForm = ({ formId, title, description, className = '', form, onSubmit
|
|
|
2426
2511
|
formId: parseInt(formId),
|
|
2427
2512
|
fields: formData,
|
|
2428
2513
|
returnUrl: window.location.href,
|
|
2429
|
-
...(derivedFormName ? { formName: derivedFormName } : {})
|
|
2514
|
+
...(derivedFormName ? { formName: derivedFormName } : {}),
|
|
2515
|
+
...(turnstileToken ? {
|
|
2516
|
+
headers: {
|
|
2517
|
+
'cf-turnstile-response': turnstileToken
|
|
2518
|
+
}
|
|
2519
|
+
} : {})
|
|
2430
2520
|
};
|
|
2431
2521
|
// Call custom onSubmit if provided
|
|
2432
2522
|
if (onSubmit) {
|
|
@@ -2515,7 +2605,23 @@ const MauticForm = ({ formId, title, description, className = '', form, onSubmit
|
|
|
2515
2605
|
return (jsxRuntimeExports.jsxs("form", { className: `mautic-form ${className}`, onSubmit: handleSubmit, children: [(title || form.name) && (jsxRuntimeExports.jsxs("div", { className: "form-header", children: [jsxRuntimeExports.jsx("h3", { children: title || form.name }), (description || form.description) && (jsxRuntimeExports.jsx("p", { className: "form-description", children: description || form.description }))] })), jsxRuntimeExports.jsx("div", { className: "form-fields", children: form.fields
|
|
2516
2606
|
// Filter out button/submit from field group; render them in actions
|
|
2517
2607
|
.filter((field) => field.type !== 'button' && field.alias !== 'submit')
|
|
2518
|
-
.map((field) => (jsxRuntimeExports.jsxs("div", { className: `form-field form-field-${field.type}`, children: [field.showLabel !== false && (jsxRuntimeExports.jsxs("label", { htmlFor: field.alias, className: "field-label", children: [field.label, field.isRequired && jsxRuntimeExports.jsx("span", { className: "required", children: "*" })] })), renderField(field), field.properties?.helpText && (jsxRuntimeExports.jsx("p", { className: "field-help", children: field.properties.helpText })), errors[field.alias] && (jsxRuntimeExports.jsx("p", { className: "field-error", children: errors[field.alias] }))] }, field.id))) }),
|
|
2608
|
+
.map((field) => (jsxRuntimeExports.jsxs("div", { className: `form-field form-field-${field.type}`, children: [field.showLabel !== false && (jsxRuntimeExports.jsxs("label", { htmlFor: field.alias, className: "field-label", children: [field.label, field.isRequired && jsxRuntimeExports.jsx("span", { className: "required", children: "*" })] })), renderField(field), field.properties?.helpText && (jsxRuntimeExports.jsx("p", { className: "field-help", children: field.properties.helpText })), errors[field.alias] && (jsxRuntimeExports.jsx("p", { className: "field-error", children: errors[field.alias] }))] }, field.id))) }), turnstilesiteKey && (jsxRuntimeExports.jsxs("div", { className: "form-turnstile", children: [jsxRuntimeExports.jsx(TurnstileWidget, { siteKey: turnstilesiteKey, onSuccess: (token) => {
|
|
2609
|
+
setTurnstileToken(token);
|
|
2610
|
+
// Clear any turnstile error
|
|
2611
|
+
if (errors._turnstile) {
|
|
2612
|
+
setErrors(prev => {
|
|
2613
|
+
const next = { ...prev };
|
|
2614
|
+
delete next._turnstile;
|
|
2615
|
+
return next;
|
|
2616
|
+
});
|
|
2617
|
+
}
|
|
2618
|
+
}, onError: () => {
|
|
2619
|
+
setTurnstileToken(null);
|
|
2620
|
+
setErrors(prev => ({ ...prev, _turnstile: 'Verification failed. Please try again.' }));
|
|
2621
|
+
}, onExpire: () => {
|
|
2622
|
+
setTurnstileToken(null);
|
|
2623
|
+
setErrors(prev => ({ ...prev, _turnstile: 'Verification expired. Please verify again.' }));
|
|
2624
|
+
}, theme: "auto", size: "normal" }), errors._turnstile && (jsxRuntimeExports.jsx("p", { className: "field-error turnstile-error", children: errors._turnstile }))] })), jsxRuntimeExports.jsx("div", { className: "form-actions", children: jsxRuntimeExports.jsx("button", { type: "submit", disabled: isSubmitting || (!!turnstilesiteKey && !turnstileToken), className: "submit-button", children: isSubmitting ? 'Submitting...' : 'Submit' }) }), submitMutation.error && (jsxRuntimeExports.jsx("div", { className: "form-error", children: jsxRuntimeExports.jsx("p", { children: "There was an error submitting the form. Please try again." }) }))] }));
|
|
2519
2625
|
};
|
|
2520
2626
|
|
|
2521
2627
|
const MauticTracking = ({ enabled, mauticUrl, proxyUrl, children }) => {
|
|
@@ -3076,6 +3182,7 @@ exports.MauticGenerator = MauticGenerator;
|
|
|
3076
3182
|
exports.MauticProvider = MauticProvider;
|
|
3077
3183
|
exports.MauticService = MauticService;
|
|
3078
3184
|
exports.MauticTracking = MauticTracking;
|
|
3185
|
+
exports.TurnstileWidget = TurnstileWidget;
|
|
3079
3186
|
exports.createMauticConfig = createMauticConfig;
|
|
3080
3187
|
exports.formatFormDataForSubmission = formatFormDataForSubmission;
|
|
3081
3188
|
exports.generateMauticData = generateMauticData;
|