@ngx-rock/yandex-smart-captcha 17.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/README.md +7 -0
- package/fesm2022/ngx-rock-yandex-smart-captcha.mjs +363 -0
- package/fesm2022/ngx-rock-yandex-smart-captcha.mjs.map +1 -0
- package/index.d.ts +1 -0
- package/lib/helpers/is-valid-host.d.ts +1 -0
- package/lib/yandex-smart-captcha/yandex-smart-captcha.component.d.ts +56 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, output, viewChild, signal, effect, PLATFORM_ID, forwardRef, Inject, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
+
import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
|
|
4
|
+
import { isPlatformBrowser, DOCUMENT } from '@angular/common';
|
|
5
|
+
|
|
6
|
+
const domainRE = /^(\S+)$/;
|
|
7
|
+
const localhostDomainRE = /^localhost[:?\d]*(?:[^:?\d]\S*)?$/;
|
|
8
|
+
const nonLocalhostDomainRE = /^[^\s.]+\.\S{2,}$/;
|
|
9
|
+
const IPv4RE = /^(https?:\/\/)?([0-9]{1,3}\.){3}[0-9]{1,3}:\d+$/;
|
|
10
|
+
const IPv6RE = /^(https?:\/\/)?\[([0-9a-fA-F]{0,4}:){7}([0-9a-fA-F]){0,4}]:\d+$/;
|
|
11
|
+
function isValidHost(str) {
|
|
12
|
+
if (typeof str !== 'string') {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
const match = str.match(domainRE);
|
|
16
|
+
if (!match) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const everythingAfterProtocol = match[0];
|
|
20
|
+
if (!everythingAfterProtocol) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return (localhostDomainRE.test(everythingAfterProtocol) ||
|
|
24
|
+
nonLocalhostDomainRE.test(everythingAfterProtocol) ||
|
|
25
|
+
IPv4RE.test(everythingAfterProtocol) ||
|
|
26
|
+
IPv6RE.test(everythingAfterProtocol));
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const API_LINK = (host = 'smartcaptcha.yandexcloud.net') => {
|
|
30
|
+
const base = /^https?/.test(host) ? host : `https://${host}`;
|
|
31
|
+
return `${base}/captcha.js?render=onload&onload=__onSmartCaptchaReady`;
|
|
32
|
+
};
|
|
33
|
+
// Shared callbacks array
|
|
34
|
+
const callbacks = [];
|
|
35
|
+
const startLoading = new Map();
|
|
36
|
+
class SmartCaptchaComponent {
|
|
37
|
+
renderer2;
|
|
38
|
+
document;
|
|
39
|
+
platformId;
|
|
40
|
+
sitekey = input.required();
|
|
41
|
+
invisible = input(false);
|
|
42
|
+
visible = input(); // For InvisibleCaptcha to execute
|
|
43
|
+
hideShield = input();
|
|
44
|
+
shieldPosition = input();
|
|
45
|
+
language = input();
|
|
46
|
+
host = input();
|
|
47
|
+
theme = input('auto');
|
|
48
|
+
test = input();
|
|
49
|
+
webview = input();
|
|
50
|
+
challengeHidden = output();
|
|
51
|
+
challengeVisible = output();
|
|
52
|
+
success = output();
|
|
53
|
+
networkError = output();
|
|
54
|
+
tokenExpired = output();
|
|
55
|
+
javascriptError = output();
|
|
56
|
+
captchaContainer = viewChild('captchaContainer');
|
|
57
|
+
widgetId;
|
|
58
|
+
smartCaptchaInstance;
|
|
59
|
+
destroyed = false;
|
|
60
|
+
unsubscribeFns = [];
|
|
61
|
+
errorEventHandler;
|
|
62
|
+
onChange = () => {
|
|
63
|
+
// onChange
|
|
64
|
+
};
|
|
65
|
+
onTouched = () => {
|
|
66
|
+
// onTouched
|
|
67
|
+
};
|
|
68
|
+
_innerValue = signal(null); // Use a signal for innerValue
|
|
69
|
+
callbackIndex = null;
|
|
70
|
+
constructor(renderer2, document, platformId) {
|
|
71
|
+
this.renderer2 = renderer2;
|
|
72
|
+
this.document = document;
|
|
73
|
+
this.platformId = platformId;
|
|
74
|
+
// Effect for theme changes
|
|
75
|
+
effect(() => {
|
|
76
|
+
if (this.theme() &&
|
|
77
|
+
this.widgetId !== undefined &&
|
|
78
|
+
this.smartCaptchaInstance?.setTheme) {
|
|
79
|
+
this.smartCaptchaInstance.setTheme(this.widgetId, this.theme());
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
// Effect for visible changes (Invisible Captcha)
|
|
83
|
+
effect(() => {
|
|
84
|
+
if (this.visible() &&
|
|
85
|
+
this.invisible() &&
|
|
86
|
+
this.smartCaptchaInstance &&
|
|
87
|
+
typeof this.widgetId === 'number' &&
|
|
88
|
+
!this.destroyed) {
|
|
89
|
+
this.smartCaptchaInstance.execute(this.widgetId);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
ngOnInit() {
|
|
94
|
+
if (!isPlatformBrowser(this.platformId)) {
|
|
95
|
+
return; // Don't proceed on server-side
|
|
96
|
+
}
|
|
97
|
+
if (this.host() !== undefined && !isValidHost(this.host())) {
|
|
98
|
+
console.error(`[SmartCaptcha] ${this.host()} host is invalid. It should be of a kind: domain.ru, localhost:3000`);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (typeof window !== 'undefined') {
|
|
102
|
+
// Setup global callback if not already defined
|
|
103
|
+
if (window.__onSmartCaptchaReady === undefined) {
|
|
104
|
+
window.__onSmartCaptchaReady = () => {
|
|
105
|
+
callbacks.forEach((callback) => callback());
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
// Check if SmartCaptcha is already loaded
|
|
109
|
+
if (window.smartCaptcha) {
|
|
110
|
+
this.smartCaptchaInstance = window.smartCaptcha;
|
|
111
|
+
}
|
|
112
|
+
// Add our callback to the shared array
|
|
113
|
+
this.callbackIndex = callbacks.push(() => {
|
|
114
|
+
this.smartCaptchaInstance = window.smartCaptcha;
|
|
115
|
+
this.renderCaptcha();
|
|
116
|
+
});
|
|
117
|
+
// Load script if not already loading
|
|
118
|
+
const hostKey = this.host() || 'default';
|
|
119
|
+
if (!startLoading.get(hostKey)) {
|
|
120
|
+
this.loadScript();
|
|
121
|
+
startLoading.set(hostKey, true);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
ngAfterViewInit() {
|
|
126
|
+
if (this.smartCaptchaInstance) {
|
|
127
|
+
this.renderCaptcha();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
ngOnDestroy() {
|
|
131
|
+
this.destroyed = true;
|
|
132
|
+
// Remove callback from shared array
|
|
133
|
+
if (this.callbackIndex !== null) {
|
|
134
|
+
callbacks.splice(this.callbackIndex - 1, 1);
|
|
135
|
+
}
|
|
136
|
+
// Destroy widget if it exists
|
|
137
|
+
if (this.widgetId !== undefined && this.smartCaptchaInstance) {
|
|
138
|
+
this.smartCaptchaInstance.destroy(this.widgetId);
|
|
139
|
+
this.widgetId = undefined;
|
|
140
|
+
}
|
|
141
|
+
// Clean up subscriptions
|
|
142
|
+
this.unsubscribeFns.forEach((fn) => fn && fn());
|
|
143
|
+
this.unsubscribeFns = [];
|
|
144
|
+
// Remove error event handler
|
|
145
|
+
if (this.errorEventHandler && typeof window !== 'undefined') {
|
|
146
|
+
window.removeEventListener('error', this.errorEventHandler);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
loadScript() {
|
|
150
|
+
const src = API_LINK(this.host());
|
|
151
|
+
const script = this.renderer2.createElement('script');
|
|
152
|
+
this.renderer2.setAttribute(script, 'src', src);
|
|
153
|
+
this.renderer2.setAttribute(script, 'type', 'text/javascript');
|
|
154
|
+
this.renderer2.setAttribute(script, 'crossOrigin', 'anonymous');
|
|
155
|
+
// Handle regular onload/onerror
|
|
156
|
+
script.onload = () => {
|
|
157
|
+
if (window.smartCaptcha && !this.smartCaptchaInstance) {
|
|
158
|
+
this.smartCaptchaInstance = window.smartCaptcha;
|
|
159
|
+
this.renderCaptcha();
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
script.onerror = () => {
|
|
163
|
+
this.handleJavascriptError({
|
|
164
|
+
filename: src,
|
|
165
|
+
message: 'Unknown error on script loading',
|
|
166
|
+
col: 0,
|
|
167
|
+
line: 0,
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
// Add error event listener for JS errors in the captcha script
|
|
171
|
+
if (typeof window !== 'undefined') {
|
|
172
|
+
this.errorEventHandler = (e) => {
|
|
173
|
+
if (e.filename?.indexOf(src) === 0) {
|
|
174
|
+
this.handleJavascriptError({
|
|
175
|
+
filename: e.filename,
|
|
176
|
+
message: e.message,
|
|
177
|
+
col: e.colno,
|
|
178
|
+
line: e.lineno,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
window.addEventListener('error', this.errorEventHandler);
|
|
183
|
+
}
|
|
184
|
+
// Add script to document
|
|
185
|
+
this.renderer2.appendChild(this.document.body, script);
|
|
186
|
+
}
|
|
187
|
+
renderCaptcha() {
|
|
188
|
+
const container = this.captchaContainer()?.nativeElement;
|
|
189
|
+
if (!container ||
|
|
190
|
+
!this.smartCaptchaInstance ||
|
|
191
|
+
this.widgetId !== undefined ||
|
|
192
|
+
this.destroyed) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
const params = {
|
|
196
|
+
sitekey: this.sitekey(),
|
|
197
|
+
hl: this.language(),
|
|
198
|
+
theme: this.theme(),
|
|
199
|
+
invisible: this.invisible(),
|
|
200
|
+
hideShield: this.hideShield(),
|
|
201
|
+
shieldPosition: this.shieldPosition(),
|
|
202
|
+
test: this.test(),
|
|
203
|
+
webview: this.webview(),
|
|
204
|
+
};
|
|
205
|
+
try {
|
|
206
|
+
this.widgetId = this.smartCaptchaInstance.render(container, params);
|
|
207
|
+
this.setupSubscriptions();
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
console.error('[SmartCaptcha] Error rendering captcha widget:', error);
|
|
211
|
+
let message = 'Unknown error during rendering';
|
|
212
|
+
if (error instanceof Error) {
|
|
213
|
+
message = error.message;
|
|
214
|
+
}
|
|
215
|
+
this.handleJavascriptError({
|
|
216
|
+
filename: API_LINK(this.host()),
|
|
217
|
+
message,
|
|
218
|
+
col: 0,
|
|
219
|
+
line: 0,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
setupSubscriptions() {
|
|
224
|
+
if (this.widgetId === undefined || !this.smartCaptchaInstance) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
// Store unsubscribe functions for cleanup
|
|
228
|
+
this.unsubscribeFns = [
|
|
229
|
+
this.smartCaptchaInstance.subscribe(this.widgetId, 'challenge-visible', () => {
|
|
230
|
+
this.challengeVisible.emit();
|
|
231
|
+
}),
|
|
232
|
+
this.smartCaptchaInstance.subscribe(this.widgetId, 'challenge-hidden', () => {
|
|
233
|
+
console.error('hidden');
|
|
234
|
+
this.challengeHidden.emit();
|
|
235
|
+
}),
|
|
236
|
+
this.smartCaptchaInstance.subscribe(this.widgetId, 'network-error', () => {
|
|
237
|
+
this.networkError.emit();
|
|
238
|
+
}),
|
|
239
|
+
this.smartCaptchaInstance.subscribe(this.widgetId, 'success', (...args) => {
|
|
240
|
+
const [token] = args;
|
|
241
|
+
this._innerValue.set(token);
|
|
242
|
+
this.onChange(token);
|
|
243
|
+
this.onTouched();
|
|
244
|
+
this.success.emit(token);
|
|
245
|
+
}),
|
|
246
|
+
this.smartCaptchaInstance.subscribe(this.widgetId, 'token-expired', () => {
|
|
247
|
+
this._innerValue.set(null);
|
|
248
|
+
this.onChange(null);
|
|
249
|
+
this.onTouched();
|
|
250
|
+
this.tokenExpired.emit();
|
|
251
|
+
}),
|
|
252
|
+
this.smartCaptchaInstance.subscribe(this.widgetId, 'javascript-error', (...args) => {
|
|
253
|
+
const [error] = args;
|
|
254
|
+
this.handleJavascriptError(error);
|
|
255
|
+
}),
|
|
256
|
+
];
|
|
257
|
+
}
|
|
258
|
+
handleJavascriptError(error) {
|
|
259
|
+
console.error('[SmartCaptcha] Javascript error:', error);
|
|
260
|
+
this.javascriptError.emit(error);
|
|
261
|
+
}
|
|
262
|
+
// ControlValueAccessor methods
|
|
263
|
+
writeValue(value) {
|
|
264
|
+
this._innerValue.set(value); // Set the signal value
|
|
265
|
+
}
|
|
266
|
+
registerOnChange(fn) {
|
|
267
|
+
this.onChange = fn;
|
|
268
|
+
}
|
|
269
|
+
registerOnTouched(fn) {
|
|
270
|
+
this.onTouched = fn;
|
|
271
|
+
}
|
|
272
|
+
// Validator method
|
|
273
|
+
validate() {
|
|
274
|
+
// When using invisible captcha, don't validate until user interacts
|
|
275
|
+
if (this.invisible() && !this._innerValue()) {
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
// For standard captcha, require token
|
|
279
|
+
if (!this.invisible() && !this._innerValue()) {
|
|
280
|
+
// Access signal value
|
|
281
|
+
return { captchaRequired: true };
|
|
282
|
+
}
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: SmartCaptchaComponent, deps: [{ token: i0.Renderer2 }, { token: DOCUMENT }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component });
|
|
286
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.2", type: SmartCaptchaComponent, isStandalone: true, selector: "smart-captcha", inputs: { sitekey: { classPropertyName: "sitekey", publicName: "sitekey", isSignal: true, isRequired: true, transformFunction: null }, invisible: { classPropertyName: "invisible", publicName: "invisible", isSignal: true, isRequired: false, transformFunction: null }, visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, hideShield: { classPropertyName: "hideShield", publicName: "hideShield", isSignal: true, isRequired: false, transformFunction: null }, shieldPosition: { classPropertyName: "shieldPosition", publicName: "shieldPosition", isSignal: true, isRequired: false, transformFunction: null }, language: { classPropertyName: "language", publicName: "language", isSignal: true, isRequired: false, transformFunction: null }, host: { classPropertyName: "host", publicName: "host", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, test: { classPropertyName: "test", publicName: "test", isSignal: true, isRequired: false, transformFunction: null }, webview: { classPropertyName: "webview", publicName: "webview", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { challengeHidden: "challengeHidden", challengeVisible: "challengeVisible", success: "success", networkError: "networkError", tokenExpired: "tokenExpired", javascriptError: "javascriptError" }, providers: [
|
|
287
|
+
{
|
|
288
|
+
provide: NG_VALUE_ACCESSOR,
|
|
289
|
+
useExisting: forwardRef(() => SmartCaptchaComponent),
|
|
290
|
+
multi: true,
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
provide: NG_VALIDATORS,
|
|
294
|
+
useExisting: forwardRef(() => SmartCaptchaComponent),
|
|
295
|
+
multi: true,
|
|
296
|
+
},
|
|
297
|
+
], viewQueries: [{ propertyName: "captchaContainer", first: true, predicate: ["captchaContainer"], descendants: true, isSignal: true }], ngImport: i0, template: ` <div class="smart-captcha" #captchaContainer></div> `, isInline: true, styles: [".smart-captcha{height:102px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
298
|
+
}
|
|
299
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: SmartCaptchaComponent, decorators: [{
|
|
300
|
+
type: Component,
|
|
301
|
+
args: [{ selector: 'smart-captcha', template: ` <div class="smart-captcha" #captchaContainer></div> `, providers: [
|
|
302
|
+
{
|
|
303
|
+
provide: NG_VALUE_ACCESSOR,
|
|
304
|
+
useExisting: forwardRef(() => SmartCaptchaComponent),
|
|
305
|
+
multi: true,
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
provide: NG_VALIDATORS,
|
|
309
|
+
useExisting: forwardRef(() => SmartCaptchaComponent),
|
|
310
|
+
multi: true,
|
|
311
|
+
},
|
|
312
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, styles: [".smart-captcha{height:102px}\n"] }]
|
|
313
|
+
}], ctorParameters: () => [{ type: i0.Renderer2 }, { type: Document, decorators: [{
|
|
314
|
+
type: Inject,
|
|
315
|
+
args: [DOCUMENT]
|
|
316
|
+
}] }, { type: undefined, decorators: [{
|
|
317
|
+
type: Inject,
|
|
318
|
+
args: [PLATFORM_ID]
|
|
319
|
+
}] }] });
|
|
320
|
+
class InvisibleSmartCaptchaComponent extends SmartCaptchaComponent {
|
|
321
|
+
// Always set invisible to true
|
|
322
|
+
invisible = input(true);
|
|
323
|
+
// Override ngOnInit to ensure invisible is always true
|
|
324
|
+
ngOnInit() {
|
|
325
|
+
// Call parent initialization
|
|
326
|
+
super.ngOnInit();
|
|
327
|
+
}
|
|
328
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: InvisibleSmartCaptchaComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
329
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.2", type: InvisibleSmartCaptchaComponent, isStandalone: true, selector: "invisible-smart-captcha", inputs: { invisible: { classPropertyName: "invisible", publicName: "invisible", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
330
|
+
{
|
|
331
|
+
provide: NG_VALUE_ACCESSOR,
|
|
332
|
+
useExisting: forwardRef(() => InvisibleSmartCaptchaComponent),
|
|
333
|
+
multi: true,
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
provide: NG_VALIDATORS,
|
|
337
|
+
useExisting: forwardRef(() => InvisibleSmartCaptchaComponent),
|
|
338
|
+
multi: true,
|
|
339
|
+
},
|
|
340
|
+
], usesInheritance: true, ngImport: i0, template: ` <div class="smart-captcha" #captchaContainer></div> `, isInline: true, styles: [""], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
341
|
+
}
|
|
342
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.2", ngImport: i0, type: InvisibleSmartCaptchaComponent, decorators: [{
|
|
343
|
+
type: Component,
|
|
344
|
+
args: [{ selector: 'invisible-smart-captcha', template: ` <div class="smart-captcha" #captchaContainer></div> `, providers: [
|
|
345
|
+
{
|
|
346
|
+
provide: NG_VALUE_ACCESSOR,
|
|
347
|
+
useExisting: forwardRef(() => InvisibleSmartCaptchaComponent),
|
|
348
|
+
multi: true,
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
provide: NG_VALIDATORS,
|
|
352
|
+
useExisting: forwardRef(() => InvisibleSmartCaptchaComponent),
|
|
353
|
+
multi: true,
|
|
354
|
+
},
|
|
355
|
+
], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush }]
|
|
356
|
+
}] });
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Generated bundle index. Do not edit.
|
|
360
|
+
*/
|
|
361
|
+
|
|
362
|
+
export { InvisibleSmartCaptchaComponent, SmartCaptchaComponent, startLoading };
|
|
363
|
+
//# sourceMappingURL=ngx-rock-yandex-smart-captcha.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngx-rock-yandex-smart-captcha.mjs","sources":["../../../../libs/yandex-smart-captcha/src/lib/helpers/is-valid-host.ts","../../../../libs/yandex-smart-captcha/src/lib/yandex-smart-captcha/yandex-smart-captcha.component.ts","../../../../libs/yandex-smart-captcha/src/ngx-rock-yandex-smart-captcha.ts"],"sourcesContent":["const domainRE = /^(\\S+)$/;\nconst localhostDomainRE = /^localhost[:?\\d]*(?:[^:?\\d]\\S*)?$/;\nconst nonLocalhostDomainRE = /^[^\\s.]+\\.\\S{2,}$/;\nconst IPv4RE = /^(https?:\\/\\/)?([0-9]{1,3}\\.){3}[0-9]{1,3}:\\d+$/;\nconst IPv6RE =\n /^(https?:\\/\\/)?\\[([0-9a-fA-F]{0,4}:){7}([0-9a-fA-F]){0,4}]:\\d+$/;\n\nexport function isValidHost(str: string | undefined): boolean {\n if (typeof str !== 'string') {\n return false;\n }\n const match = str.match(domainRE);\n if (!match) {\n return false;\n }\n const everythingAfterProtocol = match[0];\n if (!everythingAfterProtocol) {\n return false;\n }\n return (\n localhostDomainRE.test(everythingAfterProtocol) ||\n nonLocalhostDomainRE.test(everythingAfterProtocol) ||\n IPv4RE.test(everythingAfterProtocol) ||\n IPv6RE.test(everythingAfterProtocol)\n );\n}\n","import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n effect,\n ElementRef,\n forwardRef,\n Inject,\n input,\n OnDestroy,\n OnInit,\n output,\n PLATFORM_ID,\n Renderer2,\n signal,\n viewChild,\n} from '@angular/core';\nimport {\n ControlValueAccessor,\n NG_VALIDATORS,\n NG_VALUE_ACCESSOR,\n ValidationErrors,\n Validator,\n} from '@angular/forms';\nimport { DOCUMENT, isPlatformBrowser } from '@angular/common';\nimport { isValidHost } from '../helpers/is-valid-host';\nimport {\n JavascriptErrorPayload,\n SmartCaptchaInstance,\n SmartCaptchaParams,\n} from '../types';\n\nconst API_LINK = (host = 'smartcaptcha.yandexcloud.net') => {\n const base = /^https?/.test(host) ? host : `https://${host}`;\n return `${base}/captcha.js?render=onload&onload=__onSmartCaptchaReady`;\n};\n\n// Shared callbacks array\nconst callbacks: (() => void)[] = [];\nexport const startLoading = new Map<string, boolean>();\n\n@Component({\n selector: 'smart-captcha',\n template: ` <div class=\"smart-captcha\" #captchaContainer></div> `,\n styles: [\n `\n .smart-captcha {\n height: 102px;\n }\n `,\n ],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => SmartCaptchaComponent),\n multi: true,\n },\n {\n provide: NG_VALIDATORS,\n useExisting: forwardRef(() => SmartCaptchaComponent),\n multi: true,\n },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n})\nexport class SmartCaptchaComponent\n implements ControlValueAccessor, Validator, OnInit, AfterViewInit, OnDestroy\n{\n sitekey = input.required<string>();\n invisible = input<boolean>(false);\n visible = input<boolean>(); // For InvisibleCaptcha to execute\n hideShield = input<boolean>();\n shieldPosition = input<\n 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'\n >();\n language = input<string>();\n host = input<string>();\n theme = input<'light' | 'dark' | 'auto'>('auto');\n test = input<boolean>();\n webview = input<boolean>();\n\n challengeHidden = output<void>();\n challengeVisible = output<void>();\n success = output<string>();\n networkError = output<void>();\n tokenExpired = output<void>();\n javascriptError = output<JavascriptErrorPayload>();\n\n captchaContainer = viewChild<ElementRef<HTMLDivElement>>('captchaContainer');\n\n protected widgetId: number | undefined;\n protected smartCaptchaInstance: SmartCaptchaInstance | undefined;\n protected destroyed = false;\n private unsubscribeFns: Array<(() => void) | undefined> = [];\n private errorEventHandler: ((e: ErrorEvent) => void) | undefined;\n\n private onChange: (value: string | null) => void = () => {\n // onChange\n };\n private onTouched = () => {\n // onTouched\n };\n private _innerValue = signal<string | null>(null); // Use a signal for innerValue\n private callbackIndex: number | null = null;\n\n constructor(\n private renderer2: Renderer2,\n @Inject(DOCUMENT) private document: Document,\n @Inject(PLATFORM_ID) private platformId: object\n ) {\n // Effect for theme changes\n effect(() => {\n if (\n this.theme() &&\n this.widgetId !== undefined &&\n this.smartCaptchaInstance?.setTheme\n ) {\n this.smartCaptchaInstance.setTheme(this.widgetId, this.theme());\n }\n });\n\n // Effect for visible changes (Invisible Captcha)\n effect(() => {\n if (\n this.visible() &&\n this.invisible() &&\n this.smartCaptchaInstance &&\n typeof this.widgetId === 'number' &&\n !this.destroyed\n ) {\n this.smartCaptchaInstance.execute(this.widgetId);\n }\n });\n }\n\n ngOnInit(): void {\n if (!isPlatformBrowser(this.platformId)) {\n return; // Don't proceed on server-side\n }\n\n if (this.host() !== undefined && !isValidHost(this.host())) {\n console.error(\n `[SmartCaptcha] ${this.host()} host is invalid. It should be of a kind: domain.ru, localhost:3000`\n );\n return;\n }\n\n if (typeof window !== 'undefined') {\n // Setup global callback if not already defined\n if (window.__onSmartCaptchaReady === undefined) {\n window.__onSmartCaptchaReady = () => {\n callbacks.forEach((callback) => callback());\n };\n }\n\n // Check if SmartCaptcha is already loaded\n if (window.smartCaptcha) {\n this.smartCaptchaInstance = window.smartCaptcha;\n }\n\n // Add our callback to the shared array\n this.callbackIndex = callbacks.push(() => {\n this.smartCaptchaInstance = window.smartCaptcha;\n this.renderCaptcha();\n });\n\n // Load script if not already loading\n const hostKey = this.host() || 'default';\n if (!startLoading.get(hostKey)) {\n this.loadScript();\n startLoading.set(hostKey, true);\n }\n }\n }\n\n ngAfterViewInit(): void {\n if (this.smartCaptchaInstance) {\n this.renderCaptcha();\n }\n }\n\n ngOnDestroy(): void {\n this.destroyed = true;\n\n // Remove callback from shared array\n if (this.callbackIndex !== null) {\n callbacks.splice(this.callbackIndex - 1, 1);\n }\n\n // Destroy widget if it exists\n if (this.widgetId !== undefined && this.smartCaptchaInstance) {\n this.smartCaptchaInstance.destroy(this.widgetId);\n this.widgetId = undefined;\n }\n\n // Clean up subscriptions\n this.unsubscribeFns.forEach((fn) => fn && fn());\n this.unsubscribeFns = [];\n\n // Remove error event handler\n if (this.errorEventHandler && typeof window !== 'undefined') {\n window.removeEventListener('error', this.errorEventHandler);\n }\n }\n\n private loadScript(): void {\n const src = API_LINK(this.host());\n const script = this.renderer2.createElement('script');\n this.renderer2.setAttribute(script, 'src', src);\n this.renderer2.setAttribute(script, 'type', 'text/javascript');\n this.renderer2.setAttribute(script, 'crossOrigin', 'anonymous');\n\n // Handle regular onload/onerror\n script.onload = () => {\n if (window.smartCaptcha && !this.smartCaptchaInstance) {\n this.smartCaptchaInstance = window.smartCaptcha;\n this.renderCaptcha();\n }\n };\n\n script.onerror = () => {\n this.handleJavascriptError({\n filename: src,\n message: 'Unknown error on script loading',\n col: 0,\n line: 0,\n });\n };\n\n // Add error event listener for JS errors in the captcha script\n if (typeof window !== 'undefined') {\n this.errorEventHandler = (e: ErrorEvent) => {\n if (e.filename?.indexOf(src) === 0) {\n this.handleJavascriptError({\n filename: e.filename,\n message: e.message,\n col: e.colno,\n line: e.lineno,\n });\n }\n };\n window.addEventListener('error', this.errorEventHandler);\n }\n\n // Add script to document\n this.renderer2.appendChild(this.document.body, script);\n }\n\n private renderCaptcha(): void {\n const container = this.captchaContainer()?.nativeElement;\n if (\n !container ||\n !this.smartCaptchaInstance ||\n this.widgetId !== undefined ||\n this.destroyed\n ) {\n return;\n }\n\n const params: SmartCaptchaParams = {\n sitekey: this.sitekey(),\n hl: this.language(),\n theme: this.theme(),\n invisible: this.invisible(),\n hideShield: this.hideShield(),\n shieldPosition: this.shieldPosition(),\n test: this.test(),\n webview: this.webview(),\n };\n\n try {\n this.widgetId = this.smartCaptchaInstance.render(container, params);\n this.setupSubscriptions();\n } catch (error: unknown) {\n console.error('[SmartCaptcha] Error rendering captcha widget:', error);\n\n let message = 'Unknown error during rendering';\n if (error instanceof Error) {\n message = error.message;\n }\n\n this.handleJavascriptError({\n filename: API_LINK(this.host()),\n message,\n col: 0,\n line: 0,\n });\n }\n }\n\n private setupSubscriptions(): void {\n if (this.widgetId === undefined || !this.smartCaptchaInstance) {\n return;\n }\n\n // Store unsubscribe functions for cleanup\n this.unsubscribeFns = [\n this.smartCaptchaInstance.subscribe(\n this.widgetId,\n 'challenge-visible',\n () => {\n this.challengeVisible.emit();\n }\n ),\n\n this.smartCaptchaInstance.subscribe(\n this.widgetId,\n 'challenge-hidden',\n () => {\n console.error('hidden');\n this.challengeHidden.emit();\n }\n ),\n\n this.smartCaptchaInstance.subscribe(\n this.widgetId,\n 'network-error',\n () => {\n this.networkError.emit();\n }\n ),\n\n this.smartCaptchaInstance.subscribe(\n this.widgetId,\n 'success',\n (...args: unknown[]) => {\n const [token] = args as [string];\n\n this._innerValue.set(token);\n this.onChange(token);\n this.onTouched();\n this.success.emit(token);\n }\n ),\n\n this.smartCaptchaInstance.subscribe(\n this.widgetId,\n 'token-expired',\n () => {\n this._innerValue.set(null);\n this.onChange(null);\n this.onTouched();\n this.tokenExpired.emit();\n }\n ),\n\n this.smartCaptchaInstance.subscribe(\n this.widgetId,\n 'javascript-error',\n (...args: unknown[]) => {\n const [error] = args as [JavascriptErrorPayload];\n this.handleJavascriptError(error);\n }\n ),\n ];\n }\n\n private handleJavascriptError(error: JavascriptErrorPayload): void {\n console.error('[SmartCaptcha] Javascript error:', error);\n this.javascriptError.emit(error);\n }\n\n // ControlValueAccessor methods\n writeValue(value: string): void {\n this._innerValue.set(value); // Set the signal value\n }\n\n registerOnChange(fn: (value: string | null) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n // Validator method\n validate(): ValidationErrors | null {\n // When using invisible captcha, don't validate until user interacts\n if (this.invisible() && !this._innerValue()) {\n return null;\n }\n\n // For standard captcha, require token\n if (!this.invisible() && !this._innerValue()) {\n // Access signal value\n return { captchaRequired: true };\n }\n\n return null;\n }\n}\n\n@Component({\n selector: 'invisible-smart-captcha',\n template: ` <div class=\"smart-captcha\" #captchaContainer></div> `,\n styles: [\n `\n .smart-captcha {\n /* No height needed for invisible captcha */\n }\n `,\n ],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => InvisibleSmartCaptchaComponent),\n multi: true,\n },\n {\n provide: NG_VALIDATORS,\n useExisting: forwardRef(() => InvisibleSmartCaptchaComponent),\n multi: true,\n },\n ],\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class InvisibleSmartCaptchaComponent\n extends SmartCaptchaComponent\n implements OnInit\n{\n // Always set invisible to true\n override invisible = input(true);\n\n // Override ngOnInit to ensure invisible is always true\n override ngOnInit(): void {\n // Call parent initialization\n super.ngOnInit();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './lib/yandex-smart-captcha/yandex-smart-captcha.component';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isValidHost(str: string | undefined): boolean;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { AfterViewInit, ElementRef, OnDestroy, OnInit, Renderer2 } from '@angular/core';
|
|
2
|
+
import { ControlValueAccessor, ValidationErrors, Validator } from '@angular/forms';
|
|
3
|
+
import { JavascriptErrorPayload, SmartCaptchaInstance } from '../types';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
export declare const startLoading: Map<string, boolean>;
|
|
6
|
+
export declare class SmartCaptchaComponent implements ControlValueAccessor, Validator, OnInit, AfterViewInit, OnDestroy {
|
|
7
|
+
private renderer2;
|
|
8
|
+
private document;
|
|
9
|
+
private platformId;
|
|
10
|
+
sitekey: import("@angular/core").InputSignal<string>;
|
|
11
|
+
invisible: import("@angular/core").InputSignal<boolean>;
|
|
12
|
+
visible: import("@angular/core").InputSignal<boolean | undefined>;
|
|
13
|
+
hideShield: import("@angular/core").InputSignal<boolean | undefined>;
|
|
14
|
+
shieldPosition: import("@angular/core").InputSignal<"top-left" | "top-right" | "bottom-left" | "bottom-right" | undefined>;
|
|
15
|
+
language: import("@angular/core").InputSignal<string | undefined>;
|
|
16
|
+
host: import("@angular/core").InputSignal<string | undefined>;
|
|
17
|
+
theme: import("@angular/core").InputSignal<"light" | "dark" | "auto">;
|
|
18
|
+
test: import("@angular/core").InputSignal<boolean | undefined>;
|
|
19
|
+
webview: import("@angular/core").InputSignal<boolean | undefined>;
|
|
20
|
+
challengeHidden: import("@angular/core").OutputEmitterRef<void>;
|
|
21
|
+
challengeVisible: import("@angular/core").OutputEmitterRef<void>;
|
|
22
|
+
success: import("@angular/core").OutputEmitterRef<string>;
|
|
23
|
+
networkError: import("@angular/core").OutputEmitterRef<void>;
|
|
24
|
+
tokenExpired: import("@angular/core").OutputEmitterRef<void>;
|
|
25
|
+
javascriptError: import("@angular/core").OutputEmitterRef<JavascriptErrorPayload>;
|
|
26
|
+
captchaContainer: import("@angular/core").Signal<ElementRef<HTMLDivElement> | undefined>;
|
|
27
|
+
protected widgetId: number | undefined;
|
|
28
|
+
protected smartCaptchaInstance: SmartCaptchaInstance | undefined;
|
|
29
|
+
protected destroyed: boolean;
|
|
30
|
+
private unsubscribeFns;
|
|
31
|
+
private errorEventHandler;
|
|
32
|
+
private onChange;
|
|
33
|
+
private onTouched;
|
|
34
|
+
private _innerValue;
|
|
35
|
+
private callbackIndex;
|
|
36
|
+
constructor(renderer2: Renderer2, document: Document, platformId: object);
|
|
37
|
+
ngOnInit(): void;
|
|
38
|
+
ngAfterViewInit(): void;
|
|
39
|
+
ngOnDestroy(): void;
|
|
40
|
+
private loadScript;
|
|
41
|
+
private renderCaptcha;
|
|
42
|
+
private setupSubscriptions;
|
|
43
|
+
private handleJavascriptError;
|
|
44
|
+
writeValue(value: string): void;
|
|
45
|
+
registerOnChange(fn: (value: string | null) => void): void;
|
|
46
|
+
registerOnTouched(fn: () => void): void;
|
|
47
|
+
validate(): ValidationErrors | null;
|
|
48
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<SmartCaptchaComponent, never>;
|
|
49
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SmartCaptchaComponent, "smart-captcha", never, { "sitekey": { "alias": "sitekey"; "required": true; "isSignal": true; }; "invisible": { "alias": "invisible"; "required": false; "isSignal": true; }; "visible": { "alias": "visible"; "required": false; "isSignal": true; }; "hideShield": { "alias": "hideShield"; "required": false; "isSignal": true; }; "shieldPosition": { "alias": "shieldPosition"; "required": false; "isSignal": true; }; "language": { "alias": "language"; "required": false; "isSignal": true; }; "host": { "alias": "host"; "required": false; "isSignal": true; }; "theme": { "alias": "theme"; "required": false; "isSignal": true; }; "test": { "alias": "test"; "required": false; "isSignal": true; }; "webview": { "alias": "webview"; "required": false; "isSignal": true; }; }, { "challengeHidden": "challengeHidden"; "challengeVisible": "challengeVisible"; "success": "success"; "networkError": "networkError"; "tokenExpired": "tokenExpired"; "javascriptError": "javascriptError"; }, never, never, true, never>;
|
|
50
|
+
}
|
|
51
|
+
export declare class InvisibleSmartCaptchaComponent extends SmartCaptchaComponent implements OnInit {
|
|
52
|
+
invisible: import("@angular/core").InputSignal<boolean>;
|
|
53
|
+
ngOnInit(): void;
|
|
54
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<InvisibleSmartCaptchaComponent, never>;
|
|
55
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<InvisibleSmartCaptchaComponent, "invisible-smart-captcha", never, { "invisible": { "alias": "invisible"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
56
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ngx-rock/yandex-smart-captcha",
|
|
3
|
+
"version": "17.0.0",
|
|
4
|
+
"description": "Yandex smart captcha",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git@github.com:ngx-rock/yandex-smart-captcha.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/ngx-rock/yandex-smart-captcha/issues"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://github.com/ngx-rock/yandex-smart-captcha#readme",
|
|
14
|
+
"keywords": [
|
|
15
|
+
"angular",
|
|
16
|
+
"ng",
|
|
17
|
+
"yandex smart captcha",
|
|
18
|
+
"captcha"
|
|
19
|
+
],
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"@angular/common": ">=17.3.0",
|
|
22
|
+
"@angular/core": ">=17.3.0",
|
|
23
|
+
"@angular/forms": ">=17.3.0"
|
|
24
|
+
},
|
|
25
|
+
"sideEffects": false,
|
|
26
|
+
"module": "fesm2022/ngx-rock-yandex-smart-captcha.mjs",
|
|
27
|
+
"typings": "index.d.ts",
|
|
28
|
+
"exports": {
|
|
29
|
+
"./package.json": {
|
|
30
|
+
"default": "./package.json"
|
|
31
|
+
},
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./index.d.ts",
|
|
34
|
+
"default": "./fesm2022/ngx-rock-yandex-smart-captcha.mjs"
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"tslib": "^2.3.0"
|
|
39
|
+
}
|
|
40
|
+
}
|