initial import from /x/ monorepo

Signed-off-by: Xe Iaso <me@xeiaso.net>
This commit is contained in:
Xe Iaso 2025-03-17 19:33:07 -04:00
commit 9923878c5c
No known key found for this signature in database
61 changed files with 5615 additions and 0 deletions

71
cmd/anubis/js/main.mjs Normal file
View file

@ -0,0 +1,71 @@
import { process } from './proof-of-work.mjs';
import { testVideo } from './video.mjs';
// from Xeact
const u = (url = "", params = {}) => {
let result = new URL(url, window.location.href);
Object.entries(params).forEach((kv) => {
let [k, v] = kv;
result.searchParams.set(k, v);
});
return result.toString();
};
const imageURL = (mood) => {
return `/.within.website/x/cmd/anubis/static/img/${mood}.webp`;
};
(async () => {
const status = document.getElementById('status');
const image = document.getElementById('image');
const title = document.getElementById('title');
const spinner = document.getElementById('spinner');
// const testarea = document.getElementById('testarea');
// const videoWorks = await testVideo(testarea);
// console.log(`videoWorks: ${videoWorks}`);
// if (!videoWorks) {
// title.innerHTML = "Oh no!";
// status.innerHTML = "Checks failed. Please check your browser's settings and try again.";
// image.src = imageURL("sad");
// spinner.innerHTML = "";
// spinner.style.display = "none";
// return;
// }
status.innerHTML = 'Calculating...';
const { challenge, difficulty } = await fetch("/.within.website/x/cmd/anubis/api/make-challenge", { method: "POST" })
.then(r => {
if (!r.ok) {
throw new Error("Failed to fetch config");
}
return r.json();
})
.catch(err => {
title.innerHTML = "Oh no!";
status.innerHTML = `Failed to fetch config: ${err.message}`;
image.src = imageURL("sad");
spinner.innerHTML = "";
spinner.style.display = "none";
throw err;
});
status.innerHTML = `Calculating...<br/>Difficulty: ${difficulty}`;
const t0 = Date.now();
const { hash, nonce } = await process(challenge, difficulty);
const t1 = Date.now();
title.innerHTML = "Success!";
status.innerHTML = `Done! Took ${t1 - t0}ms, ${nonce} iterations`;
image.src = imageURL("happy");
spinner.innerHTML = "";
spinner.style.display = "none";
setTimeout(() => {
const redir = window.location.href;
window.location.href = u("/.within.website/x/cmd/anubis/api/pass-challenge", { response: hash, nonce, redir, elapsedTime: t1 - t0 });
}, 2000);
})();

View file

@ -0,0 +1,62 @@
// https://dev.to/ratmd/simple-proof-of-work-in-javascript-3kgm
export function process(data, difficulty = 5) {
return new Promise((resolve, reject) => {
let webWorkerURL = URL.createObjectURL(new Blob([
'(', processTask(), ')()'
], { type: 'application/javascript' }));
let worker = new Worker(webWorkerURL);
worker.onmessage = (event) => {
worker.terminate();
resolve(event.data);
};
worker.onerror = (event) => {
worker.terminate();
reject();
};
worker.postMessage({
data,
difficulty
});
URL.revokeObjectURL(webWorkerURL);
});
}
function processTask() {
return function () {
const sha256 = (text) => {
const encoded = new TextEncoder().encode(text);
return crypto.subtle.digest("SHA-256", encoded.buffer).then((result) =>
Array.from(new Uint8Array(result))
.map((c) => c.toString(16).padStart(2, "0"))
.join(""),
);
};
addEventListener('message', async (event) => {
let data = event.data.data;
let difficulty = event.data.difficulty;
let hash;
let nonce = 0;
do {
hash = await sha256(data + nonce++);
} while (hash.substring(0, difficulty) !== Array(difficulty + 1).join('0'));
nonce -= 1; // last nonce was post-incremented
postMessage({
hash,
data,
difficulty,
nonce,
});
});
}.toString();
}

16
cmd/anubis/js/video.mjs Normal file
View file

@ -0,0 +1,16 @@
const videoElement = `<video id="videotest" width="0" height="0" src="/.within.website/x/cmd/anubis/static/testdata/black.mp4"></video>`;
export const testVideo = async (testarea) => {
testarea.innerHTML = videoElement;
return (await new Promise((resolve) => {
const video = document.getElementById('videotest');
video.oncanplay = () => {
testarea.style.display = "none";
resolve(true);
};
video.onerror = (ev) => {
testarea.style.display = "none";
resolve(false);
};
}));
};