ngx-recaptcha-v3 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.
Files changed (3) hide show
  1. package/CHANGELOG.md +0 -0
  2. package/README.md +275 -0
  3. package/package.json +83 -0
package/CHANGELOG.md ADDED
File without changes
package/README.md ADDED
@@ -0,0 +1,275 @@
1
+ # ngx-recaptcha-v3
2
+
3
+ A production-grade, enterprise-ready, tree-shakable Angular library for integrating Google reCAPTCHA v2 (Checkbox & Invisible), v3, and Enterprise. Fully compatible with Angular 12 through 22, SSR‑safe (Universal), and native Angular Signals‑ready.
4
+
5
+ ---
6
+
7
+ ## Key Features
8
+
9
+ - **Full Angular Compatibility**: Out‑of‑the‑box support for Angular 12 to 22.
10
+ - **First‑Class Signals Support**: Decoupled `ngx-recaptcha-v3/signals` entry point for modern reactive applications (Angular 16+).
11
+ - **SSR & Hydration Safe**: Strictly guards DOM operations on the server side using `isPlatformBrowser`.
12
+ - **Zoneless Support**: Executes heavy execution logic outside `Zone.js` context for high performance.
13
+ - **Dynamic Re‑Render**: V2 widget automatically re‑renders when inputs (theme, size, tabIndex, siteKey) change! No manual cleanup required!
14
+ - **Tree‑Shakable Secondary Entry Points**: Only import what you use (`core`, `v2`, `v3`, `enterprise`, `signals`, `forms`, `testing`).
15
+ - **ControlValueAccessor (CVA)**: Native support for Reactive Forms and Template‑driven Forms.
16
+ - **Region & Domain Flex**: Easily switch between `google.com` and `recaptcha.net` (for restricted regions).
17
+
18
+ ---
19
+
20
+ ## Folder & Entrypoint Architecture
21
+
22
+ To avoid breaking compilation in legacy Angular environments (versions 12–15) that do not support Signals, the codebase utilizes isolated secondary entry points:
23
+
24
+ - `ngx-recaptcha-v3/core`: Script loading lifecycle, dynamic configuration tokens.
25
+ - `ngx-recaptcha-v3/v2`: V2 Checkbox and Invisible component.
26
+ - `ngx-recaptcha-v3/v3`: Score‑based execution service.
27
+ - `ngx-recaptcha-v3/enterprise`: Score‑based Enterprise service.
28
+ - `ngx-recaptcha-v3/forms`: Angular Forms ControlValueAccessor directive.
29
+ - `ngx-recaptcha-v3/signals`: Reactive signals wrapper (Angular 16+ only).
30
+ - `ngx-recaptcha-v3/testing`: Mock services and providers for Jest/Karma test isolation.
31
+
32
+ ---
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ npm install ngx-recaptcha-v3
38
+ ```
39
+
40
+ Configure your global settings during the application bootstrap phase:
41
+
42
+ ### Standard Module Bootstrapping (Angular 12+)
43
+ ```typescript
44
+ import { NgModule } from '@angular/core';
45
+ import { BrowserModule } from '@angular/platform-browser';
46
+ import { RECAPTCHA_CONFIG, RecaptchaConfig } from 'ngx-recaptcha-v3/core';
47
+ import { AppComponent } from './app.component';
48
+
49
+ const recaptchaConfig: RecaptchaConfig = {
50
+ v2SiteKey: 'YOUR_V2_SITE_KEY',
51
+ v3SiteKey: 'YOUR_V3_SITE_KEY',
52
+ recaptchaDomain: 'google.com'
53
+ };
54
+
55
+ @NgModule({
56
+ declarations: [AppComponent],
57
+ imports: [BrowserModule],
58
+ providers: [
59
+ { provide: RECAPTCHA_CONFIG, useValue: recaptchaConfig }
60
+ ],
61
+ bootstrap: [AppComponent]
62
+ })
63
+ export class AppModule {}
64
+ ```
65
+
66
+ ### Standalone Bootstrapping (Angular 14+)
67
+ ```typescript
68
+ import { bootstrapApplication } from '@angular/platform-browser';
69
+ import { RECAPTCHA_CONFIG, RecaptchaConfig } from 'ngx-recaptcha-v3/core';
70
+ import { AppComponent } from './app/app.component';
71
+
72
+ bootstrapApplication(AppComponent, {
73
+ providers: [
74
+ {
75
+ provide: RECAPTCHA_CONFIG,
76
+ useValue: {
77
+ v2SiteKey: 'YOUR_V2_SITE_KEY',
78
+ v3SiteKey: 'YOUR_V3_SITE_KEY',
79
+ useEnterprise: false
80
+ } as RecaptchaConfig
81
+ }
82
+ ]
83
+ });
84
+ ```
85
+
86
+ ---
87
+
88
+ ## Usage Examples
89
+
90
+ ### 1. reCAPTCHA v2 Checkbox with Reactive Forms
91
+
92
+ ```typescript
93
+ import { Component, signal } from '@angular/core';
94
+ import { FormGroup, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
95
+ import { RecaptchaV2Component } from 'ngx-recaptcha-v3/v2';
96
+ import { RecaptchaValueAccessorDirective } from 'ngx-recaptcha-v3/forms';
97
+
98
+ @Component({
99
+ selector: 'app-login',
100
+ template: `
101
+ <form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
102
+ <input formControlName="username" type="text" placeholder="Username" />
103
+
104
+ <!-- Toggle theme to test dynamic re-render! -->
105
+ <div style="margin: 1rem 0;">
106
+ <label style="margin-right: 1rem;">
107
+ <input type="radio" [value]="'light'" (change)="setTheme('light')" [checked]="theme() === 'light'"> Light
108
+ </label>
109
+ <label>
110
+ <input type="radio" [value]="'dark'" (change)="setTheme('dark')" [checked]="theme() === 'dark'"> Dark
111
+ </label>
112
+ </div>
113
+
114
+ <!-- CVA Directive Automatically Binds value to FormGroup -->
115
+ <ngx-recaptcha-v3
116
+ [siteKey]="'YOUR_V2_SITE_KEY'"
117
+ [theme]="theme()"
118
+ formControlName="recaptcha">
119
+ </ngx-recaptcha-v3>
120
+
121
+ <button [disabled]="loginForm.invalid" type="submit">Login</button>
122
+ </form>
123
+ `,
124
+ standalone: true,
125
+ imports: [ReactiveFormsModule, RecaptchaV2Component, RecaptchaValueAccessorDirective]
126
+ })
127
+ export class LoginComponent {
128
+ theme = signal<'light' | 'dark'>('light');
129
+
130
+ loginForm = new FormGroup({
131
+ username: new FormControl('', Validators.required),
132
+ recaptcha: new FormControl(null, Validators.required)
133
+ });
134
+
135
+ setTheme(newTheme: 'light' | 'dark'): void {
136
+ this.theme.set(newTheme);
137
+ }
138
+
139
+ onSubmit() {
140
+ console.log(this.loginForm.value);
141
+ }
142
+ }
143
+ ```
144
+
145
+ **Dynamic Re‑Render Feature**: `RecaptchaV2Component` now supports automatic re‑rendering when any of its inputs (siteKey, theme, size, tabIndex) change! This means you can dynamically switch between light/dark themes, or normal/compact/invisible sizes at runtime without any manual cleanup!
146
+
147
+ ### 2. reCAPTCHA v3 Execution Service (RxJS & Promise)
148
+
149
+ ```typescript
150
+ import { Component, inject } from '@angular/core';
151
+ import { RecaptchaV3Service } from 'ngx-recaptcha-v3/v3';
152
+
153
+ @Component({
154
+ selector: 'app-payment',
155
+ template: `
156
+ <div style="display: flex; gap: 1rem;">
157
+ <button (click)="processPaymentRxjs()">Pay Now (RxJS)</button>
158
+ <button (click)="processPaymentAsync()">Pay Now (Async/Await)</button>
159
+ </div>
160
+ `,
161
+ standalone: true
162
+ })
163
+ export class PaymentComponent {
164
+ private recaptchaV3 = inject(RecaptchaV3Service);
165
+
166
+ processPaymentRxjs(): void {
167
+ this.recaptchaV3.execute('checkout').subscribe({
168
+ next: (token) => {
169
+ // Send token to backend API for verification assessment
170
+ console.log('Action token resolved (RxJS):', token);
171
+ },
172
+ error: (err) => {
173
+ console.error('Resolution error (RxJS):', err);
174
+ }
175
+ });
176
+ }
177
+
178
+ async processPaymentAsync(): Promise<void> {
179
+ try {
180
+ const token = await this.recaptchaV3.executeAsync('checkout');
181
+ console.log('Action token resolved (Async/Await):', token);
182
+ } catch (err) {
183
+ console.error('Resolution error (Async/Await):', err);
184
+ }
185
+ }
186
+ }
187
+ ```
188
+
189
+ ### 3. Reactive Signals Integration (Angular 16+)
190
+
191
+ ```typescript
192
+ import { Component, effect, inject } from '@angular/core';
193
+ import { RecaptchaSignalService } from 'ngx-recaptcha-v3/signals';
194
+ import { RecaptchaV2Component } from 'ngx-recaptcha-v3/v2';
195
+
196
+ @Component({
197
+ selector: 'app-signals-page',
198
+ template: `
199
+ <ngx-recaptcha-v3
200
+ [siteKey]="'YOUR_V2_SITE_KEY'"
201
+ (resolved)="recaptchaSignals.setToken($event)"
202
+ (error)="recaptchaSignals.setError('Load Error occurred')">
203
+ </ngx-recaptcha-v3>
204
+
205
+ @if (recaptchaSignals.verified()) {
206
+ <p>Verification successful! Token: {{ recaptchaSignals.token() }}</p>
207
+ }
208
+ `,
209
+ standalone: true,
210
+ imports: [RecaptchaV2Component]
211
+ })
212
+ export class SignalsPageComponent {
213
+ recaptchaSignals = inject(RecaptchaSignalService);
214
+
215
+ constructor() {
216
+ // Intercept state reactively
217
+ effect(() => {
218
+ if (this.recaptchaSignals.verified()) {
219
+ console.log('User verified with token:', this.recaptchaSignals.token());
220
+ }
221
+ });
222
+ }
223
+ }
224
+ ```
225
+
226
+ ---
227
+
228
+ ## SSR (Server‑Side Rendering) Support
229
+ The library contains native safety guards. When rendering on a server environment, the script loading will gracefully bypass DOM manipulation and execute empty mock resolutions. This ensures standard universal/SSR pipelines do not trigger `window` or `document` reference execution errors.
230
+
231
+ ---
232
+
233
+ ## Unit Testing Setup
234
+
235
+ The library provides testing mocks under the `/testing` sub‑entrypoint.
236
+
237
+ ```typescript
238
+ import { TestBed } from '@angular/core/testing';
239
+ import { RecaptchaV3Service } from 'ngx-recaptcha-v3/v3';
240
+ import { RecaptchaMockV3Service } from 'ngx-recaptcha-v3/testing';
241
+
242
+ describe('MyService', () => {
243
+ beforeEach(() => {
244
+ TestBed.configureTestingModule({
245
+ providers: [
246
+ { provide: RecaptchaV3Service, useClass: RecaptchaMockV3Service }
247
+ ]
248
+ });
249
+ });
250
+
251
+ // Your unit tests...
252
+ });
253
+ ```
254
+
255
+ ---
256
+
257
+ ## Migration Guide (From `ng-recaptcha`)
258
+
259
+ If migrating from legacy packages like `ng-recaptcha`:
260
+
261
+ 1. Remove old configurations and modules from your app imports.
262
+ 2. Update imports from `ng-recaptcha` to `ngx-recaptcha-v3/v2`, `ngx-recaptcha-v3/v3`, or `ngx-recaptcha-v3/core`.
263
+ 3. Provide settings using the unified configuration injection token: `RECAPTCHA_CONFIG`.
264
+ 4. Replace event listeners `(resolved)` with signals using `RecaptchaSignalService` if using Angular 16+.
265
+
266
+ ---
267
+
268
+ ## FAQ & Troubleshooting
269
+
270
+ ### Why is my reCAPTCHA script not loading?
271
+ - Double‑check that you provided `v2SiteKey` or `v3SiteKey` inside the `RECAPTCHA_CONFIG` InjectionToken.
272
+ - Verify that your network has direct access to `google.com` or switch config settings to use `recaptchaDomain: 'recaptcha.net'`.
273
+
274
+ ### Is it compatible with Angular Zoneless mode?
275
+ Yes. The library is built with zoneless capability, utilizing custom element zones via `NgZone.runOutsideAngular` to handle script callbacks without triggering change detection cycles redundantly.
package/package.json ADDED
@@ -0,0 +1,83 @@
1
+ {
2
+ "name": "ngx-recaptcha-v3",
3
+ "version": "1.0.0",
4
+ "description": "A modern, standalone Google reCAPTCHA library for Angular supporting v2, v3, enterprise, reactive forms, and signals. Fully compatible with Angular versions 12–22",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "https://github.com/Tapdiq49/ngx-recaptcha-v3"
8
+ },
9
+ "homepage": "https://github.com/Tapdiq49/ngx-recaptcha-v3/blob/main/README.md",
10
+ "keywords": [
11
+ "angular",
12
+ "recaptcha",
13
+ "google-recaptcha",
14
+ "ng-recaptcha",
15
+ "captcha",
16
+ "recaptcha-v2",
17
+ "recaptcha-v3",
18
+ "recaptcha-enterprise",
19
+ "angular-forms",
20
+ "control-value-accessor",
21
+ "angular-signals"
22
+ ],
23
+ "peerDependencies": {
24
+ "@angular/common": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
25
+ "@angular/core": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0",
26
+ "@angular/forms": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0 || ^22.0.0"
27
+ },
28
+ "peerDependenciesMeta": {
29
+ "@angular/forms": {
30
+ "optional": true
31
+ }
32
+ },
33
+ "dependencies": {
34
+ "tslib": "^2.3.0"
35
+ },
36
+ "author": "",
37
+ "license": "MIT",
38
+ "files": [
39
+ "README.md",
40
+ "CHANGELOG.md"
41
+ ],
42
+ "module": "fesm2022/ngx-recaptcha-v3.mjs",
43
+ "typings": "types/ngx-recaptcha-v3.d.ts",
44
+ "exports": {
45
+ "./package.json": {
46
+ "default": "./package.json"
47
+ },
48
+ ".": {
49
+ "types": "./types/ngx-recaptcha-v3.d.ts",
50
+ "default": "./fesm2022/ngx-recaptcha-v3.mjs"
51
+ },
52
+ "./core": {
53
+ "types": "./types/ngx-recaptcha-v3-core.d.ts",
54
+ "default": "./fesm2022/ngx-recaptcha-v3-core.mjs"
55
+ },
56
+ "./enterprise": {
57
+ "types": "./types/ngx-recaptcha-v3-enterprise.d.ts",
58
+ "default": "./fesm2022/ngx-recaptcha-v3-enterprise.mjs"
59
+ },
60
+ "./forms": {
61
+ "types": "./types/ngx-recaptcha-v3-forms.d.ts",
62
+ "default": "./fesm2022/ngx-recaptcha-v3-forms.mjs"
63
+ },
64
+ "./signals": {
65
+ "types": "./types/ngx-recaptcha-v3-signals.d.ts",
66
+ "default": "./fesm2022/ngx-recaptcha-v3-signals.mjs"
67
+ },
68
+ "./testing": {
69
+ "types": "./types/ngx-recaptcha-v3-testing.d.ts",
70
+ "default": "./fesm2022/ngx-recaptcha-v3-testing.mjs"
71
+ },
72
+ "./v2": {
73
+ "types": "./types/ngx-recaptcha-v3-v2.d.ts",
74
+ "default": "./fesm2022/ngx-recaptcha-v3-v2.mjs"
75
+ },
76
+ "./v3": {
77
+ "types": "./types/ngx-recaptcha-v3-v3.d.ts",
78
+ "default": "./fesm2022/ngx-recaptcha-v3-v3.mjs"
79
+ }
80
+ },
81
+ "sideEffects": false,
82
+ "type": "module"
83
+ }