@internetarchive/recaptcha-manager
Advanced tools
Comparing version 0.0.1-alpha.1 to 0.0.1-alpha.2
import { html, css, LitElement } from 'lit'; | ||
import { customElement, state } from 'lit/decorators.js'; | ||
import { RecaptchaWidget } from '../src/recaptcha-widget'; | ||
import { | ||
@@ -12,14 +13,32 @@ RecaptchaManager, | ||
private recaptchaManager?: RecaptchaManagerInterface; | ||
@state() result2?: string; | ||
private recaptchaManager: RecaptchaManagerInterface = new RecaptchaManager({ | ||
defaultSiteKey: '6LeTUvYUAAAAAPTvW98MaXyS8c6vxk4-9n8DI1ve', | ||
}); | ||
private recaptcha1?: RecaptchaWidget; | ||
private recaptcha2?: RecaptchaWidget; | ||
render() { | ||
return html` | ||
<button @click="${this.loadRecaptcha}">Load Recaptcha</button> | ||
<button @click="${this.executeRecaptcha}">Execute Recaptcha</button> | ||
<slot name="recaptcha"></slot> | ||
<p> | ||
<button @click="${this.loadRecaptcha}">Load Recaptcha</button | ||
><button @click="${this.executeRecaptcha}">Execute Recaptcha</button> | ||
</p> | ||
${this.result | ||
? html`<strong | ||
>Token:<strong><p>${this.result}</p></strong></strong | ||
>` | ||
? html`<p><strong>Token:</strong></p> | ||
<p>${this.result}</p>` | ||
: ''} | ||
<p> | ||
<button @click="${this.loadRecaptcha2}">Load Another Recaptcha</button | ||
><button @click="${this.executeRecaptcha2}"> | ||
Execute Another Recaptcha | ||
</button> | ||
</p> | ||
${this.result2 | ||
? html`<p><strong>Token 2:</strong></p> | ||
<p>${this.result2}</p>` | ||
: ''} | ||
`; | ||
@@ -29,15 +48,17 @@ } | ||
private async loadRecaptcha() { | ||
this.recaptchaManager = await RecaptchaManager.getRecaptchaManager({ | ||
siteKey: '6LeTUvYUAAAAAPTvW98MaXyS8c6vxk4-9n8DI1ve', | ||
this.recaptcha1 = await this.recaptchaManager?.getRecaptchaWidget({ | ||
recaptchaParams: { | ||
tabindex: 0, | ||
theme: 'light', | ||
type: 'image', | ||
}, | ||
}); | ||
const element = document.querySelector('#recaptcha') as HTMLDivElement; | ||
this.recaptchaManager?.setup(element, 0, 'light', 'image'); | ||
} | ||
private async executeRecaptcha() { | ||
if (!this.recaptchaManager) { | ||
if (!this.recaptcha1) { | ||
await this.loadRecaptcha(); | ||
} | ||
if (!this.recaptchaManager) { | ||
if (!this.recaptcha1) { | ||
console.error('error loading recaptcha'); | ||
@@ -47,5 +68,24 @@ return; | ||
this.result = await this.recaptchaManager.execute(); | ||
this.result = await this.recaptcha1.execute(); | ||
} | ||
private async loadRecaptcha2() { | ||
this.recaptcha2 = await this.recaptchaManager?.getRecaptchaWidget({ | ||
siteKey: '6LfDgOgeAAAAAEIzkbGeW4N_yQoN3PxhUYdkxbS6', | ||
}); | ||
} | ||
private async executeRecaptcha2() { | ||
if (!this.recaptcha2) { | ||
await this.loadRecaptcha(); | ||
} | ||
if (!this.recaptcha2) { | ||
console.error('error loading recaptcha'); | ||
return; | ||
} | ||
this.result2 = await this.recaptcha2.execute(); | ||
} | ||
static styles = css` | ||
@@ -52,0 +92,0 @@ :host { |
import { LitElement } from 'lit'; | ||
export declare class AppRoot extends LitElement { | ||
result?: string; | ||
private recaptchaManager?; | ||
result2?: string; | ||
private recaptchaManager; | ||
private recaptcha1?; | ||
private recaptcha2?; | ||
render(): import("lit").TemplateResult<1>; | ||
private loadRecaptcha; | ||
private executeRecaptcha; | ||
private loadRecaptcha2; | ||
private executeRecaptcha2; | ||
static styles: import("lit").CSSResult; | ||
} |
@@ -6,12 +6,28 @@ import { __decorate } from "tslib"; | ||
let AppRoot = class AppRoot extends LitElement { | ||
constructor() { | ||
super(...arguments); | ||
this.recaptchaManager = new RecaptchaManager({ | ||
defaultSiteKey: '6LeTUvYUAAAAAPTvW98MaXyS8c6vxk4-9n8DI1ve', | ||
}); | ||
} | ||
render() { | ||
return html ` | ||
<button @click="${this.loadRecaptcha}">Load Recaptcha</button> | ||
<button @click="${this.executeRecaptcha}">Execute Recaptcha</button> | ||
<slot name="recaptcha"></slot> | ||
<p> | ||
<button @click="${this.loadRecaptcha}">Load Recaptcha</button | ||
><button @click="${this.executeRecaptcha}">Execute Recaptcha</button> | ||
</p> | ||
${this.result | ||
? html `<strong | ||
>Token:<strong><p>${this.result}</p></strong></strong | ||
>` | ||
? html `<p><strong>Token:</strong></p> | ||
<p>${this.result}</p>` | ||
: ''} | ||
<p> | ||
<button @click="${this.loadRecaptcha2}">Load Another Recaptcha</button | ||
><button @click="${this.executeRecaptcha2}"> | ||
Execute Another Recaptcha | ||
</button> | ||
</p> | ||
${this.result2 | ||
? html `<p><strong>Token 2:</strong></p> | ||
<p>${this.result2}</p>` | ||
: ''} | ||
`; | ||
@@ -21,18 +37,36 @@ } | ||
var _a; | ||
this.recaptchaManager = await RecaptchaManager.getRecaptchaManager({ | ||
siteKey: '6LeTUvYUAAAAAPTvW98MaXyS8c6vxk4-9n8DI1ve', | ||
}); | ||
const element = document.querySelector('#recaptcha'); | ||
(_a = this.recaptchaManager) === null || _a === void 0 ? void 0 : _a.setup(element, 0, 'light', 'image'); | ||
this.recaptcha1 = await ((_a = this.recaptchaManager) === null || _a === void 0 ? void 0 : _a.getRecaptchaWidget({ | ||
recaptchaParams: { | ||
tabindex: 0, | ||
theme: 'light', | ||
type: 'image', | ||
}, | ||
})); | ||
} | ||
async executeRecaptcha() { | ||
if (!this.recaptchaManager) { | ||
if (!this.recaptcha1) { | ||
await this.loadRecaptcha(); | ||
} | ||
if (!this.recaptchaManager) { | ||
if (!this.recaptcha1) { | ||
console.error('error loading recaptcha'); | ||
return; | ||
} | ||
this.result = await this.recaptchaManager.execute(); | ||
this.result = await this.recaptcha1.execute(); | ||
} | ||
async loadRecaptcha2() { | ||
var _a; | ||
this.recaptcha2 = await ((_a = this.recaptchaManager) === null || _a === void 0 ? void 0 : _a.getRecaptchaWidget({ | ||
siteKey: '6LfDgOgeAAAAAEIzkbGeW4N_yQoN3PxhUYdkxbS6', | ||
})); | ||
} | ||
async executeRecaptcha2() { | ||
if (!this.recaptcha2) { | ||
await this.loadRecaptcha(); | ||
} | ||
if (!this.recaptcha2) { | ||
console.error('error loading recaptcha'); | ||
return; | ||
} | ||
this.result2 = await this.recaptcha2.execute(); | ||
} | ||
}; | ||
@@ -47,2 +81,5 @@ AppRoot.styles = css ` | ||
], AppRoot.prototype, "result", void 0); | ||
__decorate([ | ||
state() | ||
], AppRoot.prototype, "result2", void 0); | ||
AppRoot = __decorate([ | ||
@@ -49,0 +86,0 @@ customElement('app-root') |
@@ -1,1 +0,2 @@ | ||
export { RecaptchaManager, RecaptchaManagerInterface } from './src/recaptcha-manager'; | ||
export { RecaptchaManager, RecaptchaManagerInterface, } from './src/recaptcha-manager'; | ||
export { RecaptchaWidget, RecaptchaWidgetInterface, } from './src/recaptcha-widget'; |
@@ -1,2 +0,3 @@ | ||
export { RecaptchaManager } from './src/recaptcha-manager'; | ||
export { RecaptchaManager, } from './src/recaptcha-manager'; | ||
export { RecaptchaWidget, } from './src/recaptcha-widget'; | ||
//# sourceMappingURL=index.js.map |
/// <reference types="grecaptcha" /> | ||
import { LazyLoaderServiceInterface } from '@internetarchive/lazy-loader-service'; | ||
import { RecaptchaWidget } from './recaptcha-widget'; | ||
export interface RecaptchaManagerInterface { | ||
execute(): Promise<string>; | ||
setup(container: HTMLElement, tabIndex: number, theme: ReCaptchaV2.Theme, type: ReCaptchaV2.Type): void; | ||
/** | ||
* Load a recaptcha widget for a given site key or the default site key. | ||
*/ | ||
getRecaptchaWidget(options?: { | ||
siteKey?: string; | ||
recaptchaParams?: ReCaptchaV2.Parameters; | ||
}): Promise<RecaptchaWidget>; | ||
} | ||
export declare class RecaptchaManager implements RecaptchaManagerInterface { | ||
/** | ||
* This is a convenience initializer that also lazily loads | ||
* the recaptcha library from Google. | ||
* | ||
* @param options | ||
* @returns | ||
*/ | ||
static getRecaptchaManager(options: { | ||
siteKey: string; | ||
}): Promise<RecaptchaManagerInterface>; | ||
/** | ||
* Load the Recaptch library from Google. | ||
* | ||
* @param options | ||
* @returns | ||
*/ | ||
static loadRecaptchaLibrary(options?: { | ||
private lazyLoader; | ||
private defaultSiteKey?; | ||
private recaptchaCache; | ||
constructor(options: { | ||
defaultSiteKey: string; | ||
lazyLoader?: LazyLoaderServiceInterface; | ||
}): Promise<ReCaptchaV2.ReCaptcha>; | ||
private grecaptchaLibrary; | ||
private siteKey; | ||
constructor(options: { | ||
grecaptchaLibrary: ReCaptchaV2.ReCaptcha; | ||
siteKey: string; | ||
grecaptchaLibrary?: ReCaptchaV2.ReCaptcha; | ||
}); | ||
private executionSuccessBlock?; | ||
private executionExpiredBlock?; | ||
private executionErrorBlock?; | ||
private isExecuting; | ||
/** @inheritdoc */ | ||
getRecaptchaWidget(options?: { | ||
siteKey?: string; | ||
recaptchaParams?: ReCaptchaV2.Parameters; | ||
}): Promise<RecaptchaWidget>; | ||
/** | ||
* Execute Recaptcha and return a Promise containing the response token. | ||
* Load the Recaptch library from Google. | ||
* | ||
* This is an interesting flow.. we call `execute()` here, but have to wait for the | ||
* response and expiration handlers that we bind during the inital `setup` call. | ||
* For consumers, we want to be able to just call `execute()` and wait for a response. | ||
* To allow this, we assign two callbacks: | ||
* - `executionSuccessBlock` | ||
* - `executionExpiredBlock` | ||
* | ||
* We then call those callbacks from inside `responseHandler` and `expiredHandler` to | ||
* either resolve or reject the Promise. | ||
* | ||
* ie: | ||
* | ||
* try { | ||
* const recaptchaResult = await recaptchaManager.execute(); | ||
* console.log('recaptcha token:', recaptchaResult); | ||
* } catch { | ||
* console.error('something happened') | ||
* } | ||
* | ||
* @returns {Promise<string>} | ||
* @memberof RecaptchaManager | ||
* @returns Promise<ReCaptchaV2.ReCaptcha> | ||
*/ | ||
execute(): Promise<string>; | ||
private finishExecution; | ||
setup(container: HTMLElement, tabIndex: number, theme: ReCaptchaV2.Theme, type: ReCaptchaV2.Type): void; | ||
private responseHandler; | ||
private expiredHandler; | ||
private errorHandler; | ||
private getRecaptchaLibrary; | ||
/** don't use directly, use `getRecaptchaLibrary()` */ | ||
private grecaptchaLibraryCache?; | ||
} |
import { LazyLoaderService, } from '@internetarchive/lazy-loader-service'; | ||
import { RecaptchaWidget } from './recaptcha-widget'; | ||
export class RecaptchaManager { | ||
constructor(options) { | ||
this.isExecuting = false; | ||
this.grecaptchaLibrary = options.grecaptchaLibrary; | ||
this.siteKey = options.siteKey; | ||
var _a; | ||
this.recaptchaCache = {}; | ||
this.defaultSiteKey = options.defaultSiteKey; | ||
this.lazyLoader = (_a = options.lazyLoader) !== null && _a !== void 0 ? _a : new LazyLoaderService(); | ||
this.grecaptchaLibraryCache = options.grecaptchaLibrary; | ||
} | ||
/** | ||
* This is a convenience initializer that also lazily loads | ||
* the recaptcha library from Google. | ||
* | ||
* @param options | ||
* @returns | ||
*/ | ||
static async getRecaptchaManager(options) { | ||
const grecaptchaLibrary = await RecaptchaManager.loadRecaptchaLibrary(); | ||
return new RecaptchaManager({ | ||
/** @inheritdoc */ | ||
async getRecaptchaWidget(options) { | ||
var _a; | ||
const key = (_a = options === null || options === void 0 ? void 0 : options.siteKey) !== null && _a !== void 0 ? _a : this.defaultSiteKey; | ||
if (!key) { | ||
throw new Error('RecaptchaManager requires a site key'); | ||
} | ||
const cached = this.recaptchaCache[key]; | ||
if (cached) | ||
return cached; | ||
const grecaptchaLibrary = await this.getRecaptchaLibrary(); | ||
const recaptcha = new RecaptchaWidget({ | ||
siteKey: key, | ||
grecaptchaLibrary, | ||
siteKey: options.siteKey, | ||
}); | ||
}, options === null || options === void 0 ? void 0 : options.recaptchaParams); | ||
this.recaptchaCache[key] = recaptcha; | ||
return recaptcha; | ||
} | ||
@@ -25,8 +32,8 @@ /** | ||
* | ||
* @param options | ||
* @returns | ||
* @returns Promise<ReCaptchaV2.ReCaptcha> | ||
*/ | ||
static async loadRecaptchaLibrary(options) { | ||
var _a; | ||
const service = (_a = options === null || options === void 0 ? void 0 : options.lazyLoader) !== null && _a !== void 0 ? _a : new LazyLoaderService(); | ||
async getRecaptchaLibrary() { | ||
if (this.grecaptchaLibraryCache) { | ||
return this.grecaptchaLibraryCache; | ||
} | ||
return new Promise(resolve => { | ||
@@ -38,5 +45,6 @@ window.grecaptchaLoadedCallback = () => { | ||
}, 10); | ||
this.grecaptchaLibraryCache = window.grecaptcha; | ||
resolve(window.grecaptcha); | ||
}; | ||
service.loadScript({ | ||
this.lazyLoader.loadScript({ | ||
src: 'https://www.google.com/recaptcha/api.js?onload=grecaptchaLoadedCallback&render=explicit', | ||
@@ -46,84 +54,3 @@ }); | ||
} | ||
/** | ||
* Execute Recaptcha and return a Promise containing the response token. | ||
* | ||
* This is an interesting flow.. we call `execute()` here, but have to wait for the | ||
* response and expiration handlers that we bind during the inital `setup` call. | ||
* For consumers, we want to be able to just call `execute()` and wait for a response. | ||
* To allow this, we assign two callbacks: | ||
* - `executionSuccessBlock` | ||
* - `executionExpiredBlock` | ||
* | ||
* We then call those callbacks from inside `responseHandler` and `expiredHandler` to | ||
* either resolve or reject the Promise. | ||
* | ||
* ie: | ||
* | ||
* try { | ||
* const recaptchaResult = await recaptchaManager.execute(); | ||
* console.log('recaptcha token:', recaptchaResult); | ||
* } catch { | ||
* console.error('something happened') | ||
* } | ||
* | ||
* @returns {Promise<string>} | ||
* @memberof RecaptchaManager | ||
*/ | ||
execute() { | ||
if (this.isExecuting) { | ||
this.finishExecution(); | ||
} | ||
this.isExecuting = true; | ||
return new Promise((resolve, reject) => { | ||
this.executionSuccessBlock = (token) => { | ||
this.finishExecution(); | ||
resolve(token); | ||
}; | ||
this.executionExpiredBlock = () => { | ||
this.finishExecution(); | ||
reject(new Error('expired')); | ||
}; | ||
this.executionErrorBlock = () => { | ||
this.finishExecution(); | ||
reject(new Error('error')); | ||
}; | ||
this.grecaptchaLibrary.execute(); | ||
}); | ||
} | ||
finishExecution() { | ||
this.isExecuting = false; | ||
this.grecaptchaLibrary.reset(); | ||
} | ||
setup(container, tabIndex, theme, type) { | ||
this.grecaptchaLibrary.render(container, { | ||
callback: this.responseHandler.bind(this), | ||
'expired-callback': this.expiredHandler.bind(this), | ||
'error-callback': this.errorHandler.bind(this), | ||
sitekey: this.siteKey, | ||
tabindex: tabIndex, | ||
theme, | ||
type, | ||
size: 'invisible', | ||
}); | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
responseHandler(response) { | ||
if (this.executionSuccessBlock) { | ||
this.executionSuccessBlock(response); | ||
this.executionSuccessBlock = undefined; | ||
} | ||
} | ||
expiredHandler() { | ||
if (this.executionExpiredBlock) { | ||
this.executionExpiredBlock(); | ||
this.executionExpiredBlock = undefined; | ||
} | ||
} | ||
errorHandler() { | ||
if (this.executionErrorBlock) { | ||
this.executionErrorBlock(); | ||
this.executionErrorBlock = undefined; | ||
} | ||
} | ||
} | ||
//# sourceMappingURL=recaptcha-manager.js.map |
"use strict"; | ||
describe('YourWebComponent', () => { | ||
}); | ||
describe('YourWebComponent', () => { }); | ||
//# sourceMappingURL=recaptcha-manager.test.js.map |
10
index.ts
@@ -1,1 +0,9 @@ | ||
export { RecaptchaManager, RecaptchaManagerInterface } from './src/recaptcha-manager'; | ||
export { | ||
RecaptchaManager, | ||
RecaptchaManagerInterface, | ||
} from './src/recaptcha-manager'; | ||
export { | ||
RecaptchaWidget, | ||
RecaptchaWidgetInterface, | ||
} from './src/recaptcha-widget'; |
@@ -10,3 +10,3 @@ { | ||
"author": "Internet Archive", | ||
"version": "0.0.1-alpha.1", | ||
"version": "0.0.1-alpha.2", | ||
"main": "dist/index.js", | ||
@@ -13,0 +13,0 @@ "module": "dist/index.js", |
@@ -5,42 +5,66 @@ import { | ||
} from '@internetarchive/lazy-loader-service'; | ||
import { RecaptchaWidget } from './recaptcha-widget'; | ||
export interface RecaptchaManagerInterface { | ||
execute(): Promise<string>; | ||
setup( | ||
container: HTMLElement, | ||
tabIndex: number, | ||
theme: ReCaptchaV2.Theme, | ||
type: ReCaptchaV2.Type | ||
): void; | ||
/** | ||
* Load a recaptcha widget for a given site key or the default site key. | ||
*/ | ||
getRecaptchaWidget(options?: { | ||
siteKey?: string; | ||
recaptchaParams?: ReCaptchaV2.Parameters; | ||
}): Promise<RecaptchaWidget>; | ||
} | ||
export class RecaptchaManager implements RecaptchaManagerInterface { | ||
/** | ||
* This is a convenience initializer that also lazily loads | ||
* the recaptcha library from Google. | ||
* | ||
* @param options | ||
* @returns | ||
*/ | ||
static async getRecaptchaManager(options: { | ||
siteKey: string; | ||
}): Promise<RecaptchaManagerInterface> { | ||
const grecaptchaLibrary = await RecaptchaManager.loadRecaptchaLibrary(); | ||
return new RecaptchaManager({ | ||
grecaptchaLibrary, | ||
siteKey: options.siteKey, | ||
}); | ||
private lazyLoader: LazyLoaderServiceInterface; | ||
private defaultSiteKey?: string; | ||
private recaptchaCache: Record<string, RecaptchaWidget> = {}; | ||
constructor(options: { | ||
defaultSiteKey: string; | ||
lazyLoader?: LazyLoaderServiceInterface; | ||
grecaptchaLibrary?: ReCaptchaV2.ReCaptcha; // allows dependency injection or will be lazy loaded | ||
}) { | ||
this.defaultSiteKey = options.defaultSiteKey; | ||
this.lazyLoader = options.lazyLoader ?? new LazyLoaderService(); | ||
this.grecaptchaLibraryCache = options.grecaptchaLibrary; | ||
} | ||
/** @inheritdoc */ | ||
async getRecaptchaWidget(options?: { | ||
siteKey?: string; | ||
recaptchaParams?: ReCaptchaV2.Parameters; | ||
}): Promise<RecaptchaWidget> { | ||
const key = options?.siteKey ?? this.defaultSiteKey; | ||
if (!key) { | ||
throw new Error('RecaptchaManager requires a site key'); | ||
} | ||
const cached = this.recaptchaCache[key]; | ||
if (cached) return cached; | ||
const grecaptchaLibrary = await this.getRecaptchaLibrary(); | ||
const recaptcha = new RecaptchaWidget( | ||
{ | ||
siteKey: key, | ||
grecaptchaLibrary, | ||
}, | ||
options?.recaptchaParams | ||
); | ||
this.recaptchaCache[key] = recaptcha; | ||
return recaptcha; | ||
} | ||
/** | ||
* Load the Recaptch library from Google. | ||
* | ||
* @param options | ||
* @returns | ||
* @returns Promise<ReCaptchaV2.ReCaptcha> | ||
*/ | ||
static async loadRecaptchaLibrary(options?: { | ||
lazyLoader?: LazyLoaderServiceInterface; | ||
}): Promise<ReCaptchaV2.ReCaptcha> { | ||
const service = options?.lazyLoader ?? new LazyLoaderService(); | ||
private async getRecaptchaLibrary(): Promise<ReCaptchaV2.ReCaptcha> { | ||
if (this.grecaptchaLibraryCache) { | ||
return this.grecaptchaLibraryCache; | ||
} | ||
return new Promise(resolve => { | ||
@@ -52,6 +76,7 @@ (window as any).grecaptchaLoadedCallback = (): void => { | ||
}, 10); | ||
this.grecaptchaLibraryCache = window.grecaptcha; | ||
resolve(window.grecaptcha); | ||
}; | ||
service.loadScript({ | ||
this.lazyLoader.loadScript({ | ||
src: 'https://www.google.com/recaptcha/api.js?onload=grecaptchaLoadedCallback&render=explicit', | ||
@@ -62,116 +87,4 @@ }); | ||
private grecaptchaLibrary: ReCaptchaV2.ReCaptcha; | ||
private siteKey: string; | ||
constructor(options: { | ||
grecaptchaLibrary: ReCaptchaV2.ReCaptcha; | ||
siteKey: string; | ||
}) { | ||
this.grecaptchaLibrary = options.grecaptchaLibrary; | ||
this.siteKey = options.siteKey; | ||
} | ||
private executionSuccessBlock?: (token: string) => void; | ||
private executionExpiredBlock?: () => void; | ||
private executionErrorBlock?: () => void; | ||
private isExecuting = false; | ||
/** | ||
* Execute Recaptcha and return a Promise containing the response token. | ||
* | ||
* This is an interesting flow.. we call `execute()` here, but have to wait for the | ||
* response and expiration handlers that we bind during the inital `setup` call. | ||
* For consumers, we want to be able to just call `execute()` and wait for a response. | ||
* To allow this, we assign two callbacks: | ||
* - `executionSuccessBlock` | ||
* - `executionExpiredBlock` | ||
* | ||
* We then call those callbacks from inside `responseHandler` and `expiredHandler` to | ||
* either resolve or reject the Promise. | ||
* | ||
* ie: | ||
* | ||
* try { | ||
* const recaptchaResult = await recaptchaManager.execute(); | ||
* console.log('recaptcha token:', recaptchaResult); | ||
* } catch { | ||
* console.error('something happened') | ||
* } | ||
* | ||
* @returns {Promise<string>} | ||
* @memberof RecaptchaManager | ||
*/ | ||
execute(): Promise<string> { | ||
if (this.isExecuting) { | ||
this.finishExecution(); | ||
} | ||
this.isExecuting = true; | ||
return new Promise((resolve, reject) => { | ||
this.executionSuccessBlock = (token: string): void => { | ||
this.finishExecution(); | ||
resolve(token); | ||
}; | ||
this.executionExpiredBlock = (): void => { | ||
this.finishExecution(); | ||
reject(new Error('expired')); | ||
}; | ||
this.executionErrorBlock = (): void => { | ||
this.finishExecution(); | ||
reject(new Error('error')); | ||
}; | ||
this.grecaptchaLibrary.execute(); | ||
}); | ||
} | ||
private finishExecution(): void { | ||
this.isExecuting = false; | ||
this.grecaptchaLibrary.reset(); | ||
} | ||
setup( | ||
container: HTMLElement, | ||
tabIndex: number, | ||
theme: ReCaptchaV2.Theme, | ||
type: ReCaptchaV2.Type | ||
): void { | ||
this.grecaptchaLibrary.render(container, { | ||
callback: this.responseHandler.bind(this), | ||
'expired-callback': this.expiredHandler.bind(this), | ||
'error-callback': this.errorHandler.bind(this), | ||
sitekey: this.siteKey, | ||
tabindex: tabIndex, | ||
theme, | ||
type, | ||
size: 'invisible', | ||
}); | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
private responseHandler(response: any): void { | ||
if (this.executionSuccessBlock) { | ||
this.executionSuccessBlock(response); | ||
this.executionSuccessBlock = undefined; | ||
} | ||
} | ||
private expiredHandler(): void { | ||
if (this.executionExpiredBlock) { | ||
this.executionExpiredBlock(); | ||
this.executionExpiredBlock = undefined; | ||
} | ||
} | ||
private errorHandler(): void { | ||
if (this.executionErrorBlock) { | ||
this.executionErrorBlock(); | ||
this.executionErrorBlock = undefined; | ||
} | ||
} | ||
/** don't use directly, use `getRecaptchaLibrary()` */ | ||
private grecaptchaLibraryCache?: ReCaptchaV2.ReCaptcha; | ||
} |
@@ -1,3 +0,1 @@ | ||
describe('YourWebComponent', () => { | ||
}); | ||
describe('YourWebComponent', () => {}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
125047
42
1224
1