mirror of
https://github.com/TecharoHQ/anubis.git
synced 2025-08-03 09:48:08 -04:00
web/js: Added a wait with button continue + 30 second auto continue after 30s if you click "Why am I seeing this? (#166)
* web/js: update page to allow users to read the "Why am I seeing this?", complete with a button to send them through after challenge completed, and a 30s timeout that does the same. * .gitignore: added .DS_store. * docs/docs/CHANGELOG: added to the Unreleased section as requested in code quality guidelines * web: pushing index_templ.go alongside this update. * package.json: added postcss to dependencies list. * package-lock: added postcss to dependencies * Revert "package-lock: added postcss to dependencies" This reverts commit bf02e7ba56e8bf8705821d4f4864c66b1ef614bf. * Revert "package.json: added postcss to dependencies list." This reverts commit 1a38c63049dc75099dc652ed725c7862eef4b3e4. * web/js: OG comments are important --------- Signed-off-by: Xe Iaso <me@xeiaso.net> Co-authored-by: Xe Iaso <me@xeiaso.net>
This commit is contained in:
parent
feca1ddeea
commit
28828a2e93
5
.gitignore
vendored
5
.gitignore
vendored
@ -6,4 +6,7 @@
|
|||||||
main
|
main
|
||||||
*.test
|
*.test
|
||||||
|
|
||||||
node_modules
|
node_modules
|
||||||
|
|
||||||
|
# MacOS
|
||||||
|
.DS_store
|
@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Use `TrimSuffix` instead of `TrimRight` on containerbuild
|
- Use `TrimSuffix` instead of `TrimRight` on containerbuild
|
||||||
- Fix the startup logs to correctly show the address and port the server is listening on
|
- Fix the startup logs to correctly show the address and port the server is listening on
|
||||||
- Add [LibreJS](https://www.gnu.org/software/librejs/) banner to Anubis JavaScript to allow LibreJS users to run the challenge
|
- Add [LibreJS](https://www.gnu.org/software/librejs/) banner to Anubis JavaScript to allow LibreJS users to run the challenge
|
||||||
|
- Added a wait with button continue + 30 second auto continue after 30s if you click "Why am I seeing this?"
|
||||||
- Fixed a typo in the challenge page title.
|
- Fixed a typo in the challenge page title.
|
||||||
- Disabled running integration tests on Windows hosts due to it's reliance on posix features (see [#133](https://github.com/TecharoHQ/anubis/pull/133#issuecomment-2764732309)).
|
- Disabled running integration tests on Windows hosts due to it's reliance on posix features (see [#133](https://github.com/TecharoHQ/anubis/pull/133#issuecomment-2764732309)).
|
||||||
|
|
||||||
|
4
web/index_templ.go
generated
4
web/index_templ.go
generated
@ -251,7 +251,7 @@ func bench() templ.Component {
|
|||||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs("/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" +
|
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs("/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" +
|
||||||
anubis.Version)
|
anubis.Version)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 247, Col: 19}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 148, Col: 19}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@ -264,7 +264,7 @@ func bench() templ.Component {
|
|||||||
var templ_7745c5c3_Var14 string
|
var templ_7745c5c3_Var14 string
|
||||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs("/.within.website/x/cmd/anubis/static/js/bench.mjs?cacheBuster=" + anubis.Version)
|
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs("/.within.website/x/cmd/anubis/static/js/bench.mjs?cacheBuster=" + anubis.Version)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 250, Col: 118}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 151, Col: 118}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
|
138
web/js/main.mjs
138
web/js/main.mjs
@ -10,10 +10,7 @@ const algorithms = {
|
|||||||
// from Xeact
|
// from Xeact
|
||||||
const u = (url = "", params = {}) => {
|
const u = (url = "", params = {}) => {
|
||||||
let result = new URL(url, window.location.href);
|
let result = new URL(url, window.location.href);
|
||||||
Object.entries(params).forEach((kv) => {
|
Object.entries(params).forEach(([k, v]) => result.searchParams.set(k, v));
|
||||||
let [k, v] = kv;
|
|
||||||
result.searchParams.set(k, v);
|
|
||||||
});
|
|
||||||
return result.toString();
|
return result.toString();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -33,16 +30,69 @@ const dependencies = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
function showContinueBar(hash, nonce, t0, t1) {
|
||||||
|
const barContainer = document.createElement("div");
|
||||||
|
barContainer.style.marginTop = "1rem";
|
||||||
|
barContainer.style.width = "100%";
|
||||||
|
barContainer.style.maxWidth = "32rem";
|
||||||
|
barContainer.style.background = "#3c3836";
|
||||||
|
barContainer.style.borderRadius = "4px";
|
||||||
|
barContainer.style.overflow = "hidden";
|
||||||
|
barContainer.style.cursor = "pointer";
|
||||||
|
barContainer.style.height = "2rem";
|
||||||
|
barContainer.style.marginLeft = "auto";
|
||||||
|
barContainer.style.marginRight = "auto";
|
||||||
|
barContainer.title = "Click to continue";
|
||||||
|
|
||||||
|
const barInner = document.createElement("div");
|
||||||
|
barInner.className = "bar-inner";
|
||||||
|
barInner.style.display = "flex";
|
||||||
|
barInner.style.alignItems = "center";
|
||||||
|
barInner.style.justifyContent = "center";
|
||||||
|
barInner.style.color = "white";
|
||||||
|
barInner.style.fontWeight = "bold";
|
||||||
|
barInner.style.height = "100%";
|
||||||
|
barInner.style.width = "0";
|
||||||
|
barInner.innerText = "I've finished reading, continue →";
|
||||||
|
|
||||||
|
barContainer.appendChild(barInner);
|
||||||
|
document.body.appendChild(barContainer);
|
||||||
|
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
barInner.style.width = "100%";
|
||||||
|
});
|
||||||
|
|
||||||
|
barContainer.onclick = () => {
|
||||||
|
const redir = window.location.href;
|
||||||
|
window.location.replace(
|
||||||
|
u("/.within.website/x/cmd/anubis/api/pass-challenge", {
|
||||||
|
response: hash,
|
||||||
|
nonce,
|
||||||
|
redir,
|
||||||
|
elapsedTime: t1 - t0
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const status = document.getElementById('status');
|
const status = document.getElementById('status');
|
||||||
const image = document.getElementById('image');
|
const image = document.getElementById('image');
|
||||||
const title = document.getElementById('title');
|
const title = document.getElementById('title');
|
||||||
const progress = document.getElementById('progress');
|
const progress = document.getElementById('progress');
|
||||||
const anubisVersion = JSON.parse(document.getElementById('anubis_version').textContent);
|
const anubisVersion = JSON.parse(document.getElementById('anubis_version').textContent);
|
||||||
|
const details = document.querySelector('details');
|
||||||
|
let userReadDetails = false;
|
||||||
|
|
||||||
const ohNoes = ({
|
if (details) {
|
||||||
titleMsg, statusMsg, imageSrc,
|
details.addEventListener("toggle", () => {
|
||||||
}) => {
|
if (details.open) {
|
||||||
|
userReadDetails = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const ohNoes = ({ titleMsg, statusMsg, imageSrc }) => {
|
||||||
title.innerHTML = titleMsg;
|
title.innerHTML = titleMsg;
|
||||||
status.innerHTML = statusMsg;
|
status.innerHTML = statusMsg;
|
||||||
image.src = imageSrc;
|
image.src = imageSrc;
|
||||||
@ -73,22 +123,19 @@ const dependencies = [
|
|||||||
|
|
||||||
status.innerHTML = 'Calculating...';
|
status.innerHTML = 'Calculating...';
|
||||||
|
|
||||||
for (const val of dependencies) {
|
for (const { value, name, msg } of dependencies) {
|
||||||
const { value, name, msg } = val;
|
|
||||||
if (!value) {
|
if (!value) {
|
||||||
ohNoes({
|
ohNoes({
|
||||||
titleMsg: `Missing feature ${name}`,
|
titleMsg: `Missing feature ${name}`,
|
||||||
statusMsg: msg,
|
statusMsg: msg,
|
||||||
imageSrc: imageURL("sad", anubisVersion),
|
imageSrc: imageURL("sad", anubisVersion),
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const { challenge, rules } = await fetch("/.within.website/x/cmd/anubis/api/make-challenge", { method: "POST" })
|
const { challenge, rules } = await fetch("/.within.website/x/cmd/anubis/api/make-challenge", { method: "POST" })
|
||||||
.then(r => {
|
.then(r => {
|
||||||
if (!r.ok) {
|
if (!r.ok) throw new Error("Failed to fetch config");
|
||||||
throw new Error("Failed to fetch config");
|
|
||||||
}
|
|
||||||
return r.json();
|
return r.json();
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
@ -112,7 +159,7 @@ const dependencies = [
|
|||||||
|
|
||||||
status.innerHTML = `Calculating...<br/>Difficulty: ${rules.report_as}, `;
|
status.innerHTML = `Calculating...<br/>Difficulty: ${rules.report_as}, `;
|
||||||
progress.style.display = "inline-block";
|
progress.style.display = "inline-block";
|
||||||
|
|
||||||
// the whole text, including "Speed:", as a single node, because some browsers
|
// the whole text, including "Speed:", as a single node, because some browsers
|
||||||
// (Firefox mobile) present screen readers with each node as a separate piece
|
// (Firefox mobile) present screen readers with each node as a separate piece
|
||||||
// of text.
|
// of text.
|
||||||
@ -122,6 +169,7 @@ const dependencies = [
|
|||||||
let lastSpeedUpdate = 0;
|
let lastSpeedUpdate = 0;
|
||||||
let showingApology = false;
|
let showingApology = false;
|
||||||
const likelihood = Math.pow(16, -rules.report_as);
|
const likelihood = Math.pow(16, -rules.report_as);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const t0 = Date.now();
|
const t0 = Date.now();
|
||||||
const { hash, nonce } = await process(
|
const { hash, nonce } = await process(
|
||||||
@ -135,12 +183,12 @@ const dependencies = [
|
|||||||
lastSpeedUpdate = delta;
|
lastSpeedUpdate = delta;
|
||||||
rateText.data = `Speed: ${(iters / delta).toFixed(3)}kH/s`;
|
rateText.data = `Speed: ${(iters / delta).toFixed(3)}kH/s`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the probability of still being on the page is (1 - likelihood) ^ iters.
|
// 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
|
// by definition, half of the time the progress bar only gets to half, so
|
||||||
// apply a polynomial ease-out function to move faster in the beginning
|
// apply a polynomial ease-out function to move faster in the beginning
|
||||||
// and then slow down as things get increasingly unlikely. quadratic felt
|
// and then slow down as things get increasingly unlikely. quadratic felt
|
||||||
// the best in testing, but this may need adjustment in the future.
|
// the best in testing, but this may need adjustment in the future.
|
||||||
|
|
||||||
const probability = Math.pow(1 - likelihood, iters);
|
const probability = Math.pow(1 - likelihood, iters);
|
||||||
const distance = (1 - Math.pow(probability, 2)) * 100;
|
const distance = (1 - Math.pow(probability, 2)) * 100;
|
||||||
progress["aria-valuenow"] = distance;
|
progress["aria-valuenow"] = distance;
|
||||||
@ -165,18 +213,54 @@ const dependencies = [
|
|||||||
image.src = imageURL("happy", anubisVersion);
|
image.src = imageURL("happy", anubisVersion);
|
||||||
progress.style.display = "none";
|
progress.style.display = "none";
|
||||||
|
|
||||||
setTimeout(() => {
|
if (userReadDetails) {
|
||||||
const redir = window.location.href;
|
const container = document.getElementById("progress");
|
||||||
|
|
||||||
window.location.replace(
|
// Style progress bar as a continue button
|
||||||
u("/.within.website/x/cmd/anubis/api/pass-challenge", {
|
container.style.display = "flex";
|
||||||
response: hash,
|
container.style.alignItems = "center";
|
||||||
nonce,
|
container.style.justifyContent = "center";
|
||||||
redir,
|
container.style.height = "2rem";
|
||||||
elapsedTime: t1 - t0
|
container.style.borderRadius = "1rem";
|
||||||
}),
|
container.style.cursor = "pointer";
|
||||||
);
|
container.style.background = "#b16286";
|
||||||
}, 250);
|
container.style.color = "white";
|
||||||
|
container.style.fontWeight = "bold";
|
||||||
|
container.style.outline = "4px solid #b16286";
|
||||||
|
container.style.outlineOffset = "2px";
|
||||||
|
container.style.width = "min(20rem, 90%)";
|
||||||
|
container.style.margin = "1rem auto 2rem";
|
||||||
|
container.innerHTML = "I've finished reading, continue →";
|
||||||
|
|
||||||
|
function onDetailsExpand() {
|
||||||
|
const redir = window.location.href;
|
||||||
|
window.location.replace(
|
||||||
|
u("/.within.website/x/cmd/anubis/api/pass-challenge", {
|
||||||
|
response: hash,
|
||||||
|
nonce,
|
||||||
|
redir,
|
||||||
|
elapsedTime: t1 - t0
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
container.onclick = onDetailsExpand;
|
||||||
|
setTimeout(onDetailsExpand, 30000);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
setTimeout(() => {
|
||||||
|
const redir = window.location.href;
|
||||||
|
window.location.replace(
|
||||||
|
u("/.within.website/x/cmd/anubis/api/pass-challenge", {
|
||||||
|
response: hash,
|
||||||
|
nonce,
|
||||||
|
redir,
|
||||||
|
elapsedTime: t1 - t0
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}, 250);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
ohNoes({
|
ohNoes({
|
||||||
titleMsg: "Calculation error!",
|
titleMsg: "Calculation error!",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Code generated by templ - DO NOT EDIT.
|
// Code generated by templ - DO NOT EDIT.
|
||||||
|
|
||||||
// templ: version: v0.3.857
|
// templ: version: v0.3.833
|
||||||
package xess
|
package xess
|
||||||
|
|
||||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user