If I importScripts("sodium.js") in such a blob created worker, sodium.ready inside the worker never fires.
If the web worker is created "normally" with an external js file, it works correctly.
Complete test case of issue:
<!DOCTYPE html>
<html>
<body>
<script>
class Threadable extends Function {
constructor(f) {
super("...as",`return (${f.toString()}).apply(this, as)`);
}
spawn(...as) {
var code = `self.onmessage = m => self.postMessage((${this.toString()}).apply(self,m.data));`,
blob = new Blob([code], {type: "text/javascript"}),
wrkr = new Worker(window.URL.createObjectURL(blob));
return new Promise((v, x) => (wrkr.onmessage = m => (v(m.data), wrkr.terminate()),
wrkr.onerror = e => (x(e.message), wrkr.terminate()),
wrkr.postMessage(as)));
}
};
const generateSecurityHashChunkWorker = new Threadable((salt, secret) => {
const sodiumOnload = async sodium => {
// Never enters here
console.log("Sodium ready fired");
let saltSodium = sodium.from_string(salt);
saltSodium = await sodium.crypto_generichash(16, saltSodium, null);
const secretSodium = sodium.from_string(iterationSecret);
const hash = await sodium.crypto_pwhash(
64,
secretSodium,
saltSodium,
sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,
sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE,
sodium.crypto_pwhash_ALG_ARGON2ID13);
console.log("sodium result", hash);
postMessage(hash);
};
importScripts('https://fastly.jsdelivr.net/gh/jedisct1/libsodium.js@master/dist/browsers-sumo/sodium.js');
sodium.ready.then(async () => await sodiumOnload(sodium));
console.log("sodium.ready", sodium.ready);
});
const generateSecurityHashAsync = async (salt, secret) => {
if (!salt) {
throw "salt cannot be empty";
}
if (!secret) {
throw "secret cannot be empty";
}
const start = new Date().getTime();
const worker = generateSecurityHashChunkWorker.spawn(
salt,
secret);
const hash = await worker;
console.log("Hash result from awaiting worker", hash);
const timeMilliseconds = new Date().getTime() - start;
console.log("Security hash time (ms)", timeMilliseconds, "size", hash?.length);
return hash;
};
document.addEventListener("DOMContentLoaded", async event => {
const salt = "Test";
const password = "Password";
const hash = await generateSecurityHashAsync(salt, password);
console.log(hash);
});
</script>
</body>
</html>
Hello,
Using the technique described here: https://stackoverflow.com/a/73621351/111830
If I
importScripts("sodium.js")
in such a blob created worker, sodium.ready inside the worker never fires. If the web worker is created "normally" with an external js file, it works correctly.Complete test case of issue: