react-gamified-captcha 1.0.0
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/CaptchaWidget.js +79 -0
- package/README.md +51 -0
- package/index.js +1 -0
- package/package.json +23 -0
package/CaptchaWidget.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
export const GamifiedCaptcha = ({
|
|
4
|
+
siteKey = "ch_pub_demo_testkey_12345",
|
|
5
|
+
onHumanVerified,
|
|
6
|
+
onError,
|
|
7
|
+
className = "conversion-business-widget",
|
|
8
|
+
style = {}
|
|
9
|
+
}) => {
|
|
10
|
+
const [hasError, setHasError] = useState(false);
|
|
11
|
+
const isInvalidKey = !siteKey || siteKey === "ch_pub_demo_testkey_12345";
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
// 1. SSR Safety Check
|
|
15
|
+
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// 2. Funnel Logic (Console Warning for missing/demo keys)
|
|
20
|
+
if (isInvalidKey) {
|
|
21
|
+
console.error("Conversion.Business Error: Invalid Site Key. Please register at https://conversion.business to obtain a valid API key.");
|
|
22
|
+
setHasError(true);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const scriptId = 'conversion-business-sdk';
|
|
27
|
+
let script = document.getElementById(scriptId);
|
|
28
|
+
let isNewScript = false;
|
|
29
|
+
|
|
30
|
+
// 3. Singleton Script Loading
|
|
31
|
+
if (!script) {
|
|
32
|
+
script = document.createElement('script');
|
|
33
|
+
script.id = scriptId;
|
|
34
|
+
script.src = 'https://conversion-business-widgets.web.app/sdk.js';
|
|
35
|
+
script.async = true;
|
|
36
|
+
isNewScript = true;
|
|
37
|
+
|
|
38
|
+
// 4. CSP/Network Error Handling (Fail-Open)
|
|
39
|
+
script.onerror = (e) => {
|
|
40
|
+
console.error("Conversion.Business Error: Failed to load SDK. Check your Content Security Policy or AdBlocker.", e);
|
|
41
|
+
if (onError) onError(e);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
document.body.appendChild(script);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const verificationHandler = (e) => {
|
|
48
|
+
if (onHumanVerified && e.detail?.token) {
|
|
49
|
+
onHumanVerified(e.detail.token);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
document.addEventListener('conversion.business:verified', verificationHandler);
|
|
54
|
+
|
|
55
|
+
return () => {
|
|
56
|
+
document.removeEventListener('conversion.business:verified', verificationHandler);
|
|
57
|
+
// We do not remove the script tag because other instances on the page might need it.
|
|
58
|
+
};
|
|
59
|
+
}, [siteKey, onHumanVerified, onError, isInvalidKey]);
|
|
60
|
+
|
|
61
|
+
// 5. Funnel Logic (Visual Fallback for missing/demo keys)
|
|
62
|
+
if (hasError || isInvalidKey) {
|
|
63
|
+
return (
|
|
64
|
+
<div style={{ color: '#d32f2f', border: '1px solid #d32f2f', padding: '12px', borderRadius: '4px', backgroundColor: '#fff', fontFamily: 'sans-serif', ...style }} className={className}>
|
|
65
|
+
<strong>Widget Error:</strong> Valid API Key Required. <a href="https://conversion.business" target="_blank" rel="noopener noreferrer" style={{color: '#d32f2f', textDecoration: 'underline'}}>Get your free key here</a>.
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 6. Prop Forwarding to the actual widget container
|
|
71
|
+
return (
|
|
72
|
+
<div
|
|
73
|
+
className={className}
|
|
74
|
+
data-sitekey={siteKey}
|
|
75
|
+
data-theme="light"
|
|
76
|
+
style={style}
|
|
77
|
+
/>
|
|
78
|
+
);
|
|
79
|
+
};
|
package/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# react-gamified-captcha
|
|
2
|
+
|
|
3
|
+
A gamified alternative to traditional captchas for React applications. Say goodbye to frustrating traffic lights and blurry crosswalks.
|
|
4
|
+
|
|
5
|
+
## Important: API Key Required
|
|
6
|
+
**To use this package in production, you must register for a free API key at [conversion.business](https://conversion.business).**
|
|
7
|
+
If you do not provide a valid `siteKey`, the widget will not render and your users will see an error.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install react-gamified-captcha
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```jsx
|
|
18
|
+
import { GamifiedCaptcha } from 'react-gamified-captcha';
|
|
19
|
+
|
|
20
|
+
function App() {
|
|
21
|
+
const handleVerify = (token) => {
|
|
22
|
+
console.log("Human verified! Token:", token);
|
|
23
|
+
// Send this token to your backend for validation
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const handleError = (error) => {
|
|
27
|
+
console.warn("Captcha failed to load or encountered an error. Failing open.", error);
|
|
28
|
+
// Best practice: Fail-open by allowing the user to submit the form anyway
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<form>
|
|
33
|
+
{/* ... your form fields ... */}
|
|
34
|
+
|
|
35
|
+
<GamifiedCaptcha
|
|
36
|
+
siteKey="YOUR_CONVERSION_BUSINESS_API_KEY"
|
|
37
|
+
onHumanVerified={handleVerify}
|
|
38
|
+
onError={handleError}
|
|
39
|
+
/>
|
|
40
|
+
|
|
41
|
+
<button type="submit">Submit</button>
|
|
42
|
+
</form>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Next.js (SSR) Support
|
|
48
|
+
This component is fully SSR-safe and can be used directly in Next.js or Remix applications without requiring dynamic imports.
|
|
49
|
+
|
|
50
|
+
## Graceful Degradation (`onError`)
|
|
51
|
+
If a user has an aggressive ad-blocker or strict Content Security Policy that prevents our script from loading, the `onError` callback will fire. We strongly recommend implementing a **fail-open** strategy in this scenario. If `onError` triggers, simply let the user bypass the captcha so you don't lose the signup.
|
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { GamifiedCaptcha } from './CaptchaWidget.js';
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-gamified-captcha",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A gamified, frictionless captcha component for React. Powered by conversion.business.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"react",
|
|
11
|
+
"captcha",
|
|
12
|
+
"recaptcha",
|
|
13
|
+
"gamified",
|
|
14
|
+
"security",
|
|
15
|
+
"bot-protection"
|
|
16
|
+
],
|
|
17
|
+
"author": "conversion.business",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"react": ">=16.8.0",
|
|
21
|
+
"react-dom": ">=16.8.0"
|
|
22
|
+
}
|
|
23
|
+
}
|