From 2ddf2c7d31c6dd62892606ead484d8a705532a09 Mon Sep 17 00:00:00 2001
From: not-nullptr
Date: Tue, 12 Mar 2024 08:12:21 +0000
Subject: [PATCH] sign up page with captcha
---
.env.example | 1 +
package-lock.json | 30 +++++
package.json | 4 +
src/app.pcss | 33 ++++++
src/components/HCaptcha.svelte | 111 ++++++++++++++++++
src/hooks.server.ts | 32 ++++--
src/lib/server/schema/index.ts | 5 +
src/routes/+layout.svelte | 26 ++++-
src/routes/+page.svelte | 4 +-
src/routes/account/+page.svelte | 182 +++++-------------------------
src/routes/api/user/+server.ts | 37 ++++--
src/routes/signup/+page.server.ts | 13 +++
src/routes/signup/+page.svelte | 64 +++++++++++
src/types/api.d.ts | 2 +
14 files changed, 370 insertions(+), 174 deletions(-)
create mode 100644 .env.example
create mode 100644 src/components/HCaptcha.svelte
create mode 100644 src/routes/signup/+page.server.ts
create mode 100644 src/routes/signup/+page.svelte
diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..577be0c
--- /dev/null
+++ b/.env.example
@@ -0,0 +1 @@
+HCAPTCHA_KEY=ES_
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 7847346..b989671 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,12 +12,16 @@
"@sveltejs/enhanced-img": "^0.1.8",
"better-sqlite3": "^9.4.3",
"cookie": "^0.6.0",
+ "email-validator": "^2.0.4",
+ "hcaptcha": "^0.1.1",
"jsonwebtoken": "^9.0.2",
"reflect-metadata": "^0.2.1",
"sequelize": "^6.37.1",
"sqlite3": "^5.1.7",
+ "svelte-hcaptcha": "^0.1.1",
"typeorm": "^0.3.20",
"uuid": "^9.0.1",
+ "verify-hcaptcha": "^1.0.0",
"vite-plugin-vsharp": "^1.7.3",
"ws": "^8.16.0"
},
@@ -2938,6 +2942,14 @@
"integrity": "sha512-f9iZD1t3CLy1AS6vzM5EKGa6p9pRcOeEFXRFbaG2Ta+Oe7MkfRQ3fsvPYidzHe1h4i0JvIvpcY55C+B6BZNGtQ==",
"dev": true
},
+ "node_modules/email-validator": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/email-validator/-/email-validator-2.0.4.tgz",
+ "integrity": "sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ==",
+ "engines": {
+ "node": ">4.0"
+ }
+ },
"node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
@@ -3643,6 +3655,11 @@
"node": ">= 0.4"
}
},
+ "node_modules/hcaptcha": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/hcaptcha/-/hcaptcha-0.1.1.tgz",
+ "integrity": "sha512-iMrDmH2VpIEKOrcKWidVjI89FdDKTEdZ7PfPWkP27sTazIIkob8YfdY2ezaufAnWBiUUcvzsn0qF+dyXtBH2Vw=="
+ },
"node_modules/highlight.js": {
"version": "10.7.3",
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
@@ -6290,6 +6307,11 @@
"svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0"
}
},
+ "node_modules/svelte-hcaptcha": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/svelte-hcaptcha/-/svelte-hcaptcha-0.1.1.tgz",
+ "integrity": "sha512-iFF3HwfrCRciJnDs4Y9/rpP/BM2U/5zt+vh+9d4tALPAHVkcANiJIKqYuS835pIaTm6gt+xOzjfFI3cgiRI29A=="
+ },
"node_modules/svelte-hmr": {
"version": "0.15.3",
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.3.tgz",
@@ -7087,6 +7109,14 @@
"node": ">= 0.8"
}
},
+ "node_modules/verify-hcaptcha": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/verify-hcaptcha/-/verify-hcaptcha-1.0.0.tgz",
+ "integrity": "sha512-WRpRjUdybjvpxjciQ8+SQ1qXYIKlWghVA2sabGuX09s2jSvBHv6Dzz4Kzu8eBBCLvwiZ/6+ursx1aN4w7qRG9w==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/vite": {
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.1.5.tgz",
diff --git a/package.json b/package.json
index 95c26d6..9338ab9 100644
--- a/package.json
+++ b/package.json
@@ -48,12 +48,16 @@
"@sveltejs/enhanced-img": "^0.1.8",
"better-sqlite3": "^9.4.3",
"cookie": "^0.6.0",
+ "email-validator": "^2.0.4",
+ "hcaptcha": "^0.1.1",
"jsonwebtoken": "^9.0.2",
"reflect-metadata": "^0.2.1",
"sequelize": "^6.37.1",
"sqlite3": "^5.1.7",
+ "svelte-hcaptcha": "^0.1.1",
"typeorm": "^0.3.20",
"uuid": "^9.0.1",
+ "verify-hcaptcha": "^1.0.0",
"vite-plugin-vsharp": "^1.7.3",
"ws": "^8.16.0"
}
diff --git a/src/app.pcss b/src/app.pcss
index 565363a..b361516 100644
--- a/src/app.pcss
+++ b/src/app.pcss
@@ -23,6 +23,12 @@ body {
font-family: "DM Sans", sans-serif;
}
+html {
+ scroll-behavior: smooth;
+ overflow-x: hidden;
+ scrollbar-gutter: stable;
+}
+
h1,
h2,
h3 {
@@ -41,6 +47,17 @@ h3 {
@apply flex w-fit shrink-0 select-none flex-row items-center justify-center gap-4 rounded-xl py-3 pl-7 pr-5 font-bold transition;
}
+.button,
+.cta-button {
+ padding: 0.75rem 1.5rem;
+}
+
+.button:disabled,
+.cta-button:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
.button {
border: 2px solid #46424d;
@apply flex w-fit shrink-0 select-none flex-row items-center justify-center gap-4 rounded-xl py-3 pl-7 pr-5 font-bold transition;
@@ -62,3 +79,19 @@ h3 {
background: #c3c3cd;
color: black;
}
+
+.input {
+ border: 2px solid #46424d;
+ /* @apply w-full rounded-xl px-4 py-3 text-sm font-bold transition; */
+ width: 100%;
+ border-radius: 0.75rem;
+ padding: 0.5rem 1rem;
+ font-size: 1rem;
+ font-weight: 600;
+ transition: all 0.2s;
+ background-color: transparent;
+}
+
+.link {
+ @apply text-blue-300 underline transition-all ease-out hover:text-blue-100;
+}
diff --git a/src/components/HCaptcha.svelte b/src/components/HCaptcha.svelte
new file mode 100644
index 0000000..7ba4d75
--- /dev/null
+++ b/src/components/HCaptcha.svelte
@@ -0,0 +1,111 @@
+
+
+
+
+
+ {#if mounted && !window?.hcaptcha}
+
+ {/if}
+
+
+
diff --git a/src/hooks.server.ts b/src/hooks.server.ts
index 2e51b8b..d4e5246 100644
--- a/src/hooks.server.ts
+++ b/src/hooks.server.ts
@@ -2,25 +2,35 @@ import { db } from "$lib/server/db";
import "reflect-metadata";
import { building } from "$app/environment";
import type { Handle } from "@sveltejs/kit";
-import {WebSocketServer} from "ws";
+import { WebSocketServer } from "ws";
let server: WebSocketServer;
function initServer() {
- server = new WebSocketServer({
- port: 21563,
- path: "/net"
- });
- server.on("connection", (socket) => {
- socket.on("message", (data) => {
- socket.send(data);
- })
- })
+ try {
+ server = new WebSocketServer({
+ port: 21563,
+ path: "/net",
+ });
+ server.on("error", (err) => {
+ console.error("WebSocket server error:", err);
+ });
+ server.on("connection", (socket) => {
+ socket.on("message", (data) => {
+ socket.send(data);
+ });
+ });
+ } catch {}
}
const runAllTheInitFunctions = async () => {
if (!db.isInitialized) await db.initialize();
- if (!server) initServer();
+ if (!server)
+ try {
+ initServer();
+ } catch {
+ console.error("Could not initialize WebSocket server");
+ }
};
if (!building) {
diff --git a/src/lib/server/schema/index.ts b/src/lib/server/schema/index.ts
index c7f2474..a6c256c 100644
--- a/src/lib/server/schema/index.ts
+++ b/src/lib/server/schema/index.ts
@@ -22,4 +22,9 @@ export class SuyuUser extends BaseEntity {
select: false,
})
apiKey: string;
+
+ @Column("text", {
+ select: false,
+ })
+ email: string;
}
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index e4e2a0f..08084d0 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -3,14 +3,34 @@
import { onMount, onDestroy } from "svelte";
import Logo from "../components/LogoWithTextHorizontal.svelte";
import { CodeBranchOutline, DiscordSolid, DownloadOutline } from "flowbite-svelte-icons";
+ import { browser } from "$app/environment";
let scrolled = false;
-
+ let cookies: {
+ [key: string]: string;
+ } = {};
+ if (browser) {
+ cookies = Object.fromEntries(
+ document.cookie.split("; ").map((c) => {
+ const [key, value] = c.split("=");
+ return [key, value];
+ }),
+ );
+ }
onMount(() => {
const handleScroll = () => {
scrolled = window.scrollY > 0;
};
+ handleScroll(); // we can't guarantee that the page starts at the top
+
+ cookies = Object.fromEntries(
+ document.cookie.split("; ").map((c) => {
+ const [key, value] = c.split("=");
+ return [key, value];
+ }),
+ );
+
window.addEventListener("scroll", handleScroll);
return () => {
@@ -59,7 +79,9 @@
>
- Sign in
+ {cookies.token ? "Account" : "Sign up"}
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index fcbf886..c3f088a 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -31,7 +31,7 @@
open-source, forever.
-
+
+
Contribute