diff --git a/src/hooks.server.js b/src/hooks.server.js index 8bd92ed..998b639 100644 --- a/src/hooks.server.js +++ b/src/hooks.server.js @@ -8,11 +8,16 @@ export async function handle({ event, resolve }) { } const cookie = event.cookies.get(COOKIE_NAME); - if (!cookie) return await resolve(event); + if (!cookie) { + if (event.routeId.startsWith("(app)")) return new Response("", { status: 302, headers: { Location: "/landing" } }); + return await resolve(event); + } - let user = await getUserFromSession(cookie, event.getClientAddress()); - if (!user) event.cookies.delete(COOKIE_NAME, { secure: !!process.env.PRODUCTION }); - else + let user = await getUserFromSession(cookie, event.request.headers.get("x-forwarded-for") || event.getClientAddress()); + if (!user) { + event.cookies.delete(COOKIE_NAME, { secure: !!process.env.PRODUCTION }); + if (event.routeId.startsWith("(app)")) return new Response("", { status: 302, headers: { Location: "/landing" } }); + } else event.locals.user = { _id: user._id, username: user.username, diff --git a/src/lib/components/hCaptcha.svelte b/src/lib/components/hCaptcha.svelte new file mode 100644 index 0000000..3236948 --- /dev/null +++ b/src/lib/components/hCaptcha.svelte @@ -0,0 +1,61 @@ + + + + + + + +
diff --git a/src/lib/constants.js b/src/lib/constants.js index afda1df..866b84c 100644 --- a/src/lib/constants.js +++ b/src/lib/constants.js @@ -2,6 +2,7 @@ export const COOKIE_NAME = ".ROWBLOX_SESSION_DO_NOT_SHARE"; export const USERNAME_REGEX = /[^A-Za-z0-9\-_ ]/g; export const MIN_USERNAME_LENGTH = 3; export const MAX_USERNAME_LENGTH = 16; -export const MIN_PASSWORD_LENGTH = 0; +export const MIN_PASSWORD_LENGTH = 3; export const INVITE_KEY_PREFIX = "rowblox-"; export const SESSION_EXPIRE = 604800000; +export const HCAPTCHA_SITEKEY = "be5c40c1-13db-423c-878e-f3428e9fc841"; diff --git a/src/lib/database.js b/src/lib/database.js index 08e4f18..41d931f 100644 --- a/src/lib/database.js +++ b/src/lib/database.js @@ -16,6 +16,7 @@ const assets = await db.collection("assets"); const invites = await db.collection("invites"); const avatars = await db.collection("avatars"); const sessions = await db.collection("sessions"); +const friends = await db.collection("friends"); async function inc(collection) { await collection.updateOne({ _id: "_inc" }, { $inc: { _inc: 1 } }); @@ -50,7 +51,13 @@ export async function createUser(username, password, lastip) { username, password: await hashPassword(password), lastip, - currency: 100 + currency: 100, + joinDate: Date.now(), + lastOnline: Date.now(), + rank: 1, + activity: 1, + pendingFriendRequests: [], + bio: "" }; const avatar = { @@ -63,7 +70,8 @@ export async function createUser(username, password, lastip) { LeftLegColor: 1, RightLegColor: 1 }, - Assets: {} + Wearing: [], + Inventory: [] }; await Promise.all([avatars.insertOne(avatar), await users.insertOne(user)]); @@ -104,12 +112,12 @@ export async function deleteSession(session, lastip) { const sessionDocument = await sessions.findOne({ _id: session }); if (!sessionDocument) return false; - const user = await users.findOne({ _id: sessionDocument._id }); + const user = await users.findOne({ _id: sessionDocument.owner }); if (!user) return false; await users.updateOne({ _id: user._id }, { $set: { lastip } }); - return await sessions.deleteOne({ session }); + return await sessions.deleteOne({ _id: session }); } export async function getUser(query, projection) { diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte index cc8b9b8..6423665 100644 --- a/src/routes/(app)/+layout.svelte +++ b/src/routes/(app)/+layout.svelte @@ -1,9 +1,15 @@ - Logout + Logout
diff --git a/src/routes/(app)/games/[id]/+page.server.js b/src/routes/(app)/games/[id]/+page.server.js new file mode 100644 index 0000000..e69de29 diff --git a/src/routes/(app)/games/[id]/+page.svelte b/src/routes/(app)/games/[id]/+page.svelte index f4013c7..7bc8722 100644 --- a/src/routes/(app)/games/[id]/+page.svelte +++ b/src/routes/(app)/games/[id]/+page.svelte @@ -1,38 +1,105 @@ + + - Games - Rowblox + {game?.name} - Rowblox +
+
+ +
+
+

{game?.name}

+

By {game?.creator?.username}

+
+ +
+ + Edit + + +
+ +
+
+
-
+
+
+ + + +
+
-
- -
-

Test Game

-

By Rowblox

-
-

0

-

0

-
-
-
- Edit Game
-
-
-

Test Game

-
-

Players

-

0

-

Visits

-

0

-

Created

-

10/10/22

-

Updated

-

10/10/22

-

Max Players

-

All

-
-
-

No players connected

+{#if state == 0} +
+
+

Description

+

Test Game

+
+
+
+

Players

+

0

+
+
+

Visits

+

0

+
+
+

Created

+

10/10/22

+
+
+

Updated

+

10/10/22

+
+
+

Max Players

+

No Limit

+
+
+
+{:else if state == 1} +
+

Gamepasses

+

This store does not have any gamepasses for sale.

+
+{:else if state == 2} +
+

Players

+

This game does not have any players.

+
+
+

Players

+ + + + +
+{/if} diff --git a/src/routes/(app)/users/[id]/+page.svelte b/src/routes/(app)/users/[id]/+page.svelte index d52d169..6831742 100644 --- a/src/routes/(app)/users/[id]/+page.svelte +++ b/src/routes/(app)/users/[id]/+page.svelte @@ -14,18 +14,3 @@ - -
-
-

This is my description!

-
-
- -
-
-

Friends

-
-
-

Games

-
-
diff --git a/src/routes/(nolayout)/login/+page.server.js b/src/routes/(nolayout)/login/+page.server.js index b42f2e4..c8cd1ed 100644 --- a/src/routes/(nolayout)/login/+page.server.js +++ b/src/routes/(nolayout)/login/+page.server.js @@ -18,7 +18,7 @@ export const actions = { const correctPassword = await compareHash(password, user.password); if (!correctPassword) return invalid(400, { error: "password" }); - cookies.set(COOKIE_NAME, await createSession(user._id, getClientAddress()), { secure: !!process.env.PRODUCTION }); + cookies.set(COOKIE_NAME, await createSession(user._id, request.headers.get("x-forwarded-for") || getClientAddress()), { secure: !!process.env.PRODUCTION }); throw redirect(302, "/"); } }; diff --git a/src/routes/(nolayout)/login/+page.svelte b/src/routes/(nolayout)/login/+page.svelte index db83ff1..f864383 100644 --- a/src/routes/(nolayout)/login/+page.svelte +++ b/src/routes/(nolayout)/login/+page.svelte @@ -10,7 +10,7 @@
{#if form?.message} -

{form?.message}

+

{form?.message}

{/if}
- + diff --git a/src/routes/(nolayout)/logout/+server.js b/src/routes/(nolayout)/logout/+server.js index a732660..ec8018c 100644 --- a/src/routes/(nolayout)/logout/+server.js +++ b/src/routes/(nolayout)/logout/+server.js @@ -2,7 +2,7 @@ import { deleteSession } from "$lib/database"; import { COOKIE_NAME } from "$lib/constants"; /** @type {import('./$types').RequestHandler} */ -export async function GET({ cookies, getClientAddress }) { +export async function GET({ request, cookies, getClientAddress }) { const session = cookies.get(COOKIE_NAME); if (!session) return new Response("", { @@ -11,7 +11,7 @@ export async function GET({ cookies, getClientAddress }) { }); cookies.delete(COOKIE_NAME, { secure: !!process.env.PRODUCTION }); - await deleteSession(session, getClientAddress()); + await deleteSession(session, request.headers.get("x-forwarded-for") || getClientAddress()); return new Response("", { status: 302, diff --git a/src/routes/(nolayout)/register/+page.server.js b/src/routes/(nolayout)/register/+page.server.js index 3be4a8a..2d4f6c4 100644 --- a/src/routes/(nolayout)/register/+page.server.js +++ b/src/routes/(nolayout)/register/+page.server.js @@ -1,6 +1,6 @@ import { invalid, redirect } from "@sveltejs/kit"; -import { createUser, createSession } from "$lib/database"; -import { MIN_USERNAME_LENGTH, MAX_USERNAME_LENGTH, USERNAME_REGEX, MIN_PASSWORD_LENGTH, INVITE_KEY_PREFIX, COOKIE_NAME } from "$lib/constants"; +import { createUser, createSession, getUser } from "$lib/database"; +import { MIN_USERNAME_LENGTH, MAX_USERNAME_LENGTH, USERNAME_REGEX, MIN_PASSWORD_LENGTH, INVITE_KEY_PREFIX, COOKIE_NAME, HCAPTCHA_SITEKEY } from "$lib/constants"; /** @type {import('./$types').Actions} */ export const actions = { @@ -13,6 +13,7 @@ export const actions = { const password = data.get("password"); const confirm_password = data.get("confirm_password"); const invite_key = data.get("invite_key"); + const hcaptcha_response = data.get("h-captcha-response"); if (username.length < MIN_USERNAME_LENGTH || username.length > MAX_USERNAME_LENGTH || new RegExp(USERNAME_REGEX).test(username)) return invalid(400, { @@ -35,8 +36,37 @@ export const actions = { error: "invite_key" }); - const user = await createUser(username, password, getClientAddress()); - cookies.set(COOKIE_NAME, await createSession(user, getClientAddress()), { secure: !!process.env.PRODUCTION }); + if (!hcaptcha_response) + return invalid(400, { + username, + invite_key, + error: "hcaptcha" + }); + + const existingUser = await getUser({ username }, { _id: true }); + if (existingUser) + return invalid(400, { + username, + invite_key, + error: "username" + }); + + const hcaptcha = await fetch("https://hcaptcha.com/siteverify", { + method: "POST", + body: `response=${hcaptcha_response}&secret=${process.env.HCAPTCHA_SECRET}`, + headers: { "content-type": "application/x-www-form-urlencoded" } + }); + + const hcaptchaBody = await hcaptcha.json(); + if (!hcaptchaBody.success) + return invalid(400, { + username, + invite_key, + error: "hcaptcha" + }); + + const user = await createUser(username, password, request.headers.get("x-forwarded-for") || getClientAddress()); + cookies.set(COOKIE_NAME, await createSession(user, request.headers.get("x-forwarded-for") || getClientAddress()), { secure: !!process.env.PRODUCTION }); throw redirect(302, "/"); } }; diff --git a/src/routes/(nolayout)/register/+page.svelte b/src/routes/(nolayout)/register/+page.svelte index 39ba03f..15b78b1 100644 --- a/src/routes/(nolayout)/register/+page.svelte +++ b/src/routes/(nolayout)/register/+page.svelte @@ -1,17 +1,20 @@ Register - Rowblox -
{#if form?.message} -

{form?.message}

+

{form?.message}

{/if} -
- +
+ +
+