altcha-org / altcha

GDPR compliant, self-hosted CAPTCHA alternative with PoW mechanism and advanced anti-spam filter.
https://altcha.org
MIT License
241 stars 5 forks source link

Design choice? | Hidden input not created when dispatching "verified" event #10

Closed alexbcberio closed 5 months ago

alexbcberio commented 5 months ago

I'm not sure if this is a design choice or a bug, I am reporting it just in case. If its a design choice it should be mentioned in the documentation.

I have implemented a very basic feature to automatically submit a form if the altcha-widget element contains a specific attribute (data-submit-verified).

The issue is that the hidden input is not being received by the server, I though it might be created after the event so I tried submiting the form with a delay of 100ms but still was not received on the server (seems to be working fine with a delay of 1s). I have had to create and append the hidden input manually.

This is the typescript code that I am using, you can comment the line that appends the input to the form to test/debug it.

type VerifiedEvent = CustomEvent<{ payload: string }>;

document.addEventListener("DOMContentLoaded", (): void => {
    const widgets = document.querySelectorAll<any>("altcha-widget");

    for (let i = 0; i < widgets.length; i++) {
        const widget = widgets[i];

        widget.addEventListener("verified", onWidgetVerified.bind(widget));
    }
});

function onWidgetVerified(this: HTMLElement, e: VerifiedEvent): void {
    if (!this.hasAttribute("data-submit-verified")) {
        return;
    }

    const form = this.closest("form");

    if (!form) {
        return;
    }

    const input = document.createElement("input");
    input.type = "hidden";
    input.name = this.getAttribute("name") ?? "altcha";
    input.value = e.detail.payload;
    form.appendChild(input);

    form.submit();
}
ovx commented 5 months ago

Hi, which version are you using? There was this issue in version 0.1.1 (https://github.com/altcha-org/altcha/commit/e1bb0025c14550e67198bdf318294645779a235f#diff-1a6798607b0fe5453e7855dfcea64eca8d1575e764c9be76696ac2e49283a490L73), fixed since 0.1.2.

alexbcberio commented 5 months ago

I'm using the latest version available in yarn, the yarn.lock reports v0.1.2. Seems to be the latest version available too on npm

ovx commented 5 months ago

Please try with the latest version 0.1.4 now published to npm.

alexbcberio commented 5 months ago

On v0.1.4 the input is created on the next tick, so I have to perform the submit inside a setTimeout with a delay of 0.

In terms of code


function onWidgetVerified(this: HTMLElement): void {
    const form = this.closest("form");

    if (!form) {
        return;
    }

    setTimeout(() => {
        form.submit();
    }, 0);
}
ovx commented 5 months ago

In the latest version 0.1.5, the verified event is triggered after re-render of the widget ensuring that the hidden input is there. This should fix the issue.

Also, you might try using the new auto="" (values: onload or onsubmit) attribute, which auto-verifies when loaded or submitted instead of your custom implementation.

alexbcberio commented 5 months ago

Works ok in v0.1.5, thanks!

Closing as resolved ^-^

PS, The auto is a pretty nice addition, I'm using it as a middleware before showing up the real page content.