@silverassist/recaptcha 0.1.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/CHANGELOG.md +45 -0
- package/LICENSE +135 -0
- package/README.md +240 -0
- package/dist/client/index.d.mts +75 -0
- package/dist/client/index.d.ts +75 -0
- package/dist/client/index.js +115 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/index.mjs +106 -0
- package/dist/client/index.mjs.map +1 -0
- package/dist/constants/index.d.mts +28 -0
- package/dist/constants/index.d.ts +28 -0
- package/dist/constants/index.js +19 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/constants/index.mjs +15 -0
- package/dist/constants/index.mjs.map +1 -0
- package/dist/index.d.mts +46 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +218 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +206 -0
- package/dist/index.mjs.map +1 -0
- package/dist/server/index.d.mts +79 -0
- package/dist/server/index.d.ts +79 -0
- package/dist/server/index.js +114 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/index.mjs +110 -0
- package/dist/server/index.mjs.map +1 -0
- package/dist/types/index.d.mts +97 -0
- package/dist/types/index.d.ts +97 -0
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/index.mjs +3 -0
- package/dist/types/index.mjs.map +1 -0
- package/package.json +123 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* reCAPTCHA v3 Integration Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for Google reCAPTCHA v3 integration with Next.js.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* reCAPTCHA v3 verification API response from Google
|
|
10
|
+
*
|
|
11
|
+
* @see https://developers.google.com/recaptcha/docs/verify
|
|
12
|
+
*/
|
|
13
|
+
interface RecaptchaVerifyResponse {
|
|
14
|
+
/** Whether the verification was successful */
|
|
15
|
+
success: boolean;
|
|
16
|
+
/** Score between 0.0 and 1.0 (1.0 = very likely human) */
|
|
17
|
+
score: number;
|
|
18
|
+
/** Action name from the client */
|
|
19
|
+
action: string;
|
|
20
|
+
/** Timestamp of the challenge (ISO format) */
|
|
21
|
+
challenge_ts: string;
|
|
22
|
+
/** Hostname of the site where reCAPTCHA was solved */
|
|
23
|
+
hostname: string;
|
|
24
|
+
/** Error codes if verification failed */
|
|
25
|
+
"error-codes"?: string[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Result of reCAPTCHA validation in server action
|
|
29
|
+
*/
|
|
30
|
+
interface RecaptchaValidationResult {
|
|
31
|
+
/** Whether the validation passed */
|
|
32
|
+
success: boolean;
|
|
33
|
+
/** The score from Google (0.0 - 1.0) */
|
|
34
|
+
score: number;
|
|
35
|
+
/** Error message if validation failed */
|
|
36
|
+
error?: string;
|
|
37
|
+
/** Whether validation was skipped (not configured) */
|
|
38
|
+
skipped?: boolean;
|
|
39
|
+
/** Raw response from Google API */
|
|
40
|
+
rawResponse?: RecaptchaVerifyResponse;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Props for RecaptchaWrapper client component
|
|
44
|
+
*/
|
|
45
|
+
interface RecaptchaWrapperProps {
|
|
46
|
+
/** Action name for reCAPTCHA analytics (e.g., "contact_form", "signup") */
|
|
47
|
+
action: string;
|
|
48
|
+
/** Name attribute for the hidden input (default: "recaptchaToken") */
|
|
49
|
+
inputName?: string;
|
|
50
|
+
/** ID attribute for the hidden input */
|
|
51
|
+
inputId?: string;
|
|
52
|
+
/** Override site key (default: uses NEXT_PUBLIC_RECAPTCHA_SITE_KEY) */
|
|
53
|
+
siteKey?: string;
|
|
54
|
+
/** Token refresh interval in ms (default: 90000 = 90 seconds) */
|
|
55
|
+
refreshInterval?: number;
|
|
56
|
+
/** Callback when token is generated */
|
|
57
|
+
onTokenGenerated?: (token: string) => void;
|
|
58
|
+
/** Callback when an error occurs */
|
|
59
|
+
onError?: (error: Error) => void;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Configuration options for reCAPTCHA validation
|
|
63
|
+
*/
|
|
64
|
+
interface RecaptchaConfig {
|
|
65
|
+
/** Google reCAPTCHA verification endpoint */
|
|
66
|
+
verifyUrl: string;
|
|
67
|
+
/** Default score threshold for validation */
|
|
68
|
+
defaultScoreThreshold: number;
|
|
69
|
+
/** Default token refresh interval in milliseconds */
|
|
70
|
+
tokenRefreshInterval: number;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Options for validateRecaptcha function
|
|
74
|
+
*/
|
|
75
|
+
interface RecaptchaValidationOptions {
|
|
76
|
+
/** Minimum score to pass (default: 0.5) */
|
|
77
|
+
scoreThreshold?: number;
|
|
78
|
+
/** Explicit secret key (default: uses RECAPTCHA_SECRET_KEY env) */
|
|
79
|
+
secretKey?: string;
|
|
80
|
+
/** Enable debug logging */
|
|
81
|
+
debug?: boolean;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Global window interface extension for reCAPTCHA
|
|
85
|
+
*/
|
|
86
|
+
declare global {
|
|
87
|
+
interface Window {
|
|
88
|
+
grecaptcha: {
|
|
89
|
+
ready: (callback: () => void) => void;
|
|
90
|
+
execute: (siteKey: string, options: {
|
|
91
|
+
action: string;
|
|
92
|
+
}) => Promise<string>;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export type { RecaptchaConfig, RecaptchaValidationOptions, RecaptchaValidationResult, RecaptchaVerifyResponse, RecaptchaWrapperProps };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* reCAPTCHA v3 Integration Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for Google reCAPTCHA v3 integration with Next.js.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* reCAPTCHA v3 verification API response from Google
|
|
10
|
+
*
|
|
11
|
+
* @see https://developers.google.com/recaptcha/docs/verify
|
|
12
|
+
*/
|
|
13
|
+
interface RecaptchaVerifyResponse {
|
|
14
|
+
/** Whether the verification was successful */
|
|
15
|
+
success: boolean;
|
|
16
|
+
/** Score between 0.0 and 1.0 (1.0 = very likely human) */
|
|
17
|
+
score: number;
|
|
18
|
+
/** Action name from the client */
|
|
19
|
+
action: string;
|
|
20
|
+
/** Timestamp of the challenge (ISO format) */
|
|
21
|
+
challenge_ts: string;
|
|
22
|
+
/** Hostname of the site where reCAPTCHA was solved */
|
|
23
|
+
hostname: string;
|
|
24
|
+
/** Error codes if verification failed */
|
|
25
|
+
"error-codes"?: string[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Result of reCAPTCHA validation in server action
|
|
29
|
+
*/
|
|
30
|
+
interface RecaptchaValidationResult {
|
|
31
|
+
/** Whether the validation passed */
|
|
32
|
+
success: boolean;
|
|
33
|
+
/** The score from Google (0.0 - 1.0) */
|
|
34
|
+
score: number;
|
|
35
|
+
/** Error message if validation failed */
|
|
36
|
+
error?: string;
|
|
37
|
+
/** Whether validation was skipped (not configured) */
|
|
38
|
+
skipped?: boolean;
|
|
39
|
+
/** Raw response from Google API */
|
|
40
|
+
rawResponse?: RecaptchaVerifyResponse;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Props for RecaptchaWrapper client component
|
|
44
|
+
*/
|
|
45
|
+
interface RecaptchaWrapperProps {
|
|
46
|
+
/** Action name for reCAPTCHA analytics (e.g., "contact_form", "signup") */
|
|
47
|
+
action: string;
|
|
48
|
+
/** Name attribute for the hidden input (default: "recaptchaToken") */
|
|
49
|
+
inputName?: string;
|
|
50
|
+
/** ID attribute for the hidden input */
|
|
51
|
+
inputId?: string;
|
|
52
|
+
/** Override site key (default: uses NEXT_PUBLIC_RECAPTCHA_SITE_KEY) */
|
|
53
|
+
siteKey?: string;
|
|
54
|
+
/** Token refresh interval in ms (default: 90000 = 90 seconds) */
|
|
55
|
+
refreshInterval?: number;
|
|
56
|
+
/** Callback when token is generated */
|
|
57
|
+
onTokenGenerated?: (token: string) => void;
|
|
58
|
+
/** Callback when an error occurs */
|
|
59
|
+
onError?: (error: Error) => void;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Configuration options for reCAPTCHA validation
|
|
63
|
+
*/
|
|
64
|
+
interface RecaptchaConfig {
|
|
65
|
+
/** Google reCAPTCHA verification endpoint */
|
|
66
|
+
verifyUrl: string;
|
|
67
|
+
/** Default score threshold for validation */
|
|
68
|
+
defaultScoreThreshold: number;
|
|
69
|
+
/** Default token refresh interval in milliseconds */
|
|
70
|
+
tokenRefreshInterval: number;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Options for validateRecaptcha function
|
|
74
|
+
*/
|
|
75
|
+
interface RecaptchaValidationOptions {
|
|
76
|
+
/** Minimum score to pass (default: 0.5) */
|
|
77
|
+
scoreThreshold?: number;
|
|
78
|
+
/** Explicit secret key (default: uses RECAPTCHA_SECRET_KEY env) */
|
|
79
|
+
secretKey?: string;
|
|
80
|
+
/** Enable debug logging */
|
|
81
|
+
debug?: boolean;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Global window interface extension for reCAPTCHA
|
|
85
|
+
*/
|
|
86
|
+
declare global {
|
|
87
|
+
interface Window {
|
|
88
|
+
grecaptcha: {
|
|
89
|
+
ready: (callback: () => void) => void;
|
|
90
|
+
execute: (siteKey: string, options: {
|
|
91
|
+
action: string;
|
|
92
|
+
}) => Promise<string>;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export type { RecaptchaConfig, RecaptchaValidationOptions, RecaptchaValidationResult, RecaptchaVerifyResponse, RecaptchaWrapperProps };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.mjs"}
|
package/package.json
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@silverassist/recaptcha",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Google reCAPTCHA v3 integration for Next.js applications with Server Actions support",
|
|
5
|
+
"author": "Miguel Colmenares <me@miguelcolmenares.com>",
|
|
6
|
+
"license": "Polyform-Noncommercial-1.0.0",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/SilverAssist/recaptcha.git"
|
|
10
|
+
},
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/SilverAssist/recaptcha/issues"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://github.com/SilverAssist/recaptcha#readme",
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"recaptcha",
|
|
20
|
+
"recaptcha-v3",
|
|
21
|
+
"google-recaptcha",
|
|
22
|
+
"nextjs",
|
|
23
|
+
"next",
|
|
24
|
+
"react",
|
|
25
|
+
"server-actions",
|
|
26
|
+
"spam-protection",
|
|
27
|
+
"bot-detection"
|
|
28
|
+
],
|
|
29
|
+
"main": "./dist/index.js",
|
|
30
|
+
"module": "./dist/index.mjs",
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"import": {
|
|
35
|
+
"types": "./dist/index.d.mts",
|
|
36
|
+
"default": "./dist/index.mjs"
|
|
37
|
+
},
|
|
38
|
+
"require": {
|
|
39
|
+
"types": "./dist/index.d.ts",
|
|
40
|
+
"default": "./dist/index.js"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"./client": {
|
|
44
|
+
"import": {
|
|
45
|
+
"types": "./dist/client/index.d.mts",
|
|
46
|
+
"default": "./dist/client/index.mjs"
|
|
47
|
+
},
|
|
48
|
+
"require": {
|
|
49
|
+
"types": "./dist/client/index.d.ts",
|
|
50
|
+
"default": "./dist/client/index.js"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"./server": {
|
|
54
|
+
"import": {
|
|
55
|
+
"types": "./dist/server/index.d.mts",
|
|
56
|
+
"default": "./dist/server/index.mjs"
|
|
57
|
+
},
|
|
58
|
+
"require": {
|
|
59
|
+
"types": "./dist/server/index.d.ts",
|
|
60
|
+
"default": "./dist/server/index.js"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"./types": {
|
|
64
|
+
"import": {
|
|
65
|
+
"types": "./dist/types/index.d.mts",
|
|
66
|
+
"default": "./dist/types/index.mjs"
|
|
67
|
+
},
|
|
68
|
+
"require": {
|
|
69
|
+
"types": "./dist/types/index.d.ts",
|
|
70
|
+
"default": "./dist/types/index.js"
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"./constants": {
|
|
74
|
+
"import": {
|
|
75
|
+
"types": "./dist/constants/index.d.mts",
|
|
76
|
+
"default": "./dist/constants/index.mjs"
|
|
77
|
+
},
|
|
78
|
+
"require": {
|
|
79
|
+
"types": "./dist/constants/index.d.ts",
|
|
80
|
+
"default": "./dist/constants/index.js"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"files": [
|
|
85
|
+
"dist",
|
|
86
|
+
"README.md",
|
|
87
|
+
"LICENSE",
|
|
88
|
+
"CHANGELOG.md"
|
|
89
|
+
],
|
|
90
|
+
"sideEffects": false,
|
|
91
|
+
"scripts": {
|
|
92
|
+
"build": "tsup && node add-use-client.js",
|
|
93
|
+
"dev": "tsup --watch",
|
|
94
|
+
"test": "jest",
|
|
95
|
+
"test:watch": "jest --watch",
|
|
96
|
+
"test:coverage": "jest --coverage",
|
|
97
|
+
"lint": "tsc --noEmit",
|
|
98
|
+
"clean": "rm -rf dist",
|
|
99
|
+
"prepublishOnly": "npm run clean && npm run lint && npm run build && npm run test",
|
|
100
|
+
"release": "npm run prepublishOnly && npm publish --access public"
|
|
101
|
+
},
|
|
102
|
+
"peerDependencies": {
|
|
103
|
+
"next": ">=14.0.0",
|
|
104
|
+
"react": ">=18.0.0",
|
|
105
|
+
"react-dom": ">=18.0.0"
|
|
106
|
+
},
|
|
107
|
+
"devDependencies": {
|
|
108
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
109
|
+
"@testing-library/react": "^16.3.2",
|
|
110
|
+
"@types/jest": "^30.0.0",
|
|
111
|
+
"@types/node": "^25.0.10",
|
|
112
|
+
"@types/react": "^19.2.9",
|
|
113
|
+
"@types/react-dom": "^19.2.3",
|
|
114
|
+
"jest": "^30.2.0",
|
|
115
|
+
"jest-environment-jsdom": "^30.2.0",
|
|
116
|
+
"next": "^16.1.5",
|
|
117
|
+
"react": "^19.2.4",
|
|
118
|
+
"react-dom": "^19.2.4",
|
|
119
|
+
"ts-jest": "^29.4.6",
|
|
120
|
+
"tsup": "^8.5.1",
|
|
121
|
+
"typescript": "^5.9.3"
|
|
122
|
+
}
|
|
123
|
+
}
|