@internetarchive/recaptcha-manager 1.0.0 → 2.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 CHANGED
@@ -1,63 +1,63 @@
1
- ![Build Status](https://github.com/internetarchive/iaux-recaptcha-manager/actions/workflows/ci.yml/badge.svg)
2
-
3
- # Internet Archive reCaptcha Manager
4
-
5
- A library to lazy load and interact with reCaptcha
6
-
7
- ## Installation
8
-
9
- ```shell
10
- > npm install @internetarchive/recaptcha-manager
11
- ```
12
-
13
- ## Usage
14
-
15
- ```ts
16
- const recaptchaManager = new RecaptchaManager({
17
- defaultSiteKey: 'your-site-key',
18
- });
19
-
20
- // will load recaptcha library if it's not loaded
21
- const recaptchaWidget = await recaptchaManager.getRecaptchaWidget({
22
- recaptchaParams: {
23
- tabindex: 0,
24
- theme: 'light',
25
- type: 'image',
26
- },
27
- });
28
-
29
- const token = await recaptchaWidget.execute();
30
-
31
- // submit token with your post and validate on the backend
32
- ```
33
-
34
- For more usage examples, see `demo/app-root.ts` and `test/recaptcha-manager.test.ts`.
35
-
36
- ## Local Demo with `web-dev-server`
37
- ```bash
38
- npm run start
39
- ```
40
- To run a local development server that serves the basic demo located in `demo/index.html`
41
-
42
- ## Testing with Web Test Runner
43
- To run the suite of Web Test Runner tests, run
44
- ```bash
45
- npm run test
46
- ```
47
-
48
- To run the tests in watch mode (for <abbr title="test driven development">TDD</abbr>, for example), run
49
-
50
- ```bash
51
- npm run test:watch
52
- ```
53
-
54
- ## Linting with ESLint, Prettier, and Types
55
- To scan the project for linting errors, run
56
- ```bash
57
- npm run lint
58
- ```
59
-
60
- To automatically fix many linting errors, run
61
- ```bash
62
- npm run format
63
- ```
1
+ ![Build Status](https://github.com/internetarchive/iaux-recaptcha-manager/actions/workflows/ci.yml/badge.svg)
2
+
3
+ # Internet Archive reCaptcha Manager
4
+
5
+ A library to lazy load and interact with reCaptcha
6
+
7
+ ## Installation
8
+
9
+ ```shell
10
+ > npm install @internetarchive/recaptcha-manager
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ const recaptchaManager = new RecaptchaManager({
17
+ defaultSiteKey: 'your-site-key',
18
+ });
19
+
20
+ // will load recaptcha library if it's not loaded
21
+ const recaptchaWidget = await recaptchaManager.getRecaptchaWidget({
22
+ recaptchaParams: {
23
+ tabindex: 0,
24
+ theme: 'light',
25
+ type: 'image',
26
+ },
27
+ });
28
+
29
+ const token = await recaptchaWidget.execute();
30
+
31
+ // submit token with your post and validate on the backend
32
+ ```
33
+
34
+ For more usage examples, see `demo/app-root.ts` and `test/recaptcha-manager.test.ts`.
35
+
36
+ ## Local Demo with `web-dev-server`
37
+ ```bash
38
+ npm run start
39
+ ```
40
+ To run a local development server that serves the basic demo located in `demo/index.html`
41
+
42
+ ## Testing with Web Test Runner
43
+ To run the suite of Web Test Runner tests, run
44
+ ```bash
45
+ npm run test
46
+ ```
47
+
48
+ To run the tests in watch mode (for <abbr title="test driven development">TDD</abbr>, for example), run
49
+
50
+ ```bash
51
+ npm run test:watch
52
+ ```
53
+
54
+ ## Linting with ESLint, Prettier, and Types
55
+ To scan the project for linting errors, run
56
+ ```bash
57
+ npm run lint
58
+ ```
59
+
60
+ To automatically fix many linting errors, run
61
+ ```bash
62
+ npm run format
63
+ ```
@@ -1,3 +1,3 @@
1
- *
2
- !.placeholder
1
+ *
2
+ !.placeholder
3
3
  !.gitignore
package/demo/app-root.ts CHANGED
@@ -1,93 +1,111 @@
1
- import { html, css, LitElement } from 'lit';
2
- import { customElement, state } from 'lit/decorators.js';
3
- import { RecaptchaWidgetInterface } from '../src/recaptcha-widget';
4
- import {
5
- RecaptchaManager,
6
- RecaptchaManagerInterface,
7
- } from '../src/recaptcha-manager';
8
-
9
- @customElement('app-root')
10
- export class AppRoot extends LitElement {
11
- @state() result?: string;
12
-
13
- @state() result2?: string;
14
-
15
- private recaptchaManager: RecaptchaManagerInterface = new RecaptchaManager({
16
- defaultSiteKey: '6Ld64a8UAAAAAGbDwi1927ztGNw7YABQ-dqzvTN2',
17
- });
18
-
19
- private recaptcha1?: RecaptchaWidgetInterface;
20
-
21
- private recaptcha2?: RecaptchaWidgetInterface;
22
-
23
- render() {
24
- return html`
25
- <p>
26
- <button @click="${this.loadRecaptcha}">Load Recaptcha</button
27
- ><button @click="${this.executeRecaptcha}">Execute Recaptcha</button>
28
- </p>
29
- ${this.result
30
- ? html`<p><strong>Token:</strong></p>
31
- <p>${this.result}</p>`
32
- : ''}
33
- <p>
34
- <button @click="${this.loadRecaptcha2}">Load Another Recaptcha</button
35
- ><button @click="${this.executeRecaptcha2}">
36
- Execute Another Recaptcha
37
- </button>
38
- </p>
39
- ${this.result2
40
- ? html`<p><strong>Token 2:</strong></p>
41
- <p>${this.result2}</p>`
42
- : ''}
43
- `;
44
- }
45
-
46
- private async loadRecaptcha() {
47
- this.recaptcha1 = await this.recaptchaManager?.getRecaptchaWidget({
48
- recaptchaParams: {
49
- tabindex: 0,
50
- theme: 'light',
51
- type: 'image',
52
- },
53
- });
54
- }
55
-
56
- private async executeRecaptcha() {
57
- if (!this.recaptcha1) {
58
- await this.loadRecaptcha();
59
- }
60
-
61
- if (!this.recaptcha1) {
62
- console.error('error loading recaptcha');
63
- return;
64
- }
65
-
66
- this.result = await this.recaptcha1.execute();
67
- }
68
-
69
- private async loadRecaptcha2() {
70
- this.recaptcha2 = await this.recaptchaManager?.getRecaptchaWidget({
71
- siteKey: '<your-site-key>',
72
- });
73
- }
74
-
75
- private async executeRecaptcha2() {
76
- if (!this.recaptcha2) {
77
- await this.loadRecaptcha();
78
- }
79
-
80
- if (!this.recaptcha2) {
81
- console.error('error loading recaptcha');
82
- return;
83
- }
84
-
85
- this.result2 = await this.recaptcha2.execute();
86
- }
87
-
88
- static styles = css`
89
- :host {
90
- display: block;
91
- }
92
- `;
93
- }
1
+ import { html, css, LitElement } from 'lit';
2
+ import { customElement, state, query } from 'lit/decorators.js';
3
+ import { RecaptchaWidgetInterface } from '../src/recaptcha-widget';
4
+ import {
5
+ RecaptchaManager,
6
+ RecaptchaManagerInterface,
7
+ } from '../src/recaptcha-manager';
8
+
9
+ @customElement('app-root')
10
+ export class AppRoot extends LitElement {
11
+ @state() result?: string;
12
+
13
+ @state() result2?: string;
14
+
15
+ @query('#timeout') timeoutInput!: HTMLInputElement;
16
+
17
+ private recaptchaManager: RecaptchaManagerInterface = new RecaptchaManager({
18
+ defaultSiteKey: '6Ld64a8UAAAAAGbDwi1927ztGNw7YABQ-dqzvTN2',
19
+ });
20
+
21
+ private recaptcha1?: RecaptchaWidgetInterface;
22
+
23
+ private recaptcha2?: RecaptchaWidgetInterface;
24
+
25
+ render() {
26
+ return html`
27
+ <label for="timeout">
28
+ Timeout (ms):
29
+ <input
30
+ type="number"
31
+ id="timeout"
32
+ value="10000"
33
+ min="0"
34
+ max="99999"
35
+ step="100"
36
+ @change=${this.updateTimeout}
37
+ />
38
+ </label>
39
+ <p>
40
+ <button @click="${this.loadRecaptcha}">Load Recaptcha</button
41
+ ><button @click="${this.executeRecaptcha}">Execute Recaptcha</button>
42
+ </p>
43
+ ${this.result
44
+ ? html`<p><strong>Token:</strong></p>
45
+ <p>${this.result}</p>`
46
+ : ''}
47
+ <p>
48
+ <button @click="${this.loadRecaptcha2}">Load Another Recaptcha</button
49
+ ><button @click="${this.executeRecaptcha2}">
50
+ Execute Another Recaptcha
51
+ </button>
52
+ </p>
53
+ ${this.result2
54
+ ? html`<p><strong>Token 2:</strong></p>
55
+ <p>${this.result2}</p>`
56
+ : ''}
57
+ `;
58
+ }
59
+
60
+ private updateTimeout() {
61
+ this.recaptchaManager.setTimeoutDelay(+this.timeoutInput.value);
62
+ }
63
+
64
+ private async loadRecaptcha() {
65
+ this.recaptcha1 = await this.recaptchaManager?.getRecaptchaWidget({
66
+ recaptchaParams: {
67
+ tabindex: 0,
68
+ theme: 'light',
69
+ type: 'image',
70
+ },
71
+ });
72
+ }
73
+
74
+ private async executeRecaptcha() {
75
+ if (!this.recaptcha1) {
76
+ await this.loadRecaptcha();
77
+ }
78
+
79
+ if (!this.recaptcha1) {
80
+ console.error('error loading recaptcha');
81
+ return;
82
+ }
83
+
84
+ this.result = await this.recaptcha1.execute();
85
+ }
86
+
87
+ private async loadRecaptcha2() {
88
+ this.recaptcha2 = await this.recaptchaManager?.getRecaptchaWidget({
89
+ siteKey: '<your-site-key>',
90
+ });
91
+ }
92
+
93
+ private async executeRecaptcha2() {
94
+ if (!this.recaptcha2) {
95
+ await this.loadRecaptcha();
96
+ }
97
+
98
+ if (!this.recaptcha2) {
99
+ console.error('error loading recaptcha');
100
+ return;
101
+ }
102
+
103
+ this.result2 = await this.recaptcha2.execute();
104
+ }
105
+
106
+ static styles = css`
107
+ :host {
108
+ display: block;
109
+ }
110
+ `;
111
+ }
package/demo/index.html CHANGED
@@ -1,21 +1,21 @@
1
- <!doctype html>
2
- <html lang="en-GB">
3
- <head>
4
- <meta charset="utf-8">
5
- <style>
6
- html {
7
- font-size: 10px; /* This is to match petabox's base font size */
8
- }
9
-
10
- body {
11
- background: #fafafa;
12
- }
13
- </style>
14
- </head>
15
- <body>
16
- <app-root></app-root>
17
-
18
- <script type="module" src="../dist/demo/app-root.js">
19
- </script>
20
- </body>
21
- </html>
1
+ <!doctype html>
2
+ <html lang="en-GB">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <style>
6
+ html {
7
+ font-size: 10px; /* This is to match petabox's base font size */
8
+ }
9
+
10
+ body {
11
+ background: #fafafa;
12
+ }
13
+ </style>
14
+ </head>
15
+ <body>
16
+ <app-root></app-root>
17
+
18
+ <script type="module" src="../dist/demo/app-root.js">
19
+ </script>
20
+ </body>
21
+ </html>
@@ -2,10 +2,12 @@ import { LitElement } from 'lit';
2
2
  export declare class AppRoot extends LitElement {
3
3
  result?: string;
4
4
  result2?: string;
5
+ timeoutInput: HTMLInputElement;
5
6
  private recaptchaManager;
6
7
  private recaptcha1?;
7
8
  private recaptcha2?;
8
9
  render(): import("lit").TemplateResult<1>;
10
+ private updateTimeout;
9
11
  private loadRecaptcha;
10
12
  private executeRecaptcha;
11
13
  private loadRecaptcha2;
@@ -1,6 +1,6 @@
1
1
  import { __decorate } from "tslib";
2
2
  import { html, css, LitElement } from 'lit';
3
- import { customElement, state } from 'lit/decorators.js';
3
+ import { customElement, state, query } from 'lit/decorators.js';
4
4
  import { RecaptchaManager, } from '../src/recaptcha-manager';
5
5
  let AppRoot = class AppRoot extends LitElement {
6
6
  constructor() {
@@ -10,27 +10,42 @@ let AppRoot = class AppRoot extends LitElement {
10
10
  });
11
11
  }
12
12
  render() {
13
- return html `
14
- <p>
15
- <button @click="${this.loadRecaptcha}">Load Recaptcha</button
16
- ><button @click="${this.executeRecaptcha}">Execute Recaptcha</button>
17
- </p>
13
+ return html `
14
+ <label for="timeout">
15
+ Timeout (ms):
16
+ <input
17
+ type="number"
18
+ id="timeout"
19
+ value="10000"
20
+ min="0"
21
+ max="99999"
22
+ step="100"
23
+ @change=${this.updateTimeout}
24
+ />
25
+ </label>
26
+ <p>
27
+ <button @click="${this.loadRecaptcha}">Load Recaptcha</button
28
+ ><button @click="${this.executeRecaptcha}">Execute Recaptcha</button>
29
+ </p>
18
30
  ${this.result
19
- ? html `<p><strong>Token:</strong></p>
31
+ ? html `<p><strong>Token:</strong></p>
20
32
  <p>${this.result}</p>`
21
- : ''}
22
- <p>
23
- <button @click="${this.loadRecaptcha2}">Load Another Recaptcha</button
24
- ><button @click="${this.executeRecaptcha2}">
25
- Execute Another Recaptcha
26
- </button>
27
- </p>
33
+ : ''}
34
+ <p>
35
+ <button @click="${this.loadRecaptcha2}">Load Another Recaptcha</button
36
+ ><button @click="${this.executeRecaptcha2}">
37
+ Execute Another Recaptcha
38
+ </button>
39
+ </p>
28
40
  ${this.result2
29
- ? html `<p><strong>Token 2:</strong></p>
41
+ ? html `<p><strong>Token 2:</strong></p>
30
42
  <p>${this.result2}</p>`
31
- : ''}
43
+ : ''}
32
44
  `;
33
45
  }
46
+ updateTimeout() {
47
+ this.recaptchaManager.setTimeoutDelay(+this.timeoutInput.value);
48
+ }
34
49
  async loadRecaptcha() {
35
50
  var _a;
36
51
  this.recaptcha1 = await ((_a = this.recaptchaManager) === null || _a === void 0 ? void 0 : _a.getRecaptchaWidget({
@@ -68,10 +83,10 @@ let AppRoot = class AppRoot extends LitElement {
68
83
  this.result2 = await this.recaptcha2.execute();
69
84
  }
70
85
  };
71
- AppRoot.styles = css `
72
- :host {
73
- display: block;
74
- }
86
+ AppRoot.styles = css `
87
+ :host {
88
+ display: block;
89
+ }
75
90
  `;
76
91
  __decorate([
77
92
  state()
@@ -79,6 +94,9 @@ __decorate([
79
94
  __decorate([
80
95
  state()
81
96
  ], AppRoot.prototype, "result2", void 0);
97
+ __decorate([
98
+ query('#timeout')
99
+ ], AppRoot.prototype, "timeoutInput", void 0);
82
100
  AppRoot = __decorate([
83
101
  customElement('app-root')
84
102
  ], AppRoot);
@@ -1 +1 @@
1
- {"version":3,"file":"app-root.js","sourceRoot":"","sources":["../../demo/app-root.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EACL,gBAAgB,GAEjB,MAAM,0BAA0B,CAAC;AAG3B,IAAM,OAAO,GAAb,MAAM,OAAQ,SAAQ,UAAU;IAAhC;;QAKG,qBAAgB,GAA8B,IAAI,gBAAgB,CAAC;YACzE,cAAc,EAAE,0CAA0C;SAC3D,CAAC,CAAC;IA4EL,CAAC;IAtEC,MAAM;QACJ,OAAO,IAAI,CAAA;;0BAEW,IAAI,CAAC,aAAa;2BACjB,IAAI,CAAC,gBAAgB;;QAExC,IAAI,CAAC,MAAM;YACX,CAAC,CAAC,IAAI,CAAA;iBACG,IAAI,CAAC,MAAM,MAAM;YAC1B,CAAC,CAAC,EAAE;;0BAEc,IAAI,CAAC,cAAc;2BAClB,IAAI,CAAC,iBAAiB;;;;QAIzC,IAAI,CAAC,OAAO;YACZ,CAAC,CAAC,IAAI,CAAA;iBACG,IAAI,CAAC,OAAO,MAAM;YAC3B,CAAC,CAAC,EAAE;KACP,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,aAAa;;QACzB,IAAI,CAAC,UAAU,GAAG,MAAM,CAAA,MAAA,IAAI,CAAC,gBAAgB,0CAAE,kBAAkB,CAAC;YAChE,eAAe,EAAE;gBACf,QAAQ,EAAE,CAAC;gBACX,KAAK,EAAE,OAAO;gBACd,IAAI,EAAE,OAAO;aACd;SACF,CAAC,CAAA,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,gBAAgB;QAC5B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;IAChD,CAAC;IAEO,KAAK,CAAC,cAAc;;QAC1B,IAAI,CAAC,UAAU,GAAG,MAAM,CAAA,MAAA,IAAI,CAAC,gBAAgB,0CAAE,kBAAkB,CAAC;YAChE,OAAO,EAAE,iBAAiB;SAC3B,CAAC,CAAA,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,iBAAiB;QAC7B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;IACjD,CAAC;;AAEM,cAAM,GAAG,GAAG,CAAA;;;;GAIlB,AAJY,CAIX;AAjFO;IAAR,KAAK,EAAE;uCAAiB;AAEhB;IAAR,KAAK,EAAE;wCAAkB;AAHf,OAAO;IADnB,aAAa,CAAC,UAAU,CAAC;GACb,OAAO,CAmFnB","sourcesContent":["import { html, css, LitElement } from 'lit';\nimport { customElement, state } from 'lit/decorators.js';\nimport { RecaptchaWidgetInterface } from '../src/recaptcha-widget';\nimport {\n RecaptchaManager,\n RecaptchaManagerInterface,\n} from '../src/recaptcha-manager';\n\n@customElement('app-root')\nexport class AppRoot extends LitElement {\n @state() result?: string;\n\n @state() result2?: string;\n\n private recaptchaManager: RecaptchaManagerInterface = new RecaptchaManager({\n defaultSiteKey: '6Ld64a8UAAAAAGbDwi1927ztGNw7YABQ-dqzvTN2',\n });\n\n private recaptcha1?: RecaptchaWidgetInterface;\n\n private recaptcha2?: RecaptchaWidgetInterface;\n\n render() {\n return html`\n <p>\n <button @click=\"${this.loadRecaptcha}\">Load Recaptcha</button\n ><button @click=\"${this.executeRecaptcha}\">Execute Recaptcha</button>\n </p>\n ${this.result\n ? html`<p><strong>Token:</strong></p>\n <p>${this.result}</p>`\n : ''}\n <p>\n <button @click=\"${this.loadRecaptcha2}\">Load Another Recaptcha</button\n ><button @click=\"${this.executeRecaptcha2}\">\n Execute Another Recaptcha\n </button>\n </p>\n ${this.result2\n ? html`<p><strong>Token 2:</strong></p>\n <p>${this.result2}</p>`\n : ''}\n `;\n }\n\n private async loadRecaptcha() {\n this.recaptcha1 = await this.recaptchaManager?.getRecaptchaWidget({\n recaptchaParams: {\n tabindex: 0,\n theme: 'light',\n type: 'image',\n },\n });\n }\n\n private async executeRecaptcha() {\n if (!this.recaptcha1) {\n await this.loadRecaptcha();\n }\n\n if (!this.recaptcha1) {\n console.error('error loading recaptcha');\n return;\n }\n\n this.result = await this.recaptcha1.execute();\n }\n\n private async loadRecaptcha2() {\n this.recaptcha2 = await this.recaptchaManager?.getRecaptchaWidget({\n siteKey: '<your-site-key>',\n });\n }\n\n private async executeRecaptcha2() {\n if (!this.recaptcha2) {\n await this.loadRecaptcha();\n }\n\n if (!this.recaptcha2) {\n console.error('error loading recaptcha');\n return;\n }\n\n this.result2 = await this.recaptcha2.execute();\n }\n\n static styles = css`\n :host {\n display: block;\n }\n `;\n}\n"]}
1
+ {"version":3,"file":"app-root.js","sourceRoot":"","sources":["../../demo/app-root.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,KAAK,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAEhE,OAAO,EACL,gBAAgB,GAEjB,MAAM,0BAA0B,CAAC;AAG3B,IAAM,OAAO,GAAb,MAAM,OAAQ,SAAQ,UAAU;IAAhC;;QAOG,qBAAgB,GAA8B,IAAI,gBAAgB,CAAC;YACzE,cAAc,EAAE,0CAA0C;SAC3D,CAAC,CAAC;IA4FL,CAAC;IAtFC,MAAM;QACJ,OAAO,IAAI,CAAA;;;;;;;;;;oBAUK,IAAI,CAAC,aAAa;;;;0BAIZ,IAAI,CAAC,aAAa;2BACjB,IAAI,CAAC,gBAAgB;;QAExC,IAAI,CAAC,MAAM;YACX,CAAC,CAAC,IAAI,CAAA;iBACG,IAAI,CAAC,MAAM,MAAM;YAC1B,CAAC,CAAC,EAAE;;0BAEc,IAAI,CAAC,cAAc;2BAClB,IAAI,CAAC,iBAAiB;;;;QAIzC,IAAI,CAAC,OAAO;YACZ,CAAC,CAAC,IAAI,CAAA;iBACG,IAAI,CAAC,OAAO,MAAM;YAC3B,CAAC,CAAC,EAAE;KACP,CAAC;IACJ,CAAC;IAEO,aAAa;QACnB,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAClE,CAAC;IAEO,KAAK,CAAC,aAAa;;QACzB,IAAI,CAAC,UAAU,GAAG,MAAM,CAAA,MAAA,IAAI,CAAC,gBAAgB,0CAAE,kBAAkB,CAAC;YAChE,eAAe,EAAE;gBACf,QAAQ,EAAE,CAAC;gBACX,KAAK,EAAE,OAAO;gBACd,IAAI,EAAE,OAAO;aACd;SACF,CAAC,CAAA,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,gBAAgB;QAC5B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;IAChD,CAAC;IAEO,KAAK,CAAC,cAAc;;QAC1B,IAAI,CAAC,UAAU,GAAG,MAAM,CAAA,MAAA,IAAI,CAAC,gBAAgB,0CAAE,kBAAkB,CAAC;YAChE,OAAO,EAAE,iBAAiB;SAC3B,CAAC,CAAA,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,iBAAiB;QAC7B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;IACjD,CAAC;;AAEM,cAAM,GAAG,GAAG,CAAA;;;;GAIlB,AAJY,CAIX;AAnGO;IAAR,KAAK,EAAE;uCAAiB;AAEhB;IAAR,KAAK,EAAE;wCAAkB;AAEP;IAAlB,KAAK,CAAC,UAAU,CAAC;6CAAiC;AALxC,OAAO;IADnB,aAAa,CAAC,UAAU,CAAC;GACb,OAAO,CAqGnB","sourcesContent":["import { html, css, LitElement } from 'lit';\r\nimport { customElement, state, query } from 'lit/decorators.js';\r\nimport { RecaptchaWidgetInterface } from '../src/recaptcha-widget';\r\nimport {\r\n RecaptchaManager,\r\n RecaptchaManagerInterface,\r\n} from '../src/recaptcha-manager';\r\n\r\n@customElement('app-root')\r\nexport class AppRoot extends LitElement {\r\n @state() result?: string;\r\n\r\n @state() result2?: string;\r\n\r\n @query('#timeout') timeoutInput!: HTMLInputElement;\r\n\r\n private recaptchaManager: RecaptchaManagerInterface = new RecaptchaManager({\r\n defaultSiteKey: '6Ld64a8UAAAAAGbDwi1927ztGNw7YABQ-dqzvTN2',\r\n });\r\n\r\n private recaptcha1?: RecaptchaWidgetInterface;\r\n\r\n private recaptcha2?: RecaptchaWidgetInterface;\r\n\r\n render() {\r\n return html`\r\n <label for=\"timeout\">\r\n Timeout (ms):\r\n <input\r\n type=\"number\"\r\n id=\"timeout\"\r\n value=\"10000\"\r\n min=\"0\"\r\n max=\"99999\"\r\n step=\"100\"\r\n @change=${this.updateTimeout}\r\n />\r\n </label>\r\n <p>\r\n <button @click=\"${this.loadRecaptcha}\">Load Recaptcha</button\r\n ><button @click=\"${this.executeRecaptcha}\">Execute Recaptcha</button>\r\n </p>\r\n ${this.result\r\n ? html`<p><strong>Token:</strong></p>\r\n <p>${this.result}</p>`\r\n : ''}\r\n <p>\r\n <button @click=\"${this.loadRecaptcha2}\">Load Another Recaptcha</button\r\n ><button @click=\"${this.executeRecaptcha2}\">\r\n Execute Another Recaptcha\r\n </button>\r\n </p>\r\n ${this.result2\r\n ? html`<p><strong>Token 2:</strong></p>\r\n <p>${this.result2}</p>`\r\n : ''}\r\n `;\r\n }\r\n\r\n private updateTimeout() {\r\n this.recaptchaManager.setTimeoutDelay(+this.timeoutInput.value);\r\n }\r\n\r\n private async loadRecaptcha() {\r\n this.recaptcha1 = await this.recaptchaManager?.getRecaptchaWidget({\r\n recaptchaParams: {\r\n tabindex: 0,\r\n theme: 'light',\r\n type: 'image',\r\n },\r\n });\r\n }\r\n\r\n private async executeRecaptcha() {\r\n if (!this.recaptcha1) {\r\n await this.loadRecaptcha();\r\n }\r\n\r\n if (!this.recaptcha1) {\r\n console.error('error loading recaptcha');\r\n return;\r\n }\r\n\r\n this.result = await this.recaptcha1.execute();\r\n }\r\n\r\n private async loadRecaptcha2() {\r\n this.recaptcha2 = await this.recaptchaManager?.getRecaptchaWidget({\r\n siteKey: '<your-site-key>',\r\n });\r\n }\r\n\r\n private async executeRecaptcha2() {\r\n if (!this.recaptcha2) {\r\n await this.loadRecaptcha();\r\n }\r\n\r\n if (!this.recaptcha2) {\r\n console.error('error loading recaptcha');\r\n return;\r\n }\r\n\r\n this.result2 = await this.recaptcha2.execute();\r\n }\r\n\r\n static styles = css`\r\n :host {\r\n display: block;\r\n }\r\n `;\r\n}\r\n"]}
@@ -1,6 +1,10 @@
1
1
  import { LazyLoaderServiceInterface } from '@internetarchive/lazy-loader-service';
2
2
  import { RecaptchaWidgetInterface } from './recaptcha-widget';
3
3
  export interface RecaptchaManagerInterface {
4
+ /**
5
+ * Changes the manager's timeout delay to the given number of milliseconds.
6
+ */
7
+ setTimeoutDelay(delay: number): void;
4
8
  /**
5
9
  * Load a recaptcha widget for a given site key or the default site key.
6
10
  */
@@ -10,21 +14,29 @@ export interface RecaptchaManagerInterface {
10
14
  }): Promise<RecaptchaWidgetInterface>;
11
15
  }
12
16
  export declare class RecaptchaManager implements RecaptchaManagerInterface {
17
+ private static readonly DEFAULT_TIMEOUT;
13
18
  private lazyLoader;
14
19
  private defaultSiteKey?;
15
20
  private recaptchaCache;
21
+ /**
22
+ * How long in milliseconds to wait for the recaptcha library to load before timing out.
23
+ */
24
+ private timeout;
16
25
  constructor(options?: {
17
26
  defaultSiteKey?: string;
18
27
  lazyLoader?: LazyLoaderServiceInterface;
19
28
  grecaptchaLibrary?: ReCaptchaV2.ReCaptcha;
29
+ timeout?: number;
20
30
  });
21
31
  /** @inheritdoc */
32
+ setTimeoutDelay(delay: number): void;
33
+ /** @inheritdoc */
22
34
  getRecaptchaWidget(options?: {
23
35
  siteKey?: string;
24
36
  recaptchaParams?: ReCaptchaV2.Parameters;
25
37
  }): Promise<RecaptchaWidgetInterface>;
26
38
  /**
27
- * Load the Recaptch library from Google.
39
+ * Load the Recaptcha library from Google.
28
40
  *
29
41
  * @returns Promise<ReCaptchaV2.ReCaptcha>
30
42
  */
@@ -2,11 +2,20 @@ import { LazyLoaderService, } from '@internetarchive/lazy-loader-service';
2
2
  import { RecaptchaWidget } from './recaptcha-widget';
3
3
  export class RecaptchaManager {
4
4
  constructor(options) {
5
- var _a;
5
+ var _a, _b;
6
6
  this.recaptchaCache = {};
7
+ /**
8
+ * How long in milliseconds to wait for the recaptcha library to load before timing out.
9
+ */
10
+ this.timeout = RecaptchaManager.DEFAULT_TIMEOUT;
7
11
  this.defaultSiteKey = options === null || options === void 0 ? void 0 : options.defaultSiteKey;
8
12
  this.lazyLoader = (_a = options === null || options === void 0 ? void 0 : options.lazyLoader) !== null && _a !== void 0 ? _a : new LazyLoaderService();
9
13
  this.grecaptchaLibraryCache = options === null || options === void 0 ? void 0 : options.grecaptchaLibrary;
14
+ this.timeout = (_b = options === null || options === void 0 ? void 0 : options.timeout) !== null && _b !== void 0 ? _b : RecaptchaManager.DEFAULT_TIMEOUT;
15
+ }
16
+ /** @inheritdoc */
17
+ setTimeoutDelay(delay) {
18
+ this.timeout = delay;
10
19
  }
11
20
  /** @inheritdoc */
12
21
  async getRecaptchaWidget(options) {
@@ -27,7 +36,7 @@ export class RecaptchaManager {
27
36
  return recaptcha;
28
37
  }
29
38
  /**
30
- * Load the Recaptch library from Google.
39
+ * Load the Recaptcha library from Google.
31
40
  *
32
41
  * @returns Promise<ReCaptchaV2.ReCaptcha>
33
42
  */
@@ -35,7 +44,7 @@ export class RecaptchaManager {
35
44
  if (this.grecaptchaLibraryCache) {
36
45
  return this.grecaptchaLibraryCache;
37
46
  }
38
- return new Promise(resolve => {
47
+ return new Promise((resolve, reject) => {
39
48
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
40
49
  window.grecaptchaLoadedCallback = () => {
41
50
  setTimeout(() => {
@@ -46,10 +55,12 @@ export class RecaptchaManager {
46
55
  this.grecaptchaLibraryCache = window.grecaptcha;
47
56
  resolve(window.grecaptcha);
48
57
  };
58
+ setTimeout(() => reject(new Error('grecaptcha failed to execute callback')), this.timeout);
49
59
  this.lazyLoader.loadScript({
50
60
  src: 'https://www.google.com/recaptcha/api.js?onload=grecaptchaLoadedCallback&render=explicit',
51
61
  });
52
62
  });
53
63
  }
54
64
  }
65
+ RecaptchaManager.DEFAULT_TIMEOUT = 10000;
55
66
  //# sourceMappingURL=recaptcha-manager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"recaptcha-manager.js","sourceRoot":"","sources":["../../src/recaptcha-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,GAElB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,eAAe,EAA4B,MAAM,oBAAoB,CAAC;AAY/E,MAAM,OAAO,gBAAgB;IAO3B,YAAY,OAIX;;QANO,mBAAc,GAAoC,EAAE,CAAC;QAO3D,IAAI,CAAC,cAAc,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,cAAc,CAAC;QAC9C,IAAI,CAAC,UAAU,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,UAAU,mCAAI,IAAI,iBAAiB,EAAE,CAAC;QACjE,IAAI,CAAC,sBAAsB,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,iBAAiB,CAAC;IAC3D,CAAC;IAED,kBAAkB;IAClB,KAAK,CAAC,kBAAkB,CAAC,OAGxB;;QACC,MAAM,GAAG,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,mCAAI,IAAI,CAAC,cAAc,CAAC;QACpD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAE1B,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3D,MAAM,SAAS,GAAG,IAAI,eAAe,CACnC;YACE,OAAO,EAAE,GAAG;YACZ,iBAAiB;SAClB,EACD,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,eAAe,CACzB,CAAC;QAEF,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;QACrC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,mBAAmB;QAC/B,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC,sBAAsB,CAAC;QACrC,CAAC;QACD,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;YAC3B,8DAA8D;YAC7D,MAAc,CAAC,wBAAwB,GAAG,GAAS,EAAE;gBACpD,UAAU,CAAC,GAAG,EAAE;oBACd,8CAA8C;oBAC9C,8DAA8D;oBAC9D,OAAQ,MAAc,CAAC,wBAAwB,CAAC;gBAClD,CAAC,EAAE,EAAE,CAAC,CAAC;gBACP,IAAI,CAAC,sBAAsB,GAAG,MAAM,CAAC,UAAU,CAAC;gBAChD,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC7B,CAAC,CAAC;YAEF,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;gBACzB,GAAG,EAAE,yFAAyF;aAC/F,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CAIF","sourcesContent":["import {\n LazyLoaderService,\n LazyLoaderServiceInterface,\n} from '@internetarchive/lazy-loader-service';\nimport { RecaptchaWidget, RecaptchaWidgetInterface } from './recaptcha-widget';\n\nexport interface RecaptchaManagerInterface {\n /**\n * Load a recaptcha widget for a given site key or the default site key.\n */\n getRecaptchaWidget(options?: {\n siteKey?: string;\n recaptchaParams?: ReCaptchaV2.Parameters;\n }): Promise<RecaptchaWidgetInterface>;\n}\n\nexport class RecaptchaManager implements RecaptchaManagerInterface {\n private lazyLoader: LazyLoaderServiceInterface;\n\n private defaultSiteKey?: string;\n\n private recaptchaCache: Record<string, RecaptchaWidget> = {};\n\n constructor(options?: {\n defaultSiteKey?: string;\n lazyLoader?: LazyLoaderServiceInterface;\n grecaptchaLibrary?: ReCaptchaV2.ReCaptcha; // allows dependency injection or will be lazy loaded\n }) {\n this.defaultSiteKey = options?.defaultSiteKey;\n this.lazyLoader = options?.lazyLoader ?? new LazyLoaderService();\n this.grecaptchaLibraryCache = options?.grecaptchaLibrary;\n }\n\n /** @inheritdoc */\n async getRecaptchaWidget(options?: {\n siteKey?: string;\n recaptchaParams?: ReCaptchaV2.Parameters;\n }): Promise<RecaptchaWidgetInterface> {\n const key = options?.siteKey ?? this.defaultSiteKey;\n if (!key) {\n throw new Error('The reCaptcha widget requires a site key');\n }\n\n const cached = this.recaptchaCache[key];\n if (cached) return cached;\n\n const grecaptchaLibrary = await this.getRecaptchaLibrary();\n const recaptcha = new RecaptchaWidget(\n {\n siteKey: key,\n grecaptchaLibrary,\n },\n options?.recaptchaParams,\n );\n\n this.recaptchaCache[key] = recaptcha;\n return recaptcha;\n }\n\n /**\n * Load the Recaptch library from Google.\n *\n * @returns Promise<ReCaptchaV2.ReCaptcha>\n */\n private async getRecaptchaLibrary(): Promise<ReCaptchaV2.ReCaptcha> {\n if (this.grecaptchaLibraryCache) {\n return this.grecaptchaLibraryCache;\n }\n return new Promise(resolve => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (window as any).grecaptchaLoadedCallback = (): void => {\n setTimeout(() => {\n // remove the callback when we're done with it\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n delete (window as any).grecaptchaLoadedCallback;\n }, 10);\n this.grecaptchaLibraryCache = window.grecaptcha;\n resolve(window.grecaptcha);\n };\n\n this.lazyLoader.loadScript({\n src: 'https://www.google.com/recaptcha/api.js?onload=grecaptchaLoadedCallback&render=explicit',\n });\n });\n }\n\n /** don't use directly, use `getRecaptchaLibrary()` */\n private grecaptchaLibraryCache?: ReCaptchaV2.ReCaptcha;\n}\n"]}
1
+ {"version":3,"file":"recaptcha-manager.js","sourceRoot":"","sources":["../../src/recaptcha-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,GAElB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,eAAe,EAA4B,MAAM,oBAAoB,CAAC;AAiB/E,MAAM,OAAO,gBAAgB;IAc3B,YAAY,OAKX;;QAZO,mBAAc,GAAoC,EAAE,CAAC;QAE7D;;WAEG;QACK,YAAO,GAAG,gBAAgB,CAAC,eAAe,CAAC;QAQjD,IAAI,CAAC,cAAc,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,cAAc,CAAC;QAC9C,IAAI,CAAC,UAAU,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,UAAU,mCAAI,IAAI,iBAAiB,EAAE,CAAC;QACjE,IAAI,CAAC,sBAAsB,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,iBAAiB,CAAC;QACzD,IAAI,CAAC,OAAO,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,mCAAI,gBAAgB,CAAC,eAAe,CAAC;IACtE,CAAC;IAED,kBAAkB;IAClB,eAAe,CAAC,KAAa;QAC3B,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,kBAAkB;IAClB,KAAK,CAAC,kBAAkB,CAAC,OAGxB;;QACC,MAAM,GAAG,GAAG,MAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,OAAO,mCAAI,IAAI,CAAC,cAAc,CAAC;QACpD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAE1B,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3D,MAAM,SAAS,GAAG,IAAI,eAAe,CACnC;YACE,OAAO,EAAE,GAAG;YACZ,iBAAiB;SAClB,EACD,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,eAAe,CACzB,CAAC;QAEF,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;QACrC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,mBAAmB;QAC/B,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC,sBAAsB,CAAC;QACrC,CAAC;QACD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,8DAA8D;YAC7D,MAAc,CAAC,wBAAwB,GAAG,GAAS,EAAE;gBACpD,UAAU,CAAC,GAAG,EAAE;oBACd,8CAA8C;oBAC9C,8DAA8D;oBAC9D,OAAQ,MAAc,CAAC,wBAAwB,CAAC;gBAClD,CAAC,EAAE,EAAE,CAAC,CAAC;gBACP,IAAI,CAAC,sBAAsB,GAAG,MAAM,CAAC,UAAU,CAAC;gBAChD,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC7B,CAAC,CAAC;YAEF,UAAU,CACR,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC,EAChE,IAAI,CAAC,OAAO,CACb,CAAC;YAEF,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;gBACzB,GAAG,EAAE,yFAAyF;aAC/F,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;;AAtFuB,gCAAe,GAAG,KAAK,AAAR,CAAS","sourcesContent":["import {\r\n LazyLoaderService,\r\n LazyLoaderServiceInterface,\r\n} from '@internetarchive/lazy-loader-service';\r\nimport { RecaptchaWidget, RecaptchaWidgetInterface } from './recaptcha-widget';\r\n\r\nexport interface RecaptchaManagerInterface {\r\n /**\r\n * Changes the manager's timeout delay to the given number of milliseconds.\r\n */\r\n setTimeoutDelay(delay: number): void;\r\n\r\n /**\r\n * Load a recaptcha widget for a given site key or the default site key.\r\n */\r\n getRecaptchaWidget(options?: {\r\n siteKey?: string;\r\n recaptchaParams?: ReCaptchaV2.Parameters;\r\n }): Promise<RecaptchaWidgetInterface>;\r\n}\r\n\r\nexport class RecaptchaManager implements RecaptchaManagerInterface {\r\n private static readonly DEFAULT_TIMEOUT = 10000;\r\n\r\n private lazyLoader: LazyLoaderServiceInterface;\r\n\r\n private defaultSiteKey?: string;\r\n\r\n private recaptchaCache: Record<string, RecaptchaWidget> = {};\r\n\r\n /**\r\n * How long in milliseconds to wait for the recaptcha library to load before timing out.\r\n */\r\n private timeout = RecaptchaManager.DEFAULT_TIMEOUT;\r\n\r\n constructor(options?: {\r\n defaultSiteKey?: string;\r\n lazyLoader?: LazyLoaderServiceInterface;\r\n grecaptchaLibrary?: ReCaptchaV2.ReCaptcha; // allows dependency injection or will be lazy loaded\r\n timeout?: number;\r\n }) {\r\n this.defaultSiteKey = options?.defaultSiteKey;\r\n this.lazyLoader = options?.lazyLoader ?? new LazyLoaderService();\r\n this.grecaptchaLibraryCache = options?.grecaptchaLibrary;\r\n this.timeout = options?.timeout ?? RecaptchaManager.DEFAULT_TIMEOUT;\r\n }\r\n\r\n /** @inheritdoc */\r\n setTimeoutDelay(delay: number): void {\r\n this.timeout = delay;\r\n }\r\n\r\n /** @inheritdoc */\r\n async getRecaptchaWidget(options?: {\r\n siteKey?: string;\r\n recaptchaParams?: ReCaptchaV2.Parameters;\r\n }): Promise<RecaptchaWidgetInterface> {\r\n const key = options?.siteKey ?? this.defaultSiteKey;\r\n if (!key) {\r\n throw new Error('The reCaptcha widget requires a site key');\r\n }\r\n\r\n const cached = this.recaptchaCache[key];\r\n if (cached) return cached;\r\n\r\n const grecaptchaLibrary = await this.getRecaptchaLibrary();\r\n const recaptcha = new RecaptchaWidget(\r\n {\r\n siteKey: key,\r\n grecaptchaLibrary,\r\n },\r\n options?.recaptchaParams,\r\n );\r\n\r\n this.recaptchaCache[key] = recaptcha;\r\n return recaptcha;\r\n }\r\n\r\n /**\r\n * Load the Recaptcha library from Google.\r\n *\r\n * @returns Promise<ReCaptchaV2.ReCaptcha>\r\n */\r\n private async getRecaptchaLibrary(): Promise<ReCaptchaV2.ReCaptcha> {\r\n if (this.grecaptchaLibraryCache) {\r\n return this.grecaptchaLibraryCache;\r\n }\r\n return new Promise((resolve, reject) => {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n (window as any).grecaptchaLoadedCallback = (): void => {\r\n setTimeout(() => {\r\n // remove the callback when we're done with it\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n delete (window as any).grecaptchaLoadedCallback;\r\n }, 10);\r\n this.grecaptchaLibraryCache = window.grecaptcha;\r\n resolve(window.grecaptcha);\r\n };\r\n\r\n setTimeout(\r\n () => reject(new Error('grecaptcha failed to execute callback')),\r\n this.timeout,\r\n );\r\n\r\n this.lazyLoader.loadScript({\r\n src: 'https://www.google.com/recaptcha/api.js?onload=grecaptchaLoadedCallback&render=explicit',\r\n });\r\n });\r\n }\r\n\r\n /** don't use directly, use `getRecaptchaLibrary()` */\r\n private grecaptchaLibraryCache?: ReCaptchaV2.ReCaptcha;\r\n}\r\n"]}
@@ -1,7 +1,9 @@
1
1
  import { BundleType, LazyLoaderServiceEvents, LazyLoaderServiceInterface } from '@internetarchive/lazy-loader-service';
2
2
  import { Unsubscribe } from 'nanoevents';
3
3
  export declare class MockLazyLoaderService implements LazyLoaderServiceInterface {
4
+ private onloadFn;
4
5
  loadScriptSrc?: string;
6
+ constructor(onloadFn?: () => unknown);
5
7
  on<E extends keyof LazyLoaderServiceEvents>(event: E, callback: LazyLoaderServiceEvents[E]): Unsubscribe;
6
8
  loadBundle(bundle: {
7
9
  module?: string;