@descope/web-components-ui 1.0.308 → 1.0.309

Sign up to get free protection for your applications and to get access to all the features.
@@ -1 +1 @@
1
- "use strict";(self.webpackChunk_descope_web_components_ui=self.webpackChunk_descope_web_components_ui||[]).push([[964],{8164:(e,t,a)=>{a.r(t),a.d(t,{RecaptchaClass:()=>p});var c=a(4978),n=a(3346),s=a(2061);const i=(0,a(4567).iY)("recaptcha"),r=["enabled","site-key","action","enterprise"],o=(0,n.s)({componentName:i,baseSelector:":host > div"}),p=(0,s.qC)(c.e4)(class extends o{static get observedAttributes(){return r.concat(o.observedAttributes||[])}attributeChangedCallback(e,t,a){super.attributeChangedCallback?.(e,t,a),"enabled"===e&&this.#e("true"===a)}renderRecaptcha(e){e?(this.recaptchaEle.style.display="",this.mockRecaptchaEle.style.display="none"):(this.recaptchaEle.style.display="none",this.mockRecaptchaEle.style.display="")}constructor(){super(),this.attachShadow({mode:"open"}).innerHTML='\n\t\t<style>\n :host {\n display: inline-flex;\n }\n :host > div {\n display: flex;\n }\n :host #recaptcha {\n\t\t\t\twidth: 100%;\n height: 100%;\n\t\t\t}\n :host img {\n width: 256px;\n }\n\t\t</style>\n <div>\n <span id="recaptcha"></span>\n <img src="https://imgs.descope.com/connectors/templates/recaptcha/recaptcha-big.png" alt="recaptcha"/>\n </div>\n\t',this.recaptchaEle=this.baseElement.querySelector("#recaptcha"),this.mockRecaptchaEle=this.baseElement.querySelector("img")}get enterprise(){return"true"===this.getAttribute("enterprise")}get siteKey(){return this.getAttribute("site-key")}get action(){return this.getAttribute("action")||"load"}get enabled(){return"true"===this.getAttribute("enabled")}get scriptURL(){const e=new URL("https://www.google.com/recaptcha/");return e.pathname+=(this.enterprise?"enterprise":"api")+".js",e.searchParams.append("onload","onRecaptchaLoadCallback"),e.searchParams.append("render","explicit"),e.toString()}#e(e){this.renderRecaptcha(e),e&&(this.#t(),this.#a())}#t(){if(document.getElementById("recaptcha-script"))window.onRecaptchaLoadCallback();else{const e=document.createElement("script");e.src=this.scriptURL,e.async=!0,e.id="recaptcha-script",e.defer=!0,document.body.appendChild(e)}}#a(){window.onRecaptchaLoadCallback||(window.onRecaptchaLoadCallback=()=>{const e=this.recaptchaEle;if(e.hasChildNodes())return;const t=this.enterprise?window.grecaptcha?.enterprise:window.grecaptcha;t&&setTimeout((()=>{const a=t.render(e,{sitekey:this.siteKey,badge:"inline",size:"invisible"});t.ready((()=>{const c=e.querySelector("#g-recaptcha-response")?.cloneNode();c&&(c.style.display="none",document.body.appendChild(c)),this.siteKey&&t?.execute(a,{action:this.action}).then((e=>{this.updateComponentsContext({risktoken:e,riskaction:this.action})}))}))}),0)})}connectedCallback(){super.connectedCallback?.(),this.#e(this.enabled)}});customElements.define(i,p)}}]);
1
+ "use strict";(self.webpackChunk_descope_web_components_ui=self.webpackChunk_descope_web_components_ui||[]).push([[964],{8164:(e,t,a)=>{a.r(t),a.d(t,{RecaptchaClass:()=>p});var c=a(4978),n=a(3346),s=a(2061);const i=(0,a(4567).iY)("recaptcha"),r=["enabled","site-key","action","enterprise"],o=(0,n.s)({componentName:i,baseSelector:":host > div"}),p=(0,s.qC)(c.e4)(class extends o{static get observedAttributes(){return r.concat(o.observedAttributes||[])}attributeChangedCallback(e,t,a){super.attributeChangedCallback?.(e,t,a),t!==a&&"enabled"===e&&this.#e("true"===a)}renderRecaptcha(e){e?(this.recaptchaEle.style.display="",this.mockRecaptchaEle.style.display="none"):(this.recaptchaEle.style.display="none",this.mockRecaptchaEle.style.display="")}constructor(){super(),this.attachShadow({mode:"open"}).innerHTML='\n\t\t<style>\n :host {\n display: inline-flex;\n }\n :host > div {\n display: flex;\n }\n :host #recaptcha {\n\t\t\t\twidth: 100%;\n height: 100%;\n\t\t\t}\n :host img {\n width: 256px;\n }\n\t\t</style>\n <div>\n <span id="recaptcha"></span>\n <img src="https://imgs.descope.com/connectors/templates/recaptcha/recaptcha-big.png" alt="recaptcha"/>\n </div>\n\t',this.recaptchaEle=this.baseElement.querySelector("#recaptcha"),this.mockRecaptchaEle=this.baseElement.querySelector("img")}get enterprise(){return"true"===this.getAttribute("enterprise")}get siteKey(){return this.getAttribute("site-key")}get action(){return this.getAttribute("action")||"load"}get enabled(){return"true"===this.getAttribute("enabled")}get scriptURL(){const e=new URL("https://www.google.com/recaptcha/");return e.pathname+=(this.enterprise?"enterprise":"api")+".js",e.searchParams.append("onload","onRecaptchaLoadCallback"),e.searchParams.append("render","explicit"),e.toString()}#e(e){this.renderRecaptcha(e),e&&(this.#t(),document.getElementById("recaptcha-script")?window.onRecaptchaLoadCallback():this.#a())}#a(){const e=document.createElement("script");e.src=this.scriptURL,e.async=!0,e.id="recaptcha-script",e.defer=!0,document.body.appendChild(e)}get grecaptchaInstance(){return this.enterprise?window.grecaptcha?.enterprise:window.grecaptcha}#t(){window.onRecaptchaLoadCallback=()=>{const e=this.recaptchaEle;if(e.hasChildNodes())return;const{grecaptchaInstance:t}=this;t&&setTimeout((()=>{const a=t.render(e,{sitekey:this.siteKey,badge:"inline",size:"invisible"});t.ready((()=>{const c=e.querySelector('textarea[name^="g-recaptcha-response"]')?.cloneNode();c&&(c.style.display="none",document.body.appendChild(c));const n=()=>{c.remove()};if(this.siteKey){const e=t?.execute(a,{action:this.action});e.then((e=>{this.updateComponentsContext({risktoken:e,riskaction:this.action}),n()})).catch((e=>{n(),console.warn("could not execute recaptcha",e)}))}}))}),0)}}});customElements.define(i,p)}}]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@descope/web-components-ui",
3
- "version": "1.0.308",
3
+ "version": "1.0.309",
4
4
  "description": "",
5
5
  "main": "dist/cjs/index.cjs.js",
6
6
  "module": "dist/index.esm.js",
@@ -18,8 +18,10 @@ class RawRecaptcha extends BaseClass {
18
18
 
19
19
  attributeChangedCallback(attrName, oldValue, newValue) {
20
20
  super.attributeChangedCallback?.(attrName, oldValue, newValue);
21
- if (attrName === 'enabled') {
22
- this.#toggleRecaptcha(newValue === 'true');
21
+ if (oldValue !== newValue) {
22
+ if (attrName === 'enabled') {
23
+ this.#toggleRecaptcha(newValue === 'true');
24
+ }
23
25
  }
24
26
  }
25
27
 
@@ -89,73 +91,89 @@ class RawRecaptcha extends BaseClass {
89
91
  #toggleRecaptcha(enabled) {
90
92
  this.renderRecaptcha(enabled);
91
93
  if (enabled) {
92
- this.#loadRecaptchaScript();
93
94
  this.#createOnLoadScript();
95
+ if (!document.getElementById('recaptcha-script')) {
96
+ this.#loadRecaptchaScript();
97
+ } else {
98
+ window.onRecaptchaLoadCallback();
99
+ }
94
100
  }
95
101
  }
96
102
 
97
103
  #loadRecaptchaScript() {
98
- if (!document.getElementById('recaptcha-script')) {
99
- const script = document.createElement('script');
100
- script.src = this.scriptURL;
101
- script.async = true;
102
- script.id = 'recaptcha-script';
103
- script.defer = true;
104
- document.body.appendChild(script);
105
- } else {
106
- window.onRecaptchaLoadCallback();
107
- }
104
+ const script = document.createElement('script');
105
+ script.src = this.scriptURL;
106
+ script.async = true;
107
+ script.id = 'recaptcha-script';
108
+ script.defer = true;
109
+ document.body.appendChild(script);
108
110
  }
109
111
 
110
- #createOnLoadScript() {
111
- if (window.onRecaptchaLoadCallback) {
112
- return;
113
- }
112
+ get grecaptchaInstance() {
113
+ return this.enterprise ? window.grecaptcha?.enterprise : window.grecaptcha;
114
+ }
114
115
 
116
+ #createOnLoadScript() {
115
117
  window.onRecaptchaLoadCallback = () => {
116
118
  const currentNode = this.recaptchaEle;
119
+
117
120
  // if there are child nodes, it means that the recaptcha was already rendered
118
121
  if (currentNode.hasChildNodes()) {
119
122
  return;
120
123
  }
121
- const grecaptchaInstance = this.enterprise
122
- ? window.grecaptcha?.enterprise
123
- : window.grecaptcha;
124
+
125
+ const { grecaptchaInstance } = this;
124
126
 
125
127
  if (!grecaptchaInstance) {
126
128
  return;
127
129
  }
128
130
 
129
131
  setTimeout(() => {
130
- const view = grecaptchaInstance.render(currentNode, {
132
+ // returns recaptchaWidgetId
133
+ const recaptchaWidgetId = grecaptchaInstance.render(currentNode, {
131
134
  sitekey: this.siteKey,
132
135
  badge: 'inline',
133
136
  size: 'invisible',
134
137
  });
138
+
135
139
  grecaptchaInstance.ready(() => {
136
140
  // clone the node and append it to the body so that it can be used by the grepcaptcha script
137
- const cloneNode = currentNode.querySelector('#g-recaptcha-response')?.cloneNode();
141
+ const cloneNode = currentNode
142
+ .querySelector('textarea[name^="g-recaptcha-response"]')
143
+ ?.cloneNode();
138
144
  if (cloneNode) {
139
145
  cloneNode.style.display = 'none';
140
146
  document.body.appendChild(cloneNode);
141
147
  }
148
+
149
+ // cleaning up the recaptcha element we added to the body
150
+ const removeCloneNode = () => {
151
+ cloneNode.remove();
152
+ };
153
+
142
154
  if (this.siteKey) {
143
- grecaptchaInstance?.execute(view, { action: this.action }).then((token) => {
144
- this.updateComponentsContext({
145
- risktoken: token,
146
- riskaction: this.action,
155
+ // we should pass recaptchaWidgetId, but this does not allow us to run execute multiple times
156
+ // also calling grecaptchaInstance.reset() does not work
157
+ const exec = grecaptchaInstance?.execute(recaptchaWidgetId, { action: this.action });
158
+ exec
159
+ .then((token) => {
160
+ this.updateComponentsContext({
161
+ risktoken: token,
162
+ riskaction: this.action,
163
+ });
164
+
165
+ removeCloneNode();
166
+ })
167
+ .catch((e) => {
168
+ removeCloneNode();
169
+ // eslint-disable-next-line no-console
170
+ console.warn('could not execute recaptcha', e);
147
171
  });
148
- });
149
172
  }
150
173
  });
151
174
  }, 0);
152
175
  };
153
176
  }
154
-
155
- connectedCallback() {
156
- super.connectedCallback?.();
157
- this.#toggleRecaptcha(this.enabled);
158
- }
159
177
  }
160
178
 
161
179
  export const RecaptchaClass = compose(draggableMixin)(RawRecaptcha);
@@ -1,9 +1,5 @@
1
- import { createDispatchEvent } from '../helpers/mixinsHelpers';
2
-
3
1
  export const componentsContextMixin = (superclass) =>
4
2
  class ComponentsContextMixinClass extends superclass {
5
- #dispatchComponentsContext = createDispatchEvent.bind(this, 'components-context');
6
-
7
3
  updateComponentsContext(componentsContext) {
8
4
  this.dispatchEvent(
9
5
  new CustomEvent('components-context', {