|
3986 | 3986 | * | {name: "play.use", remember: "0" | "1"}
|
3987 | 3987 | * | {name: "play.use.thumbnail"}
|
3988 | 3988 | * | {name: "play.do_not_use", remember: "0" | "1"}
|
3989 |
| - * | {name: "play.do_not_use.thumbnail"}} input |
| 3989 | + * | {name: "play.do_not_use.dismiss"}} input |
3990 | 3990 | */
|
3991 | 3991 | constructor(input) {
|
3992 | 3992 | this.input = input;
|
|
4004 | 4004 | case "play.do_not_use": {
|
4005 | 4005 | return { remember: this.input.remember };
|
4006 | 4006 | }
|
4007 |
| - case "play.do_not_use.thumbnail": |
| 4007 | + case "play.do_not_use.dismiss": |
4008 | 4008 | return {};
|
4009 | 4009 | default:
|
4010 | 4010 | throw new Error("unreachable");
|
|
5497 | 5497 | return this.mobileOptOut(e.detail.remember).catch(console.error);
|
5498 | 5498 | });
|
5499 | 5499 | drawer.addEventListener(DDGVideoDrawerMobile.DISMISS, () => {
|
5500 |
| - return this.mobileOptOut(false).catch(console.error); |
| 5500 | + return this.dismissOverlay(); |
5501 | 5501 | });
|
5502 | 5502 | drawer.addEventListener(DDGVideoDrawerMobile.THUMBNAIL_CLICK, () => {
|
5503 |
| - return this.videoThumbnailClick(); |
| 5503 | + return this.dismissOverlay(); |
5504 | 5504 | });
|
5505 | 5505 | drawer.addEventListener(DDGVideoDrawerMobile.OPT_IN, (e) => {
|
5506 | 5506 | return this.mobileOptIn(e.detail.remember, params).catch(console.error);
|
|
5661 | 5661 | }
|
5662 | 5662 | this.destroy();
|
5663 | 5663 | }
|
5664 |
| - videoThumbnailClick() { |
5665 |
| - const pixel = new Pixel({ name: "play.do_not_use.thumbnail" }); |
| 5664 | + dismissOverlay() { |
| 5665 | + const pixel = new Pixel({ name: "play.do_not_use.dismiss" }); |
5666 | 5666 | this.messages.sendPixel(pixel);
|
5667 | 5667 | return this.destroy();
|
5668 | 5668 | }
|
|
8656 | 8656 |
|
8657 | 8657 | // src/features/broker-protection/captcha-services/utils/token.js
|
8658 | 8658 | init_define_import_meta_trackerLookup();
|
8659 |
| - function injectTokenIntoElement({ captchaContainerElement, elementName, token }) { |
8660 |
| - const element = getElementByTagName(captchaContainerElement, elementName); |
| 8659 | + |
| 8660 | + // src/features/broker-protection/captcha-services/utils/element.js |
| 8661 | + init_define_import_meta_trackerLookup(); |
| 8662 | + function isElementType(element, tag) { |
| 8663 | + if (Array.isArray(tag)) { |
| 8664 | + return tag.some((t) => isElementType(element, t)); |
| 8665 | + } |
| 8666 | + return element.tagName.toLowerCase() === tag.toLowerCase(); |
| 8667 | + } |
| 8668 | + |
| 8669 | + // src/features/broker-protection/captcha-services/utils/token.js |
| 8670 | + function injectTokenIntoElement({ captchaContainerElement, captchaInputElement, elementName, token }) { |
| 8671 | + let element; |
| 8672 | + if (captchaInputElement) { |
| 8673 | + element = captchaInputElement; |
| 8674 | + } else if (elementName) { |
| 8675 | + element = getElementByTagName(captchaContainerElement, elementName); |
| 8676 | + } else { |
| 8677 | + return PirError.create(`[injectTokenIntoElement] must pass in either captcha input element or element name`); |
| 8678 | + } |
8661 | 8679 | if (!element) {
|
8662 |
| - return PirError.create(`[injectTokenIntoElement] could not find element with name ${elementName}`); |
| 8680 | + return PirError.create(`[injectTokenIntoElement] could not find element to inject token into`); |
8663 | 8681 | }
|
8664 | 8682 | return safeCallWithError(
|
8665 | 8683 | () => {
|
8666 |
| - element.innerHTML = token; |
8667 |
| - return PirSuccess.create({ injected: true }); |
| 8684 | + if (isInputElement(element) && ["text", "hidden"].includes(element.type) || isTextAreaElement(element)) { |
| 8685 | + element.value = token; |
| 8686 | + return PirSuccess.create({ injected: true }); |
| 8687 | + } else { |
| 8688 | + return PirError.create(`[injectTokenIntoElement] element is neither a text input or textarea`); |
| 8689 | + } |
8668 | 8690 | },
|
8669 |
| - { errorMessage: `[injectTokenIntoElement] error injecting token into element ${elementName}` } |
| 8691 | + { errorMessage: `[injectTokenIntoElement] error injecting token into element` } |
8670 | 8692 | );
|
8671 | 8693 | }
|
| 8694 | + function isInputElement(element) { |
| 8695 | + return isElementType(element, "input"); |
| 8696 | + } |
| 8697 | + function isTextAreaElement(element) { |
| 8698 | + return isElementType(element, "textarea"); |
| 8699 | + } |
8672 | 8700 |
|
8673 | 8701 | // src/features/broker-protection/actions/captcha-callback.js
|
8674 | 8702 | init_define_import_meta_trackerLookup();
|
|
8749 | 8777 | * @param {HTMLElement} captchaContainerElement
|
8750 | 8778 | */
|
8751 | 8779 | getCaptchaIdentifier(captchaContainerElement) {
|
8752 |
| - return safeCallWithError( |
8753 |
| - () => getSiteKeyFromSearchParam({ captchaElement: this._getCaptchaElement(captchaContainerElement), siteKeyAttrName: "k" }), |
8754 |
| - { errorMessage: "[ReCaptchaProvider.getCaptchaIdentifier] could not extract site key" } |
| 8780 | + return Promise.resolve( |
| 8781 | + safeCallWithError( |
| 8782 | + () => getSiteKeyFromSearchParam({ captchaElement: this._getCaptchaElement(captchaContainerElement), siteKeyAttrName: "k" }), |
| 8783 | + { errorMessage: "[ReCaptchaProvider.getCaptchaIdentifier] could not extract site key" } |
| 8784 | + ) |
8755 | 8785 | );
|
8756 | 8786 | }
|
8757 | 8787 | getSupportingCodeToInject() {
|
|
8791 | 8821 | };
|
8792 | 8822 | _config = new WeakMap();
|
8793 | 8823 |
|
| 8824 | + // src/features/broker-protection/captcha-services/providers/image.js |
| 8825 | + init_define_import_meta_trackerLookup(); |
| 8826 | + |
| 8827 | + // src/features/broker-protection/captcha-services/utils/image.js |
| 8828 | + init_define_import_meta_trackerLookup(); |
| 8829 | + function svgToBase64Jpg(svgElement, backgroundColor = "white") { |
| 8830 | + const svgString = new XMLSerializer().serializeToString(svgElement); |
| 8831 | + const svgDataUrl = "data:image/svg+xml;base64," + btoa(svgString); |
| 8832 | + return new Promise((resolve, reject) => { |
| 8833 | + const img = new Image(); |
| 8834 | + img.onload = () => { |
| 8835 | + const canvas = document.createElement("canvas"); |
| 8836 | + const ctx = canvas.getContext("2d"); |
| 8837 | + if (!ctx) { |
| 8838 | + reject(new Error("Could not get 2D context from canvas")); |
| 8839 | + return; |
| 8840 | + } |
| 8841 | + canvas.width = img.width; |
| 8842 | + canvas.height = img.height; |
| 8843 | + ctx.fillStyle = backgroundColor; |
| 8844 | + ctx.fillRect(0, 0, canvas.width, canvas.height); |
| 8845 | + ctx.drawImage(img, 0, 0); |
| 8846 | + const jpgBase64 = canvas.toDataURL("image/jpeg"); |
| 8847 | + resolve(jpgBase64); |
| 8848 | + }; |
| 8849 | + img.onerror = (error) => { |
| 8850 | + reject(error); |
| 8851 | + }; |
| 8852 | + img.src = svgDataUrl; |
| 8853 | + }); |
| 8854 | + } |
| 8855 | + function imageToBase64(imageElement) { |
| 8856 | + const canvas = document.createElement("canvas"); |
| 8857 | + const ctx = canvas.getContext("2d"); |
| 8858 | + if (!ctx) { |
| 8859 | + throw Error("[imageToBase64] Could not get 2D context from canvas"); |
| 8860 | + } |
| 8861 | + canvas.width = imageElement.width; |
| 8862 | + canvas.height = imageElement.height; |
| 8863 | + ctx.drawImage(imageElement, 0, 0, canvas.width, canvas.height); |
| 8864 | + const base64String = canvas.toDataURL("image/jpeg"); |
| 8865 | + return base64String; |
| 8866 | + } |
| 8867 | + |
| 8868 | + // src/features/broker-protection/captcha-services/providers/image.js |
| 8869 | + var ImageProvider = class { |
| 8870 | + getType() { |
| 8871 | + return "image"; |
| 8872 | + } |
| 8873 | + /** |
| 8874 | + * @param {HTMLElement} captchaImageElement - The captcha image element |
| 8875 | + */ |
| 8876 | + isSupportedForElement(captchaImageElement) { |
| 8877 | + if (!captchaImageElement) { |
| 8878 | + return false; |
| 8879 | + } |
| 8880 | + return isElementType(captchaImageElement, ["img", "svg"]); |
| 8881 | + } |
| 8882 | + /** |
| 8883 | + * @param {HTMLElement} captchaImageElement - The captcha image element |
| 8884 | + */ |
| 8885 | + async getCaptchaIdentifier(captchaImageElement) { |
| 8886 | + if (isSVGElement(captchaImageElement)) { |
| 8887 | + return await svgToBase64Jpg(captchaImageElement); |
| 8888 | + } |
| 8889 | + if (isImgElement(captchaImageElement)) { |
| 8890 | + return imageToBase64(captchaImageElement); |
| 8891 | + } |
| 8892 | + return PirError.create( |
| 8893 | + `[ImageProvider.getCaptchaIdentifier] could not extract Base64 from image with tag name: ${captchaImageElement.tagName}` |
| 8894 | + ); |
| 8895 | + } |
| 8896 | + getSupportingCodeToInject() { |
| 8897 | + return null; |
| 8898 | + } |
| 8899 | + /** |
| 8900 | + * @param {HTMLElement} captchaInputElement - The captcha input element |
| 8901 | + */ |
| 8902 | + canSolve(captchaInputElement) { |
| 8903 | + return isElementType(captchaInputElement, ["input", "textarea"]); |
| 8904 | + } |
| 8905 | + /** |
| 8906 | + * @param {HTMLInputElement} captchaInputElement - The captcha input element |
| 8907 | + * @param {string} token - The solved captcha token |
| 8908 | + */ |
| 8909 | + injectToken(captchaInputElement, token) { |
| 8910 | + return injectTokenIntoElement({ captchaInputElement, token }); |
| 8911 | + } |
| 8912 | + /** |
| 8913 | + * @param {HTMLElement} _captchaInputElement - The element containing the captcha |
| 8914 | + * @param {string} _token - The solved captcha token |
| 8915 | + */ |
| 8916 | + getSolveCallback(_captchaInputElement, _token) { |
| 8917 | + return stringifyFunction({ |
| 8918 | + functionBody: function callbackNoop() { |
| 8919 | + }, |
| 8920 | + functionName: "callbackNoop", |
| 8921 | + args: {} |
| 8922 | + }); |
| 8923 | + } |
| 8924 | + }; |
| 8925 | + function isSVGElement(element) { |
| 8926 | + return isElementType(element, "svg"); |
| 8927 | + } |
| 8928 | + function isImgElement(element) { |
| 8929 | + return isElementType(element, "img"); |
| 8930 | + } |
| 8931 | + |
8794 | 8932 | // src/features/broker-protection/captcha-services/providers/registry.js
|
8795 | 8933 | var captchaFactory = new CaptchaFactory();
|
8796 | 8934 | captchaFactory.registerProvider(
|
|
8807 | 8945 | responseElementName: "g-recaptcha-response"
|
8808 | 8946 | })
|
8809 | 8947 | );
|
| 8948 | + captchaFactory.registerProvider(new ImageProvider()); |
8810 | 8949 |
|
8811 | 8950 | // src/features/broker-protection/captcha-services/get-captcha-provider.js
|
8812 | 8951 | function getCaptchaProvider(captchaContainer, captchaType) {
|
|
8955 | 9094 | }
|
8956 | 9095 | return SuccessResponse.create({ actionID, actionType, response: { code: captchaProvider.getSupportingCodeToInject() } });
|
8957 | 9096 | }
|
8958 |
| - function getCaptchaInfo2(action, root = document) { |
| 9097 | + async function getCaptchaInfo2(action, root = document) { |
8959 | 9098 | const { id: actionID, actionType, captchaType, selector } = action;
|
8960 | 9099 | if (!captchaType) {
|
8961 | 9100 | return getCaptchaInfo(action, root);
|
|
8969 | 9108 | if (PirError.isError(captchaProvider)) {
|
8970 | 9109 | return createError(captchaProvider.error.message);
|
8971 | 9110 | }
|
8972 |
| - const captchaIdentifier = captchaProvider.getCaptchaIdentifier(captchaContainer); |
| 9111 | + const captchaIdentifier = await captchaProvider.getCaptchaIdentifier(captchaContainer); |
8973 | 9112 | if (!captchaIdentifier) {
|
8974 | 9113 | return createError(`could not extract captcha identifier from the container with selector ${selector}`);
|
8975 | 9114 | }
|
|
9070 | 9209 | case "fillForm":
|
9071 | 9210 | return fillForm(action, data(action, inputData, "extractedProfile"), root);
|
9072 | 9211 | case "getCaptchaInfo":
|
9073 |
| - return getCaptchaInfo2(action, root); |
| 9212 | + return await getCaptchaInfo2(action, root); |
9074 | 9213 | case "solveCaptcha":
|
9075 | 9214 | return solveCaptcha2(action, data(action, inputData, "token"), root);
|
9076 | 9215 | default: {
|
|
0 commit comments