Search code examples
javascriptasync-await

Asynchronous onsubmit handler


I'm trying to convert a password to a sha1 sum before submitting. I'm using crypto.subtle.digest to do the conversion. Since it returns a promise, I await on it. The problem is, that the password is submitted unconverted.

function buf2hex(buffer) { // buffer is an ArrayBuffer
    return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}

async function onPwSubmit(event) {
    /* Handle password-form-submit-events
     *
     * Replace the entered password with the SHA1-hash of it.
     * Return 'false' to abort form-submission if anything goes wrong.
     * Return 'true' otherwise.
     */
    event.preventDefault();

    let input_password = document.getElementById('{{ form.password.auto_id }}');
    if (!input_password) { // Just in case something goes wrong, add a message.
        alert("Could not hash entered password with SHA1. Please call help.");
        console.log("Is there a form-field with id 'id_password'?");
        // Abort the form-submit by returning false.
        // Must not submit with password not hashed.
        return false;
    }

    let digest = await crypto.subtle.digest("SHA-1", new TextEncoder().encode(input_password.value));

    input_password.value = buf2hex(digest).toUpperCase();

    event.submit()

    return true; // allow form-submit to continue with return true
}

document.querySelector("#passwordform").addEventListener("onsubmit", onPwSubmit)


I expect the password to be converted before submitting, but it isn't.


Solution

  • Your handler is not running at all, because the listener is not attached properly:

    document.querySelector("#passwordform").addEventListener("onsubmit", onPwSubmit)
    

    This listens for the event named onsubmit, and when it occurs, calls the callback. But there's no such event. You want to listen for the submit event, full stop:

    document.querySelector("#passwordform").addEventListener("submit", onPwSubmit)
    

    Only use the on prefix when assigning the handler with =, for example:

    document.querySelector("#passwordform").onsubmit = onPwSubmit
    

    The same sort of pattern (of when to use on and when not to) applies to all other events as well.

    You also can't submit from an event:

    event.submit()
    

    Rather, select the form, and call submit on it instead:

    document.querySelector("#passwordform").submit();
    

    (this will not recursively call the submit handler you attached, don't worry)