Browse Source

Add initial rule reader

ghorsington 3 years ago
parent
commit
8893d26828

+ 2 - 0
docker-compose.yml

@@ -11,6 +11,7 @@ services:
       - db
       - facedetect
     env_file:
+      - .env
       - db.env
     volumes: 
       - ./bot/stickers:/app/bot/stickers
@@ -43,6 +44,7 @@ services:
       - db
       - noctbot
     env_file:
+      - .env
       - db.env
     environment:
       NODE_ENV: production

+ 3 - 0
web/package.json

@@ -41,9 +41,11 @@
 		"pg": "^8.3.3",
 		"postcss-nested": "^4.2.3",
 		"rpc_ts": "^2.1.0",
+		"showdown": "^1.9.1",
 		"sirv": "^1.0.5",
 		"svelte-awesome": "^2.3.0",
 		"typeorm": "^0.2.25",
+		"vanilla-hcaptcha": "0.0.5",
 		"winston": "^3.3.3",
 		"winston-transport": "^4.4.0"
 	},
@@ -67,6 +69,7 @@
 		"@types/express": "^4.17.7",
 		"@types/node-fetch": "^2.5.7",
 		"@types/nodemailer": "^6.4.0",
+		"@types/showdown": "^1.9.3",
 		"@typescript-eslint/eslint-plugin": "^3.10.1",
 		"@typescript-eslint/parser": "^3.10.1",
 		"autoprefixer": "^9.8.6",

+ 1 - 0
web/src/client.ts

@@ -1,5 +1,6 @@
 // eslint-disable-next-line import/no-unresolved
 import * as sapper from "@sapper/app";
+import "vanilla-hcaptcha";
 
 sapper.start({
     target: document.querySelector("#sapper"),

+ 2 - 2
web/src/routes/_layout.svelte

@@ -21,9 +21,9 @@
     if (path != "/" && !result.loggedIn) {
       return this.redirect(302, "/");
     }
-    if (result.loggedIn && !path.startsWith("/rules/")) {
+    if (result.loggedIn && !path.startsWith("/rules")) {
       if (result.moderator) {
-        return this.redirect(302, "/rules/create");
+        return this.redirect(302, "/rules/edit");
       }
       return this.redirect(302, "/rules");
     }

+ 4 - 0
web/src/routes/login/discord_auth.svelte

@@ -24,6 +24,10 @@
   });
 </script>
 
+<svelte:head>
+    <title>Logging in</title>
+</svelte:head>
+
 <div class="bg-gray-800 rounded-sm text-center px-20 py-5 shadow-lg">
   <h1 class="text-white text-4xl font-light">Logging in</h1>
   {#if ok}

web/src/routes/rules/create.svelte → web/src/routes/rules/edit.svelte


+ 84 - 1
web/src/routes/rules/index.svelte

@@ -1,2 +1,85 @@
+<script lang="typescript" context="module">
+  import type { AppSession, PageData, PreloadContext } from "src/utils/session";
+  import type { Option } from "@shared/common/async_utils";
+  import type { MDText } from "./md";
+  import type { VerifyInfo } from "./verify";
 
-<div>wew</div>
+  export async function preload(
+    this: PreloadContext,
+    { path }: PageData,
+    session: AppSession
+  ) {
+    const mdResult = await this.fetch("/rules/md");
+    const md = (await mdResult.json()) as Option<MDText, { error: string }>;
+
+    const verifyReusult = await this.fetch("/rules/verify");
+    const verify = (await verifyReusult.json()) as VerifyInfo;
+    return {
+      rulesText: md.ok ? md.text : "",
+      sitekey: verify.captchaSitekey,
+    };
+  }
+</script>
+
+<script lang="typescript">
+  import { Converter } from "showdown";
+  import { onMount } from "svelte";
+  import Icon from "svelte-awesome/components/Icon.svelte";
+  import { faSpinner } from "@fortawesome/free-solid-svg-icons";
+  import { fade } from "svelte/transition";
+
+  export let rulesText!: string;
+  export let sitekey!: string;
+  const spinner = (faSpinner as unknown) as undefined;
+  let htmlContent = new Converter().makeHtml(rulesText);
+
+  enum State { None, Verify, Error, Message };
+
+  let state: State = State.None;
+  let message: string = "";
+  function onVerified(e: { key: string }) {
+    // console.log(e.key);
+    state = State.Verify;
+    // message = "wew";
+  }
+</script>
+
+<style>
+  @import "./markdown-dark.css";
+
+  .viewport {
+    @apply bg-gray-700 h-screen w-screen p-8 pt-16;
+    overflow-y: auto;
+  }
+
+  @screen lg {
+    .viewport {
+      @apply w-2/4;
+    }
+  }
+
+  .message {
+    @apply text-white;
+  }
+
+  .error {
+    @apply text-red-600;
+  }
+</style>
+
+<div class="viewport md-dark md-body">
+  <div>
+    {@html htmlContent}
+  </div>
+  <div class="flex flex-col flex-wrap items-center">
+    <a href="asd" on:click|preventDefault={() => onVerified({ key: "wew" })}>Verify test</a>
+    <!-- <h-captcha site-key={sitekey} dark on:verified={onVerified} /> -->
+    <div class="py-2">
+      {#if state == State.Verify}
+        <span transition:fade={{ duration: 50 }}><Icon data={spinner} spin /> Verifying</span>
+        {:else if state == State.Error || state == State.Message }
+        <span class:message={state == State.Message} class:error={state == State.Error}>{message}</span>
+      {/if}
+    </div>
+  </div>
+</div>

+ 1 - 1
web/src/routes/rules/markdown-dark.css

@@ -52,7 +52,7 @@
         margin-left: 24px;
     }
     p, ul, ol {
-        font-size: 16px;
+        font-size: 18px;
         line-height: 24px;
         max-width: 540px;
     }

+ 20 - 0
web/src/routes/rules/verify.ts

@@ -0,0 +1,20 @@
+import { Request as ExpressRequest, Response as ExpressResponse } from "express";
+import { existsSync, promises } from "fs";
+import { join } from "path";
+import { ENVIRONMENT } from "src/utils/environment";
+import { Option } from "@shared/common/async_utils";
+import { rpcClient } from "src/utils/rpc";
+
+export interface VerifyInfo {
+    captchaSitekey: string;
+}
+
+type GetResult = Promise<ExpressResponse<VerifyInfo>>;
+export const get = async (req: ExpressRequest, res: ExpressResponse): GetResult => res.json({
+    captchaSitekey: ENVIRONMENT.hCaptchaSitekey,
+});
+
+// type PostResult = Promise<ExpressResponse<Option<unknown, { error: string }>>>;
+// export const post = async (req: ExpressRequest, res: ExpressResponse): PostResult => {
+
+// };

+ 7 - 1
web/src/utils/environment.ts

@@ -21,6 +21,8 @@ export interface BotEnvironment {
     redirectUrl: string;
     clientSecret: string;
     dataPath: string;
+    hCaptchaSitekey: string;
+    hCaptchaSecret: string;
 }
 
 export const ENVIRONMENT: BotEnvironment = {
@@ -28,9 +30,13 @@ export const ENVIRONMENT: BotEnvironment = {
     redirectUrl: process.env.WEB_AUTH_URI ?? "",
     clientSecret: process.env.BOT_CLIENT_SECRET ?? "",
     dataPath: process.env.WEB_DATA_PATH ?? "",
+    hCaptchaSitekey: process.env.HCAPTCHA_SITEKEY ?? "",
+    hCaptchaSecret: process.env.HCAPTCHA_SECRET ?? "",
 };
 
 export const IS_VALID = process.env.BOT_CLIENT_ID !== undefined
                         && process.env.WEB_AUTH_URI !== undefined
                         && process.env.BOT_CLIENT_SECRET !== undefined
-                        && process.env.WEB_DATA_PATH !== undefined;
+                        && process.env.WEB_DATA_PATH !== undefined
+                        && process.env.HCAPTCHA_SITEKEY !== undefined
+                        && process.env.HCAPTCHA_SECRET !== undefined;