فهرست منبع

web/js: show more errors when some probable error cases happen (#151)

Closes #150

This should hopefully make Anubis more self-describing when errors do
happen so users can self-service.
Xe Iaso 2 ماه پیش
والد
کامیت
6b2ae30bae
7فایلهای تغییر یافته به همراه97 افزوده شده و 32 حذف شده
  1. 1 0
      docs/docs/CHANGELOG.md
  2. 3 3
      package.json
  3. 6 1
      web/index.templ
  4. 0 0
      web/index_templ.go
  5. 86 26
      web/js/main.mjs
  6. 0 1
      xess/xess.go
  7. 1 1
      xess/xess_templ.go

+ 1 - 0
docs/docs/CHANGELOG.md

@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Static asset builds are now done on demand instead of the results being committed to source control
 - Static asset builds are now done on demand instead of the results being committed to source control
 - The Dockerfile has been removed as it is no longer in use
 - The Dockerfile has been removed as it is no longer in use
 - Developer documentation has been added to the docs site
 - Developer documentation has been added to the docs site
+- Show more errors when some predictable challenge page errors happen ([#150](https://github.com/TecharoHQ/anubis/issues/150))
 
 
 ## v1.15.0
 ## v1.15.0
 
 

+ 3 - 3
package.json

@@ -5,9 +5,9 @@
   "main": "index.js",
   "main": "index.js",
   "scripts": {
   "scripts": {
     "test": "npm run assets && go test ./...",
     "test": "npm run assets && go test ./...",
-    "test:integration": "npm run assets && go test ./internal/test",
-    "assets": "./web/build.sh && ./xess/build.sh",
-    "dev": "npm run assets && go run ./cmd/anubis",
+    "test:integration": "npm run assets && go test -v ./internal/test",
+    "assets": "go generate ./... && ./web/build.sh && ./xess/build.sh",
+    "dev": "npm run assets && go run ./cmd/anubis --use-remote-address",
     "container": "npm run assets && go run ./cmd/containerbuild"
     "container": "npm run assets && go run ./cmd/containerbuild"
   },
   },
   "author": "",
   "author": "",

+ 6 - 1
web/index.templ

@@ -128,6 +128,11 @@ templ base(title string, body templ.Component) {
       left: 12.28719px;
       left: 12.28719px;
     }
     }
 
 
+    .mx-auto {
+      margin-left: auto;
+      margin-right: auto;
+    }
+
     @keyframes lds-roller {
     @keyframes lds-roller {
       0% {
       0% {
         transform: rotate(0deg);
         transform: rotate(0deg);
@@ -176,7 +181,7 @@ templ index() {
 		/>
 		/>
 		<p id="status">Loading...</p>
 		<p id="status">Loading...</p>
 		<script async type="module" src={ "/.within.website/x/cmd/anubis/static/js/main.mjs?cacheBuster=" + anubis.Version }></script>
 		<script async type="module" src={ "/.within.website/x/cmd/anubis/static/js/main.mjs?cacheBuster=" + anubis.Version }></script>
-		<div id="spinner" class="lds-roller">
+		<div id="spinner" class="lds-roller mx-auto" style="display:none;">
 			<div></div>
 			<div></div>
 			<div></div>
 			<div></div>
 			<div></div>
 			<div></div>

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
web/index_templ.go


+ 86 - 26
web/js/main.mjs

@@ -5,7 +5,7 @@ import { testVideo } from "./video.mjs";
 const algorithms = {
 const algorithms = {
   "fast": processFast,
   "fast": processFast,
   "slow": processSlow,
   "slow": processSlow,
-}
+};
 
 
 // from Xeact
 // from Xeact
 const u = (url = "", params = {}) => {
 const u = (url = "", params = {}) => {
@@ -20,6 +20,19 @@ const u = (url = "", params = {}) => {
 const imageURL = (mood, cacheBuster) =>
 const imageURL = (mood, cacheBuster) =>
   u(`/.within.website/x/cmd/anubis/static/img/${mood}.webp`, { cacheBuster });
   u(`/.within.website/x/cmd/anubis/static/img/${mood}.webp`, { cacheBuster });
 
 
+const dependencies = [
+  {
+    name: "WebCrypto",
+    msg: "Your browser doesn't have a functioning web.crypto element. Are you viewing this over a secure context?",
+    value: window.crypto,
+  },
+  {
+    name: "Web Workers",
+    msg: "Your browser doesn't support web workers (Anubis uses this to avoid freezing your browser). Do you have a plugin like JShelter installed?",
+    value: window.Worker,
+  },
+];
+
 (async () => {
 (async () => {
   const status = document.getElementById('status');
   const status = document.getElementById('status');
   const image = document.getElementById('image');
   const image = document.getElementById('image');
@@ -27,6 +40,25 @@ const imageURL = (mood, cacheBuster) =>
   const spinner = document.getElementById('spinner');
   const spinner = document.getElementById('spinner');
   const anubisVersion = JSON.parse(document.getElementById('anubis_version').textContent);
   const anubisVersion = JSON.parse(document.getElementById('anubis_version').textContent);
 
 
+  const ohNoes = ({
+    titleMsg, statusMsg, imageSrc,
+  }) => {
+    title.innerHTML = titleMsg;
+    status.innerHTML = statusMsg;
+    image.src = imageSrc;
+    spinner.innerHTML = "";
+    spinner.style.display = "none";
+  };
+
+  if (!window.isSecureContext) {
+    ohNoes({
+      titleMsg: "Your context is not secure!",
+      statusMsg: `Try connecting over HTTPS or let the admin know to set up HTTPS. For more information, see <a href="https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts#when_is_a_context_considered_secure">MDN</a>.`,
+      imageSrc: imageURL("sad", anubisVersion),
+    });
+    return;
+  }
+
   // const testarea = document.getElementById('testarea');
   // const testarea = document.getElementById('testarea');
 
 
   // const videoWorks = await testVideo(testarea);
   // const videoWorks = await testVideo(testarea);
@@ -43,6 +75,17 @@ const imageURL = (mood, cacheBuster) =>
 
 
   status.innerHTML = 'Calculating...';
   status.innerHTML = 'Calculating...';
 
 
+  for (const val of dependencies) {
+    const { value, name, msg } = val;
+    if (!value) {
+      ohNoes({
+        titleMsg: `Missing feature ${name}`,
+        statusMsg: msg,
+        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) {
@@ -51,39 +94,56 @@ const imageURL = (mood, cacheBuster) =>
       return r.json();
       return r.json();
     })
     })
     .catch(err => {
     .catch(err => {
-      title.innerHTML = "Oh no!";
-      status.innerHTML = `Failed to fetch config: ${err.message}`;
-      image.src = imageURL("sad", anubisVersion);
-      spinner.innerHTML = "";
-      spinner.style.display = "none";
+      ohNoes({
+        titleMsg: "Internal error!",
+        statusMsg: `Failed to fetch challenge config: ${err.message}`,
+        imageSrc: imageURL("sad", anubisVersion),
+      });
       throw err;
       throw err;
     });
     });
 
 
   const process = algorithms[rules.algorithm];
   const process = algorithms[rules.algorithm];
   if (!process) {
   if (!process) {
-    title.innerHTML = "Oh no!";
-    status.innerHTML = `Failed to resolve check algorithm. You may want to reload the page.`;
-    image.src = imageURL("sad", anubisVersion);
-    spinner.innerHTML = "";
-    spinner.style.display = "none";
+    ohNoes({
+      titleMsg: "Challenge error!",
+      statusMsg: `Failed to resolve check algorithm. You may want to reload the page.`,
+      imageSrc: imageURL("sad", anubisVersion),
+    });
     return;
     return;
   }
   }
 
 
   status.innerHTML = `Calculating...<br/>Difficulty: ${rules.report_as}`;
   status.innerHTML = `Calculating...<br/>Difficulty: ${rules.report_as}`;
+  spinner.style.display = "block";
+
+  try {
+    const t0 = Date.now();
+    const { hash, nonce } = await process(challenge, rules.difficulty);
+    const t1 = Date.now();
+    console.log({ hash, nonce });
+
+    title.innerHTML = "Success!";
+    status.innerHTML = `Done! Took ${t1 - t0}ms, ${nonce} iterations`;
+    image.src = imageURL("happy", anubisVersion);
+    spinner.innerHTML = "";
+    spinner.style.display = "none";
+
+    setTimeout(() => {
+      const redir = window.location.href;
 
 
-  const t0 = Date.now();
-  const { hash, nonce } = await process(challenge, rules.difficulty);
-  const t1 = Date.now();
-  console.log({ hash, nonce });
-
-  title.innerHTML = "Success!";
-  status.innerHTML = `Done! Took ${t1 - t0}ms, ${nonce} iterations`;
-  image.src = imageURL("happy", anubisVersion);
-  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 });
-  }, 250);
+      window.location.replace(
+        u("/.within.website/x/cmd/anubis/api/pass-challenge", {
+          response: hash,
+          nonce,
+          redir,
+          elapsedTime: t1 - t0
+        }),
+      );
+    }, 250);
+  } catch (err) {
+    ohNoes({
+      titleMsg: "Calculation error!",
+      statusMsg: `Failed to calculate challenge: ${err.message}`,
+      imageSrc: imageURL("sad", anubisVersion),
+    });
+  }
 })();
 })();

+ 0 - 1
xess/xess.go

@@ -13,7 +13,6 @@ import (
 )
 )
 
 
 //go:generate go run github.com/a-h/templ/cmd/templ@latest generate
 //go:generate go run github.com/a-h/templ/cmd/templ@latest generate
-//go:generate npm run build
 
 
 var (
 var (
 	//go:embed *.css static
 	//go:embed *.css static

+ 1 - 1
xess/xess_templ.go

@@ -1,6 +1,6 @@
 // Code generated by templ - DO NOT EDIT.
 // Code generated by templ - DO NOT EDIT.
 
 
-// templ: version: v0.3.850
+// templ: version: v0.3.857
 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.

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است