ng-recaptcha-19
Version:
Angular component for Google reCAPTCHA for Angular v18 and onwards
323 lines (311 loc) • 12.8 kB
TypeScript
import * as i0 from '@angular/core';
import { InjectionToken, AfterViewInit, OnDestroy, EventEmitter, ElementRef, NgZone } from '@angular/core';
import { Observable } from 'rxjs';
import * as i2 from '@angular/forms';
import { ControlValueAccessor } from '@angular/forms';
interface RecaptchaSettings {
siteKey?: string;
theme?: ReCaptchaV2.Theme;
type?: ReCaptchaV2.Type;
size?: ReCaptchaV2.Size;
badge?: ReCaptchaV2.Badge;
}
/** @deprecated Use `LOADER_OPTIONS` instead. See `RecaptchaLoaderOptions.onBeforeLoad` */
declare const RECAPTCHA_LANGUAGE: InjectionToken<string>;
/** @deprecated Use `LOADER_OPTIONS` instead. See `RecaptchaLoaderOptions.onBeforeLoad` */
declare const RECAPTCHA_BASE_URL: InjectionToken<string>;
/** @deprecated Use `LOADER_OPTIONS` instead. See `RecaptchaLoaderOptions.onBeforeLoad` */
declare const RECAPTCHA_NONCE: InjectionToken<string>;
declare const RECAPTCHA_SETTINGS: InjectionToken<RecaptchaSettings>;
declare const RECAPTCHA_V3_SITE_KEY: InjectionToken<string>;
/**
* Specifies the options for loading the reCAPTCHA script tag.
*/
type RecaptchaLoaderOptions = {
/**
* Invoked before the `<script>` tag is appended to the DOM.
* Use this function as an opportunity to set `nonce`, as well as modify the URL of the tag.
*
* Use the `url.searchParams` to set additional query string attributes (including reCAPTCHA language),
* or use an entirely different base URL altogether.
*
* The URL that you provide will then properly set the `"render"` and `"onload"` attributes which are required for proper `ng-recaptcha` wire-up.
*
* @param url the current URL that was composed. Either modify it in-place, or return a completely new URL.
* @returns the final URL that is going to be used as the `src` for the `<script>` tag, along with (optionally) a nonce.
*
* @example
* Provide nonce:
* ```ts
* {
* provide: RECAPTCHA_LOADER_OPTIONS,
* useValue: {
* onBeforeLoad(url) {
* return {
* url,
* nonce: "YOUR_NONCE"
* };
* }
* }
* }
* ```
*
* Set the reCAPTCHA language:
* ```ts
* {
* provide: RECAPTCHA_LOADER_OPTIONS,
* useValue: {
* onBeforeLoad(url) {
* url.searchParams.set("hl", "en-GB")
*
* return { url };
* }
* }
* }
* ```
*
* Use a different base URL for loading reCAPTCHA
* ```ts
* {
* provide: RECAPTCHA_LOADER_OPTIONS,
* useValue: {
* onBeforeLoad(_url) {
* const chinaCompatibleUrl = new URL("https://www.recaptcha.net/recaptcha/api.js");
* // optionally, set the locale:
* // chinaCompatibleUrl.searchParams.set("hl", "zh-CN");
*
* return {
* url: chinaCompatibleUrl
* };
* }
* }
* }
* ```
*/
onBeforeLoad?(url: URL): {
url: URL;
nonce?: string;
};
/**
* Allows you to change the `grecaptcha` that the `ng-recaptcha` will be relying on.
* This method is useful when you need to use `grecaptcha.enterprise` instead of the base `grecaptcha`
*
* @param recaptcha the value of `window.grecaptcha` upon script load.
* @returns the {ReCaptchaV2.ReCaptcha} instance that the `ng-recaptcha` lib will use.
*
* @example
* Using the Enterprise version of `grecaptcha`:
*
* ```ts
* {
* provide: RECAPTCHA_LOADER_OPTIONS,
* useValue: {
* onBeforeLoad() {
* const recaptchaEnterpriseUrl = new URL("https://www.google.com/recaptcha/enterprise.js");
* // optionally, if you're using the reCAPTCHA session-tokens, set the `&waf=session` param,
* // see https://cloud.google.com/recaptcha-enterprise/docs/implement-waf-ca#session-token
* // recaptchaEnterpriseUrl.searchParams.set("waf", "session");
*
* return {
* url: recaptchaEnterpriseUrl,
* }
* },
* onLoaded(recaptcha) {
* return recaptcha.enterprise;
* }
* }
* }
* ```
*/
onLoaded?(recaptcha: ReCaptchaV2.ReCaptcha): ReCaptchaV2.ReCaptcha;
};
/**
* See the documentation for `RecaptchaLoaderOptions`.
*/
declare const RECAPTCHA_LOADER_OPTIONS: InjectionToken<RecaptchaLoaderOptions>;
declare class RecaptchaLoaderService {
private readonly platformId;
/**
* @internal
* @nocollapse
*/
private static ready;
ready: Observable<ReCaptchaV2.ReCaptcha>;
/** @internal */
private language?;
/** @internal */
private baseUrl?;
/** @internal */
private nonce?;
/** @internal */
private v3SiteKey?;
/** @internal */
private options?;
constructor(platformId: Object, language?: string, baseUrl?: string, nonce?: string, v3SiteKey?: string, options?: RecaptchaLoaderOptions);
/** @internal */
private init;
static ɵfac: i0.ɵɵFactoryDeclaration<RecaptchaLoaderService, [null, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }]>;
static ɵprov: i0.ɵɵInjectableDeclaration<RecaptchaLoaderService>;
}
type NeverUndefined<T> = T extends undefined ? never : T;
type RecaptchaErrorParameters = Parameters<NeverUndefined<ReCaptchaV2.Parameters["error-callback"]>>;
declare class RecaptchaComponent implements AfterViewInit, OnDestroy {
private elementRef;
private loader;
private zone;
id: string;
siteKey?: string;
theme?: ReCaptchaV2.Theme;
type?: ReCaptchaV2.Type;
size?: ReCaptchaV2.Size;
tabIndex?: number;
badge?: ReCaptchaV2.Badge;
errorMode: "handled" | "default";
resolved: EventEmitter<string | null>;
/**
* @deprecated `(error) output will be removed in the next major version. Use (errored) instead
*/
error: EventEmitter<[]>;
errored: EventEmitter<[]>;
/** @internal */
private subscription;
/** @internal */
private widget;
/** @internal */
private grecaptcha;
/** @internal */
private executeRequested;
constructor(elementRef: ElementRef<HTMLElement>, loader: RecaptchaLoaderService, zone: NgZone, settings?: RecaptchaSettings);
ngAfterViewInit(): void;
ngOnDestroy(): void;
/**
* Executes the invisible recaptcha.
* Does nothing if component's size is not set to "invisible".
*/
execute(): void;
reset(): void;
/**
* ⚠️ Warning! Use this property at your own risk!
*
* While this member is `public`, it is not a part of the component's public API.
* The semantic versioning guarantees _will not be honored_! Thus, you might find that this property behavior changes in incompatible ways in minor or even patch releases.
* You are **strongly advised** against using this property.
* Instead, use more idiomatic ways to get reCAPTCHA value, such as `resolved` EventEmitter, or form-bound methods (ngModel, formControl, and the likes).å
*/
get __unsafe_widgetValue(): string | null;
/** @internal */
private expired;
/** @internal */
private onError;
/** @internal */
private captchaResponseCallback;
/** @internal */
private grecaptchaReset;
/** @internal */
private renderRecaptcha;
static ɵfac: i0.ɵɵFactoryDeclaration<RecaptchaComponent, [null, null, null, { optional: true; }]>;
static ɵcmp: i0.ɵɵComponentDeclaration<RecaptchaComponent, "re-captcha", ["reCaptcha"], { "id": { "alias": "id"; "required": false; }; "siteKey": { "alias": "siteKey"; "required": false; }; "theme": { "alias": "theme"; "required": false; }; "type": { "alias": "type"; "required": false; }; "size": { "alias": "size"; "required": false; }; "tabIndex": { "alias": "tabIndex"; "required": false; }; "badge": { "alias": "badge"; "required": false; }; "errorMode": { "alias": "errorMode"; "required": false; }; }, { "resolved": "resolved"; "error": "error"; "errored": "errored"; }, never, never, false, never>;
}
declare class RecaptchaCommonModule {
static ɵfac: i0.ɵɵFactoryDeclaration<RecaptchaCommonModule, never>;
static ɵmod: i0.ɵɵNgModuleDeclaration<RecaptchaCommonModule, [typeof RecaptchaComponent], never, [typeof RecaptchaComponent]>;
static ɵinj: i0.ɵɵInjectorDeclaration<RecaptchaCommonModule>;
}
declare class RecaptchaModule {
static ɵfac: i0.ɵɵFactoryDeclaration<RecaptchaModule, never>;
static ɵmod: i0.ɵɵNgModuleDeclaration<RecaptchaModule, never, [typeof RecaptchaCommonModule], [typeof RecaptchaComponent]>;
static ɵinj: i0.ɵɵInjectorDeclaration<RecaptchaModule>;
}
declare class RecaptchaV3Module {
static ɵfac: i0.ɵɵFactoryDeclaration<RecaptchaV3Module, never>;
static ɵmod: i0.ɵɵNgModuleDeclaration<RecaptchaV3Module, never, never, never>;
static ɵinj: i0.ɵɵInjectorDeclaration<RecaptchaV3Module>;
}
interface OnExecuteData {
/**
* The name of the action that has been executed.
*/
action: string;
/**
* The token that reCAPTCHA v3 provided when executing the action.
*/
token: string;
}
interface OnExecuteErrorData {
/**
* The name of the action that has been executed.
*/
action: string;
/**
* The error which was encountered
*/
error: any;
}
/**
* The main service for working with reCAPTCHA v3 APIs.
*
* Use the `execute` method for executing a single action, and
* `onExecute` observable for listening to all actions at once.
*/
declare class ReCaptchaV3Service {
recaptchaLoader: RecaptchaLoaderService;
/** @internal */
private readonly siteKey;
/** @internal */
private readonly zone;
/** @internal */
private actionBacklog;
/** @internal */
private grecaptcha;
/** @internal */
private onExecuteSubject;
/** @internal */
private onExecuteErrorSubject;
/** @internal */
private onExecuteObservable;
/** @internal */
private onExecuteErrorObservable;
constructor(zone: NgZone, recaptchaLoader: RecaptchaLoaderService, siteKey: string);
get onExecute(): Observable<OnExecuteData>;
get onExecuteError(): Observable<OnExecuteErrorData>;
/**
* Executes the provided `action` with reCAPTCHA v3 API.
* Use the emitted token value for verification purposes on the backend.
*
* For more information about reCAPTCHA v3 actions and tokens refer to the official documentation at
* https://developers.google.com/recaptcha/docs/v3.
*
* @param {string} action the action to execute
* @returns {Observable<string>} an `Observable` that will emit the reCAPTCHA v3 string `token` value whenever ready.
* The returned `Observable` completes immediately after emitting a value.
*/
execute(action: string): Observable<string>;
/** @internal */
private executeActionWithSubject;
/** @internal */
private init;
static ɵfac: i0.ɵɵFactoryDeclaration<ReCaptchaV3Service, never>;
static ɵprov: i0.ɵɵInjectableDeclaration<ReCaptchaV3Service>;
}
declare class RecaptchaValueAccessorDirective implements ControlValueAccessor {
private host;
/** @internal */
private onChange;
/** @internal */
private onTouched;
private requiresControllerReset;
constructor(host: RecaptchaComponent);
writeValue(value: string): void;
registerOnChange(fn: (value: string) => void): void;
registerOnTouched(fn: () => void): void;
onResolve($event: string): void;
static ɵfac: i0.ɵɵFactoryDeclaration<RecaptchaValueAccessorDirective, never>;
static ɵdir: i0.ɵɵDirectiveDeclaration<RecaptchaValueAccessorDirective, "re-captcha[formControlName],re-captcha[formControl],re-captcha[ngModel]", never, {}, {}, never, never, false, never>;
}
declare class RecaptchaFormsModule {
static ɵfac: i0.ɵɵFactoryDeclaration<RecaptchaFormsModule, never>;
static ɵmod: i0.ɵɵNgModuleDeclaration<RecaptchaFormsModule, [typeof RecaptchaValueAccessorDirective], [typeof i2.FormsModule, typeof RecaptchaCommonModule], [typeof RecaptchaValueAccessorDirective]>;
static ɵinj: i0.ɵɵInjectorDeclaration<RecaptchaFormsModule>;
}
export { RECAPTCHA_BASE_URL, RECAPTCHA_LANGUAGE, RECAPTCHA_LOADER_OPTIONS, RECAPTCHA_NONCE, RECAPTCHA_SETTINGS, RECAPTCHA_V3_SITE_KEY, ReCaptchaV3Service, RecaptchaComponent, RecaptchaFormsModule, RecaptchaLoaderService, RecaptchaModule, RecaptchaV3Module, RecaptchaValueAccessorDirective };
export type { OnExecuteData, OnExecuteErrorData, RecaptchaErrorParameters, RecaptchaLoaderOptions, RecaptchaSettings };