@herdwatch/ng-recaptcha
Version:
Angular component for Google reCAPTCHA
106 lines • 14.8 kB
JavaScript
import { Inject, Injectable } from "@angular/core";
import { Subject } from "rxjs";
import { RECAPTCHA_V3_SITE_KEY } from "./tokens";
import * as i0 from "@angular/core";
import * as i1 from "./recaptcha-loader.service";
/**
* 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.
*/
export class ReCaptchaV3Service {
constructor(zone, recaptchaLoader, siteKey) {
this.recaptchaLoader = recaptchaLoader;
this.zone = zone;
this.siteKey = siteKey;
this.init();
}
get onExecute() {
if (!this.onExecuteSubject) {
this.onExecuteSubject = new Subject();
this.onExecuteObservable = this.onExecuteSubject.asObservable();
}
return this.onExecuteObservable;
}
get onExecuteError() {
if (!this.onExecuteErrorSubject) {
this.onExecuteErrorSubject = new Subject();
this.onExecuteErrorObservable = this.onExecuteErrorSubject.asObservable();
}
return this.onExecuteErrorObservable;
}
/**
* 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) {
const subject = new Subject();
if (!this.grecaptcha) {
if (!this.actionBacklog) {
this.actionBacklog = [];
}
this.actionBacklog.push([action, subject]);
}
else {
this.executeActionWithSubject(action, subject);
}
return subject.asObservable();
}
/** @internal */
executeActionWithSubject(action, subject) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const onError = (error) => {
this.zone.run(() => {
subject.error(error);
if (this.onExecuteErrorSubject) {
// We don't know any better at this point, unfortunately, so have to resort to `any`
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
this.onExecuteErrorSubject.next({ action, error });
}
});
};
this.zone.runOutsideAngular(() => {
try {
this.grecaptcha.execute(this.siteKey, { action }).then((token) => {
this.zone.run(() => {
subject.next(token);
subject.complete();
if (this.onExecuteSubject) {
this.onExecuteSubject.next({ action, token });
}
});
}, onError);
}
catch (e) {
onError(e);
}
});
}
/** @internal */
init() {
this.recaptchaLoader.ready.subscribe((value) => {
this.grecaptcha = value;
if (this.actionBacklog && this.actionBacklog.length > 0) {
this.actionBacklog.forEach(([action, subject]) => this.executeActionWithSubject(action, subject));
this.actionBacklog = undefined;
}
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: ReCaptchaV3Service, deps: [{ token: i0.NgZone }, { token: i1.RecaptchaLoaderService }, { token: RECAPTCHA_V3_SITE_KEY }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: ReCaptchaV3Service }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: ReCaptchaV3Service, decorators: [{
type: Injectable
}], ctorParameters: () => [{ type: i0.NgZone }, { type: i1.RecaptchaLoaderService }, { type: undefined, decorators: [{
type: Inject,
args: [RECAPTCHA_V3_SITE_KEY]
}] }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjYXB0Y2hhLXYzLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1yZWNhcHRjaGEvc3JjL2xpYi9yZWNhcHRjaGEtdjMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBVSxNQUFNLGVBQWUsQ0FBQztBQUMzRCxPQUFPLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRTNDLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLFVBQVUsQ0FBQzs7O0FBNEJqRDs7Ozs7R0FLRztBQUVILE1BQU0sT0FBTyxrQkFBa0I7SUFtQjdCLFlBQ0UsSUFBWSxFQUNMLGVBQXVDLEVBQ2YsT0FBZTtRQUR2QyxvQkFBZSxHQUFmLGVBQWUsQ0FBd0I7UUFHOUMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFFdkIsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ2QsQ0FBQztJQUVELElBQVcsU0FBUztRQUNsQixJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksT0FBTyxFQUFpQixDQUFDO1lBQ3JELElBQUksQ0FBQyxtQkFBbUIsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDbEUsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDO0lBQ2xDLENBQUM7SUFFRCxJQUFXLGNBQWM7UUFDdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1lBQ2hDLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLE9BQU8sRUFBc0IsQ0FBQztZQUMvRCxJQUFJLENBQUMsd0JBQXdCLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixDQUFD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QUM7WUFDakMsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQzs4R0FsSFUsa0JBQWtCLDhFQXNCbkIscUJBQXFCO2tIQXRCcEIsa0JBQWtCOzsyRkFBbEIsa0JBQWtCO2tCQUQ5QixVQUFVOzswQkF1Qk4sTUFBTTsyQkFBQyxxQkFBcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIE5nWm9uZSB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSBcInJ4anNcIjtcblxuaW1wb3J0IHsgUkVDQVBUQ0hBX1YzX1NJVEVfS0VZIH0gZnJvbSBcIi4vdG9rZW5zXCI7XG5pbXBvcnQgeyBSZWNhcHRjaGFMb2FkZXJTZXJ2aWNlIH0gZnJvbSBcIi4vcmVjYXB0Y2hhLWxvYWRlci5zZXJ2aWNlXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgT25FeGVjdXRlRGF0YSB7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgYWN0aW9uIHRoYXQgaGFzIGJlZW4gZXhlY3V0ZWQuXG4gICAqL1xuICBhY3Rpb246IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSB0b2tlbiB0aGF0IHJlQ0FQVENIQSB2MyBwcm92aWRlZCB3aGVuIGV4ZWN1dGluZyB0aGUgYWN0aW9uLlxuICAgKi9cbiAgdG9rZW46IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPbkV4ZWN1dGVFcnJvckRhdGEge1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIGFjdGlvbiB0aGF0IGhhcyBiZWVuIGV4ZWN1dGVkLlxuICAgKi9cbiAgYWN0aW9uOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBUaGUgZXJyb3Igd2hpY2ggd2FzIGVuY291bnRlcmVkXG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBlcnJvcjogYW55O1xufVxuXG50eXBlIEFjdGlvbkJhY2tsb2dFbnRyeSA9IFtzdHJpbmcsIFN1YmplY3Q8c3RyaW5nPl07XG5cbi8qKlxuICogVGhlIG1haW4gc2VydmljZSBmb3Igd29ya2luZyB3aXRoIHJlQ0FQVENIQSB2MyBBUElzLlxuICpcbiAqIFVzZSB0aGUgYGV4ZWN1dGVgIG1ldGhvZCBmb3IgZXhlY3V0aW5nIGEgc2luZ2xlIGFjdGlvbiwgYW5kXG4gKiBgb25FeGVjdXRlYCBvYnNlcnZhYmxlIGZvciBsaXN0ZW5pbmcgdG8gYWxsIGFjdGlvbnMgYXQgb25jZS5cbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFJlQ2FwdGNoYVYzU2VydmljZSB7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBzaXRlS2V5OiBzdHJpbmc7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJpdmF0ZSByZWFkb25seSB6b25lOiBOZ1pvbmU7XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJpdmF0ZSBhY3Rpb25CYWNrbG9nOiBBY3Rpb25CYWNrbG9nRW50cnlbXSB8IHVuZGVmaW5lZDtcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcml2YXRlIGdyZWNhcHRjaGE6IFJlQ2FwdGNoYVYyLlJlQ2FwdGNoYTtcblxuICAvKiogQGludGVybmFsICovXG4gIHByaXZhdGUgb25FeGVjdXRlU3ViamVjdDogU3ViamVjdDxPbkV4ZWN1dGVEYXRhPjtcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcml2YXRlIG9uRXhlY3V0ZUVycm9yU3ViamVjdDogU3ViamVjdDxPbkV4ZWN1dGVFcnJvckRhdGE+O1xuICAvKiogQGludGVybmFsICovXG4gIHByaXZhdGUgb25FeGVjdXRlT2JzZXJ2YWJsZTogT2JzZXJ2YWJsZTxPbkV4ZWN1dGVEYXRhPjtcbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcml2YXRlIG9uRXhlY3V0ZUVycm9yT2JzZXJ2YWJsZTogT2JzZXJ2YWJsZTxPbkV4ZWN1dGVFcnJvckRhdGE+O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHpvbmU6IE5nWm9uZSxcbiAgICBwdWJsaWMgcmVjYXB0Y2hhTG9hZGVyOiBSZWNhcHRjaGFMb2FkZXJTZXJ2aWNlLFxuICAgIEBJbmplY3QoUkVDQVBUQ0hBX1YzX1NJVEVfS0VZKSBzaXRlS2V5OiBzdHJpbmcsXG4gICkge1xuICAgIHRoaXMuem9uZSA9IHpvbmU7XG4gICAgdGhpcy5zaXRlS2V5ID0gc2l0ZUtleTtcblxuICAgIHRoaXMuaW5pdCgpO1xuICB9XG5cbiAgcHVibGljIGdldCBvbkV4ZWN1dGUoKTogT2JzZXJ2YWJsZTxPbkV4ZWN1dGVEYXRhPiB7XG4gICAgaWYgKCF0aGlzLm9uRXhlY3V0ZVN1YmplY3QpIHtcbiAgICAgIHRoaXMub25FeGVjdXRlU3ViamVjdCA9IG5ldyBTdWJqZWN0PE9uRXhlY3V0ZURhdGE+KCk7XG4gICAgICB0aGlzLm9uRXhlY3V0ZU9ic2VydmFibGUgPSB0aGlzLm9uRXhlY3V0ZVN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMub25FeGVjdXRlT2JzZXJ2YWJsZTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgb25FeGVjdXRlRXJyb3IoKTogT2JzZXJ2YWJsZTxPbkV4ZWN1dGVFcnJvckRhdGE+IHtcbiAgICBpZiAoIXRoaXMub25FeGVjdXRlRXJyb3JTdWJqZWN0KSB7XG4gICAgICB0aGlzLm9uRXhlY3V0ZUVycm9yU3ViamVjdCA9IG5ldyBTdWJqZWN0PE9uRXhlY3V0ZUVycm9yRGF0YT4oKTtcbiAgICAgIHRoaXMub25FeGVjdXRlRXJyb3JPYnNlcnZhYmxlID0gdGhpcy5vbkV4ZWN1dGVFcnJvclN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMub25FeGVjdXRlRXJyb3JPYnNlcnZhYmxlO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGVzIHRoZSBwcm92aWRlZCBgYWN0aW9uYCB3aXRoIHJlQ0FQVENIQSB2MyBBUEkuXG4gICAqIFVzZSB0aGUgZW1pdHRlZCB0b2tlbiB2YWx1ZSBmb3IgdmVyaWZpY2F0aW9uIHB1cnBvc2VzIG9uIHRoZSBiYWNrZW5kLlxuICAgKlxuICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCByZUNBUFRDSEEgdjMgYWN0aW9ucyBhbmQgdG9rZW5zIHJlZmVyIHRvIHRoZSBvZmZpY2lhbCBkb2N1bWVudGF0aW9uIGF0XG4gICAqIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL3JlY2FwdGNoYS9kb2NzL3YzLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYWN0aW9uIHRoZSBhY3Rpb24gdG8gZXhlY3V0ZVxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZTxzdHJpbmc+fSBhbiBgT2JzZXJ2YWJsZWAgdGhhdCB3aWxsIGVtaXQgdGhlIHJlQ0FQVENIQSB2MyBzdHJpbmcgYHRva2VuYCB2YWx1ZSB3aGVuZXZlciByZWFkeS5cbiAgICogVGhlIHJldHVybmVkIGBPYnNlcnZhYmxlYCBjb21wbGV0ZXMgaW1tZWRpYXRlbHkgYWZ0ZXIgZW1pdHRpbmcgYSB2YWx1ZS5cbiAgICovXG4gIHB1YmxpYyBleGVjdXRlKGFjdGlvbjogc3RyaW5nKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgICBjb25zdCBzdWJqZWN0ID0gbmV3IFN1YmplY3Q8c3RyaW5nPigpO1xuICAgIGlmICghdGhpcy5ncmVjYXB0Y2hhKSB7XG4gICAgICBpZiAoIXRoaXMuYWN0aW9uQmFja2xvZykge1xuICAgICAgICB0aGlzLmFjdGlvbkJhY2tsb2cgPSBbXTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hY3Rpb25CYWNrbG9nLnB1c2goW2FjdGlvbiwgc3ViamVjdF0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmV4ZWN1dGVBY3Rpb25XaXRoU3ViamVjdChhY3Rpb24sIHN1YmplY3QpO1xuICAgIH1cblxuICAgIHJldHVybiBzdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcml2YXRlIGV4ZWN1dGVBY3Rpb25XaXRoU3ViamVjdChhY3Rpb246IHN0cmluZywgc3ViamVjdDogU3ViamVjdDxzdHJpbmc+KTogdm9pZCB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICBjb25zdCBvbkVycm9yID0gKGVycm9yOiBhbnkpID0+IHtcbiAgICAgIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xuICAgICAgICBzdWJqZWN0LmVycm9yKGVycm9yKTtcbiAgICAgICAgaWYgKHRoaXMub25FeGVjdXRlRXJyb3JTdWJqZWN0KSB7XG4gICAgICAgICAgLy8gV2UgZG9uJ3Qga25vdyBhbnkgYmV0dGVyIGF0IHRoaXMgcG9pbnQsIHVuZm9ydHVuYXRlbHksIHNvIGhhdmUgdG8gcmVzb3J0IHRvIGBhbnlgXG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtYXNzaWdubWVudFxuICAgICAgICAgIHRoaXMub25FeGVjdXRlRXJyb3JTdWJqZWN0Lm5leHQoeyBhY3Rpb24sIGVycm9yIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuZ3JlY2FwdGNoYS5leGVjdXRlKHRoaXMuc2l0ZUtleSwgeyBhY3Rpb24gfSkudGhlbigodG9rZW46IHN0cmluZykgPT4ge1xuICAgICAgICAgIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgc3ViamVjdC5uZXh0KHRva2VuKTtcbiAgICAgICAgICAgIHN1YmplY3QuY29tcGxldGUoKTtcbiAgICAgICAgICAgIGlmICh0aGlzLm9uRXhlY3V0ZVN1YmplY3QpIHtcbiAgICAgICAgICAgICAgdGhpcy5vbkV4ZWN1dGVTdWJqZWN0Lm5leHQoeyBhY3Rpb24sIHRva2VuIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9LCBvbkVycm9yKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgb25FcnJvcihlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJpdmF0ZSBpbml0KCkge1xuICAgIHRoaXMucmVjYXB0Y2hhTG9hZGVyLnJlYWR5LnN1YnNjcmliZSgodmFsdWUpID0+IHtcbiAgICAgIHRoaXMuZ3JlY2FwdGNoYSA9IHZhbHVlO1xuICAgICAgaWYgKHRoaXMuYWN0aW9uQmFja2xvZyAmJiB0aGlzLmFjdGlvbkJhY2tsb2cubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmFjdGlvbkJhY2tsb2cuZm9yRWFjaCgoW2FjdGlvbiwgc3ViamVjdF0pID0+IHRoaXMuZXhlY3V0ZUFjdGlvbldpdGhTdWJqZWN0KGFjdGlvbiwgc3ViamVjdCkpO1xuICAgICAgICB0aGlzLmFjdGlvbkJhY2tsb2cgPSB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==