mirror of
https://github.com/TecharoHQ/anubis.git
synced 2026-04-11 19:18:46 +00:00
chore: set up commitlint, husky, and prettier (#1451)
* chore: add prettier configuration Signed-off-by: Xe Iaso <me@xeiaso.net> * format: run prettier tree-wide Signed-off-by: Xe Iaso <me@xeiaso.net> * chore(prettier): ignore intentionally ungrammatical files Signed-off-by: Xe Iaso <me@xeiaso.net> * ci: add PR title lint rule Signed-off-by: Xe Iaso <me@xeiaso.net> * ci: add DCO check Signed-off-by: Xe Iaso <me@xeiaso.net> * chore: add commitlint and husky Signed-off-by: Xe Iaso <me@xeiaso.net> * chore: add CONTRIBUTING guidelines Signed-off-by: Xe Iaso <me@xeiaso.net> * chore: set SKIP_INTEGRATION in precommit tests Signed-off-by: Xe Iaso <me@xeiaso.net> * chore: update spelling Signed-off-by: Xe Iaso <me@xeiaso.net> * ci(dco): remove reopened trigger Signed-off-by: Xe Iaso <me@xeiaso.net> * chore: remove dead file Signed-off-by: Xe Iaso <me@xeiaso.net> * chore(prettier): don't format nginx includes Signed-off-by: Xe Iaso <me@xeiaso.net> --------- Signed-off-by: Xe Iaso <me@xeiaso.net>
This commit is contained in:
@@ -6,7 +6,9 @@ interface ProcessOptions {
|
||||
}
|
||||
|
||||
const getHardwareConcurrency = () =>
|
||||
navigator.hardwareConcurrency !== undefined ? navigator.hardwareConcurrency : 1;
|
||||
navigator.hardwareConcurrency !== undefined
|
||||
? navigator.hardwareConcurrency
|
||||
: 1;
|
||||
|
||||
export default function process(
|
||||
options: ProcessOptions,
|
||||
@@ -25,7 +27,10 @@ export default function process(
|
||||
workerMethod = "webcrypto";
|
||||
}
|
||||
|
||||
if (navigator.userAgent.includes("Firefox") || navigator.userAgent.includes("Goanna")) {
|
||||
if (
|
||||
navigator.userAgent.includes("Firefox") ||
|
||||
navigator.userAgent.includes("Goanna")
|
||||
) {
|
||||
console.log("Firefox detected, using pure-JS fallback");
|
||||
workerMethod = "purejs";
|
||||
}
|
||||
|
||||
@@ -3,4 +3,4 @@ import fast from "./fast";
|
||||
export default {
|
||||
fast: fast,
|
||||
slow: fast, // XXX(Xe): slow is deprecated, but keep this around in case anything goes bad
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,13 +2,27 @@ import algorithms from "./algorithms";
|
||||
|
||||
const defaultDifficulty = 4;
|
||||
|
||||
const status: HTMLParagraphElement = document.getElementById("status") as HTMLParagraphElement;
|
||||
const difficultyInput: HTMLInputElement = document.getElementById("difficulty-input") as HTMLInputElement;
|
||||
const algorithmSelect: HTMLSelectElement = document.getElementById("algorithm-select") as HTMLSelectElement;
|
||||
const compareSelect: HTMLSelectElement = document.getElementById("compare-select") as HTMLSelectElement;
|
||||
const header: HTMLTableRowElement = document.getElementById("table-header") as HTMLTableRowElement;
|
||||
const headerCompare: HTMLTableSectionElement = document.getElementById("table-header-compare") as HTMLTableSectionElement;
|
||||
const results: HTMLTableRowElement = document.getElementById("results") as HTMLTableRowElement;
|
||||
const status: HTMLParagraphElement = document.getElementById(
|
||||
"status",
|
||||
) as HTMLParagraphElement;
|
||||
const difficultyInput: HTMLInputElement = document.getElementById(
|
||||
"difficulty-input",
|
||||
) as HTMLInputElement;
|
||||
const algorithmSelect: HTMLSelectElement = document.getElementById(
|
||||
"algorithm-select",
|
||||
) as HTMLSelectElement;
|
||||
const compareSelect: HTMLSelectElement = document.getElementById(
|
||||
"compare-select",
|
||||
) as HTMLSelectElement;
|
||||
const header: HTMLTableRowElement = document.getElementById(
|
||||
"table-header",
|
||||
) as HTMLTableRowElement;
|
||||
const headerCompare: HTMLTableSectionElement = document.getElementById(
|
||||
"table-header-compare",
|
||||
) as HTMLTableSectionElement;
|
||||
const results: HTMLTableRowElement = document.getElementById(
|
||||
"results",
|
||||
) as HTMLTableRowElement;
|
||||
|
||||
const setupControls = () => {
|
||||
if (defaultDifficulty == null) {
|
||||
@@ -41,7 +55,12 @@ const benchmarkTrial = async (stats, difficulty, algorithm, signal) => {
|
||||
.join("");
|
||||
|
||||
const t0 = performance.now();
|
||||
const { hash, nonce } = await process({ basePrefix: "/", version: "devel" }, challenge, Number(difficulty), signal);
|
||||
const { hash, nonce } = await process(
|
||||
{ basePrefix: "/", version: "devel" },
|
||||
challenge,
|
||||
Number(difficulty),
|
||||
signal,
|
||||
);
|
||||
const t1 = performance.now();
|
||||
console.log({ hash, nonce });
|
||||
|
||||
|
||||
@@ -29,22 +29,25 @@ const getAvailableLanguages = async () => {
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${basePrefix}/.within.website/x/cmd/anubis/static/locales/manifest.json`);
|
||||
const response = await fetch(
|
||||
`${basePrefix}/.within.website/x/cmd/anubis/static/locales/manifest.json`,
|
||||
);
|
||||
if (response.ok) {
|
||||
const manifest = await response.json();
|
||||
return manifest.supportedLanguages || ['en'];
|
||||
return manifest.supportedLanguages || ["en"];
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to load language manifest, falling back to default languages');
|
||||
console.warn(
|
||||
"Failed to load language manifest, falling back to default languages",
|
||||
);
|
||||
}
|
||||
|
||||
// Fallback to default languages if manifest loading fails
|
||||
return ['en'];
|
||||
return ["en"];
|
||||
};
|
||||
|
||||
// Use the browser language from the HTML lang attribute which is set by the server settings or request headers
|
||||
const getBrowserLanguage = async () =>
|
||||
document.documentElement.lang;
|
||||
const getBrowserLanguage = async () => document.documentElement.lang;
|
||||
|
||||
// Load translations from JSON files
|
||||
const loadTranslations = async (lang) => {
|
||||
@@ -54,12 +57,16 @@ const loadTranslations = async (lang) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${basePrefix}/.within.website/x/cmd/anubis/static/locales/${lang}.json`);
|
||||
const response = await fetch(
|
||||
`${basePrefix}/.within.website/x/cmd/anubis/static/locales/${lang}.json`,
|
||||
);
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.warn(`Failed to load translations for ${lang}, falling back to English`);
|
||||
if (lang !== 'en') {
|
||||
return await loadTranslations('en');
|
||||
console.warn(
|
||||
`Failed to load translations for ${lang}, falling back to English`,
|
||||
);
|
||||
if (lang !== "en") {
|
||||
return await loadTranslations("en");
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
@@ -72,10 +79,10 @@ const getRedirectUrl = () => {
|
||||
}
|
||||
if (publicUrl && window.location.href.startsWith(publicUrl)) {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
return urlParams.get('redir');
|
||||
return urlParams.get("redir");
|
||||
}
|
||||
return window.location.href;
|
||||
}
|
||||
};
|
||||
|
||||
let translations = {};
|
||||
let currentLang;
|
||||
@@ -95,20 +102,28 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key;
|
||||
const dependencies = [
|
||||
{
|
||||
name: "Web Workers",
|
||||
msg: t('web_workers_error'),
|
||||
msg: t("web_workers_error"),
|
||||
value: window.Worker,
|
||||
},
|
||||
{
|
||||
name: "Cookies",
|
||||
msg: t('cookies_error'),
|
||||
msg: t("cookies_error"),
|
||||
value: navigator.cookieEnabled,
|
||||
},
|
||||
];
|
||||
|
||||
const status: HTMLParagraphElement = document.getElementById("status") as HTMLParagraphElement;
|
||||
const image: HTMLImageElement = document.getElementById("image") as HTMLImageElement;
|
||||
const title: HTMLHeadingElement = document.getElementById("title") as HTMLHeadingElement;
|
||||
const progress: HTMLDivElement = document.getElementById("progress") as HTMLDivElement;
|
||||
const status: HTMLParagraphElement = document.getElementById(
|
||||
"status",
|
||||
) as HTMLParagraphElement;
|
||||
const image: HTMLImageElement = document.getElementById(
|
||||
"image",
|
||||
) as HTMLImageElement;
|
||||
const title: HTMLHeadingElement = document.getElementById(
|
||||
"title",
|
||||
) as HTMLHeadingElement;
|
||||
const progress: HTMLDivElement = document.getElementById(
|
||||
"progress",
|
||||
) as HTMLDivElement;
|
||||
|
||||
const anubisVersion = j("anubis_version");
|
||||
const basePrefix = j("anubis_base_prefix");
|
||||
@@ -130,12 +145,12 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key;
|
||||
progress.style.display = "none";
|
||||
};
|
||||
|
||||
status.innerHTML = t('calculating');
|
||||
status.innerHTML = t("calculating");
|
||||
|
||||
for (const { value, name, msg } of dependencies) {
|
||||
if (!value) {
|
||||
ohNoes({
|
||||
titleMsg: `${t('missing_feature')} ${name}`,
|
||||
titleMsg: `${t("missing_feature")} ${name}`,
|
||||
statusMsg: msg,
|
||||
imageSrc: imageURL("reject", anubisVersion, basePrefix),
|
||||
});
|
||||
@@ -148,20 +163,20 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key;
|
||||
const process = algorithms[rules.algorithm];
|
||||
if (!process) {
|
||||
ohNoes({
|
||||
titleMsg: t('challenge_error'),
|
||||
statusMsg: t('challenge_error_msg'),
|
||||
titleMsg: t("challenge_error"),
|
||||
statusMsg: t("challenge_error_msg"),
|
||||
imageSrc: imageURL("reject", anubisVersion, basePrefix),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
status.innerHTML = `${t('calculating_difficulty')} ${rules.difficulty}, `;
|
||||
status.innerHTML = `${t("calculating_difficulty")} ${rules.difficulty}, `;
|
||||
progress.style.display = "inline-block";
|
||||
|
||||
// the whole text, including "Speed:", as a single node, because some browsers
|
||||
// (Firefox mobile) present screen readers with each node as a separate piece
|
||||
// of text.
|
||||
const rateText = document.createTextNode(`${t('speed')} 0kH/s`);
|
||||
const rateText = document.createTextNode(`${t("speed")} 0kH/s`);
|
||||
status.appendChild(rateText);
|
||||
|
||||
let lastSpeedUpdate = 0;
|
||||
@@ -180,7 +195,7 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key;
|
||||
// only update the speed every second so it's less visually distracting
|
||||
if (delta - lastSpeedUpdate > 1000) {
|
||||
lastSpeedUpdate = delta;
|
||||
rateText.data = `${t('speed')} ${(iters / delta).toFixed(3)}kH/s`;
|
||||
rateText.data = `${t("speed")} ${(iters / delta).toFixed(3)}kH/s`;
|
||||
}
|
||||
// the probability of still being on the page is (1 - likelihood) ^ iters.
|
||||
// by definition, half of the time the progress bar only gets to half, so
|
||||
@@ -192,13 +207,14 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key;
|
||||
const distance = (1 - Math.pow(probability, 2)) * 100;
|
||||
progress["aria-valuenow"] = distance;
|
||||
if (progress.firstElementChild !== null) {
|
||||
(progress.firstElementChild as HTMLElement).style.width = `${distance}%`;
|
||||
(progress.firstElementChild as HTMLElement).style.width =
|
||||
`${distance}%`;
|
||||
}
|
||||
|
||||
if (probability < 0.1 && !showingApology) {
|
||||
status.append(
|
||||
document.createElement("br"),
|
||||
document.createTextNode(t('verification_longer')),
|
||||
document.createTextNode(t("verification_longer")),
|
||||
);
|
||||
showingApology = true;
|
||||
}
|
||||
@@ -208,7 +224,9 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key;
|
||||
console.log({ hash, nonce });
|
||||
|
||||
if (userReadDetails) {
|
||||
const container: HTMLDivElement = document.getElementById("progress") as HTMLDivElement;
|
||||
const container: HTMLDivElement = document.getElementById(
|
||||
"progress",
|
||||
) as HTMLDivElement;
|
||||
|
||||
// Style progress bar as a continue button
|
||||
container.style.display = "flex";
|
||||
@@ -224,7 +242,7 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key;
|
||||
container.style.outlineOffset = "2px";
|
||||
container.style.width = "min(20rem, 90%)";
|
||||
container.style.margin = "1rem auto 2rem";
|
||||
container.innerHTML = t('finished_reading');
|
||||
container.innerHTML = t("finished_reading");
|
||||
|
||||
function onDetailsExpand() {
|
||||
const redir = getRedirectUrl();
|
||||
@@ -255,8 +273,8 @@ const t = (key) => translations[`js_${key}`] || translations[key] || key;
|
||||
}
|
||||
} catch (err) {
|
||||
ohNoes({
|
||||
titleMsg: t('calculation_error'),
|
||||
statusMsg: `${t('calculation_error_msg')} ${err.message}`,
|
||||
titleMsg: t("calculation_error"),
|
||||
statusMsg: `${t("calculation_error_msg")} ${err.message}`,
|
||||
imageSrc: imageURL("reject", anubisVersion, basePrefix),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Sha256 } from '@aws-crypto/sha256-js';
|
||||
import { Sha256 } from "@aws-crypto/sha256-js";
|
||||
|
||||
const calculateSHA256 = (text) => {
|
||||
const hash = new Sha256();
|
||||
@@ -12,7 +12,7 @@ function toHexString(arr: Uint8Array): string {
|
||||
.join("");
|
||||
}
|
||||
|
||||
addEventListener('message', async ({ data: eventData }) => {
|
||||
addEventListener("message", async ({ data: eventData }) => {
|
||||
const { data, difficulty, threads } = eventData;
|
||||
let nonce = eventData.nonce;
|
||||
const isMainThread = nonce === 0;
|
||||
@@ -21,7 +21,7 @@ addEventListener('message', async ({ data: eventData }) => {
|
||||
const requiredZeroBytes = Math.floor(difficulty / 2);
|
||||
const isDifficultyOdd = difficulty % 2 !== 0;
|
||||
|
||||
for (; ;) {
|
||||
for (;;) {
|
||||
const hashBuffer = await calculateSHA256(data + nonce);
|
||||
const hashArray = new Uint8Array(hashBuffer);
|
||||
|
||||
@@ -34,7 +34,7 @@ addEventListener('message', async ({ data: eventData }) => {
|
||||
}
|
||||
|
||||
if (isValid && isDifficultyOdd) {
|
||||
if ((hashArray[requiredZeroBytes] >> 4) !== 0) {
|
||||
if (hashArray[requiredZeroBytes] >> 4 !== 0) {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ addEventListener('message', async ({ data: eventData }) => {
|
||||
|
||||
/* Truncate the decimal portion of the nonce. This is a bit of an evil bit
|
||||
* hack, but it works reliably enough. The core of why this works is:
|
||||
*
|
||||
*
|
||||
* > 13.4 % 1 !== 0
|
||||
* true
|
||||
* > 13 % 1 !== 0
|
||||
@@ -70,4 +70,4 @@ addEventListener('message', async ({ data: eventData }) => {
|
||||
postMessage(nonce);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -6,7 +6,10 @@ const calculateSHA256 = async (input: string) => {
|
||||
};
|
||||
|
||||
const toHexString = (byteArray: Uint8Array) => {
|
||||
return byteArray.reduce((str, byte) => str + byte.toString(16).padStart(2, "0"), "");
|
||||
return byteArray.reduce(
|
||||
(str, byte) => str + byte.toString(16).padStart(2, "0"),
|
||||
"",
|
||||
);
|
||||
};
|
||||
|
||||
addEventListener("message", async ({ data: eventData }) => {
|
||||
@@ -18,7 +21,7 @@ addEventListener("message", async ({ data: eventData }) => {
|
||||
const requiredZeroBytes = Math.floor(difficulty / 2);
|
||||
const isDifficultyOdd = difficulty % 2 !== 0;
|
||||
|
||||
for (; ;) {
|
||||
for (;;) {
|
||||
const hashBuffer = await calculateSHA256(data + nonce);
|
||||
const hashArray = new Uint8Array(hashBuffer);
|
||||
|
||||
@@ -31,7 +34,7 @@ addEventListener("message", async ({ data: eventData }) => {
|
||||
}
|
||||
|
||||
if (isValid && isDifficultyOdd) {
|
||||
if ((hashArray[requiredZeroBytes] >> 4) !== 0) {
|
||||
if (hashArray[requiredZeroBytes] >> 4 !== 0) {
|
||||
isValid = false;
|
||||
}
|
||||
}
|
||||
@@ -52,7 +55,7 @@ addEventListener("message", async ({ data: eventData }) => {
|
||||
|
||||
/* Truncate the decimal portion of the nonce. This is a bit of an evil bit
|
||||
* hack, but it works reliably enough. The core of why this works is:
|
||||
*
|
||||
*
|
||||
* > 13.4 % 1 !== 0
|
||||
* true
|
||||
* > 13 % 1 !== 0
|
||||
@@ -67,4 +70,4 @@ addEventListener("message", async ({ data: eventData }) => {
|
||||
postMessage(nonce);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user