fix captcha remove shitty ratelimit

This commit is contained in:
not-nullptr 2024-03-19 17:45:40 +00:00
parent 0cb5723c75
commit 5e6ad9c8d9
6 changed files with 57 additions and 24 deletions

View file

@ -0,0 +1,7 @@
import { RateLimiter, json } from "$lib/server/util/index.js";
export function POST({ request, getClientAddress }) {
return json({
success: true,
});
}

View file

@ -2,7 +2,7 @@
import { userRepo } from "$lib/server/repo";
import type { SuyuUser } from "$lib/server/schema";
import { RateLimiter, json } from "$lib/server/util";
import { json } from "$lib/server/util";
import { useAuth } from "$lib/util/api";
import type {
CreateAccountRequest,
@ -18,8 +18,6 @@ import { HCAPTCHA_KEY } from "$env/static/private";
import validator from "validator";
import bcrypt from "bcrypt";
const rateLimit = new RateLimiter();
const randomBytes = promisify(crypto.randomBytes);
async function genKey(username: string) {
@ -35,12 +33,6 @@ async function genKey(username: string) {
}
export async function POST({ request, getClientAddress }) {
if (rateLimit.isLimited(getClientAddress())) {
return json<CreateAccountResponse>({
success: false,
error: "rate limited",
});
}
const body: CreateAccountRequest = await request.json();
if (!body.username || !body.email || !body.captchaToken || !body.password) {
return json<CreateAccountResponse>({
@ -111,11 +103,6 @@ export async function POST({ request, getClientAddress }) {
}
export async function GET({ request, getClientAddress }) {
if (rateLimit.isLimited(getClientAddress()))
return json<GetUserResponse>({
success: false,
error: "rate limited",
});
const user = await useAuth(request);
if (!user) {
return json<GetUserResponse>({
@ -130,11 +117,6 @@ export async function GET({ request, getClientAddress }) {
}
export async function DELETE({ request, getClientAddress }) {
if (rateLimit.isLimited(getClientAddress()))
return json<DeleteAccountResponse>({
success: false,
error: "rate limited",
});
const user = await useAuth(request);
if (!user) {
return json<DeleteAccountResponse>({

View file

@ -1,7 +1,10 @@
import { HCAPTCHA_KEY } from "$env/static/private";
import { PUBLIC_SITE_KEY } from "$env/static/public";
import { userRepo } from "$lib/server/repo";
import { RateLimiter, json } from "$lib/server/util/index.js";
import { json } from "$lib/server/util/index.js";
import type { LoginResponse, LoginRequest } from "$types/api";
import bcrypt from "bcrypt";
import { verify } from "hcaptcha";
export async function POST({ request, getClientAddress }) {
const body: LoginRequest = await request.json();
@ -11,12 +14,20 @@ export async function POST({ request, getClientAddress }) {
body.email.trim() === "" ||
body.password.trim() === "" ||
body.email.length > 320 ||
body.password.length > 320
body.password.length > 320 ||
!body.captchaToken
)
return json<LoginResponse>({
success: false,
error: "missing fields",
});
const res = await verify(HCAPTCHA_KEY, body.captchaToken, getClientAddress(), PUBLIC_SITE_KEY);
if (!res.success) {
return json<LoginResponse>({
success: false,
error: "invalid captcha",
});
}
const user = await userRepo.findOne({
where: {
email: body.email,

View file

@ -13,16 +13,20 @@
let emailInput = "";
let passwordInput = "";
$: disabled = !emailInput || !passwordInput;
let captchaToken = "";
$: disabled = !emailInput || !passwordInput || !captchaToken;
export let data: PageData;
if (Object.keys(data.user).length !== 0 && browser) goto("/account");
let shouldLoadCaptcha = false;
async function logIn() {
const res = await SuyuAPI.users.login({
email: emailInput,
password: passwordInput,
captchaToken,
});
if (!res.success) {
// TODO: modal
@ -38,6 +42,15 @@
function enter(e: KeyboardEvent) {
if (e.key === "Enter") logIn();
}
async function captchaComplete(event: CustomEvent<any>) {
captchaToken = event.detail.token;
}
onMount(async () => {
setTimeout(() => {
shouldLoadCaptcha = true;
}, 500);
});
</script>
<div
@ -67,6 +80,11 @@
placeholder="Password"
on:keydown={enter}
/>
<div class="h-[78px]">
{#if shouldLoadCaptcha}
<HCaptcha on:success={captchaComplete} theme="dark" sitekey={PUBLIC_SITE_KEY} />
{/if}
</div>
<button {disabled} on:click={logIn} class="cta-button mt-2">Log in</button>
</div>
</div>

View file

@ -6,7 +6,7 @@
import { SuyuAPI } from "$lib/client/api";
import type { PageData } from "./$types";
import type { Writable } from "svelte/store";
import { getContext } from "svelte";
import { getContext, onMount } from "svelte";
const token = getContext<Writable<string>>("token");
if ($token) goto("/account");
@ -42,6 +42,14 @@
async function captchaComplete(event: CustomEvent<any>) {
captchaToken = event.detail.token;
}
let shouldLoadCaptcha = false;
onMount(() => {
setTimeout(() => {
shouldLoadCaptcha = true;
}, 500);
});
</script>
<div
@ -86,7 +94,13 @@
autocomplete="new-password"
/>
<div class="h-[78px]">
<HCaptcha on:success={captchaComplete} theme="dark" sitekey={PUBLIC_SITE_KEY} />
{#if shouldLoadCaptcha}
<HCaptcha
on:success={captchaComplete}
theme="dark"
sitekey={PUBLIC_SITE_KEY}
/>
{/if}
</div>
<button {disabled} type="submit" on:click={signUp} class="cta-button mt-2"
>Sign up</button

1
src/types/api.d.ts vendored
View file

@ -37,6 +37,7 @@ export type GetUserResponse = GetUserResponseSuccess | GenericFailureResponse;
export interface LoginRequest {
email: string;
password: string;
captchaToken: string;
}
export interface LoginResponseSuccess {