From 70d37106d9c42f914b45c8c679d5a765e8421af0 Mon Sep 17 00:00:00 2001 From: Arca Ege Cengiz Date: Tue, 2 Dec 2025 22:21:23 +0000 Subject: [PATCH 1/7] Prevent super admin lockout --- src/routes/auth/callback/+server.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/routes/auth/callback/+server.ts b/src/routes/auth/callback/+server.ts index bbc2013..3ddc9cc 100644 --- a/src/routes/auth/callback/+server.ts +++ b/src/routes/auth/callback/+server.ts @@ -165,6 +165,11 @@ export async function GET(event) { return redirect(302, 'https://fraud.land'); } + const isSuperAdmin = + env.SUPER_ADMIN_SLACK_ID != undefined && + env.SUPER_ADMIN_SLACK_ID.length > 0 && + slack_id === env.SUPER_ADMIN_SLACK_ID; + if (databaseUser) { // Update user (update name and profile picture and lastLoginAt on login) await db @@ -173,12 +178,11 @@ export async function GET(event) { name: username, profilePicture: profilePic, lastLoginAt: new Date(Date.now()), - hackatimeTrust + hackatimeTrust, + hasAdmin: isSuperAdmin ? true : undefined }) .where(eq(user.idvId, id)); } else { - const isSuperAdmin = slack_id === env.SUPER_ADMIN_SLACK_ID; - // Create user await db.insert(user).values({ idvId: id, From fdc6d4efd91069b390e031a340c1ab96479bdc6c Mon Sep 17 00:00:00 2001 From: Arca Ege Cengiz Date: Tue, 2 Dec 2025 22:45:46 +0000 Subject: [PATCH 2/7] Improve admin page --- src/routes/dashboard/admin/admin/+page.svelte | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/routes/dashboard/admin/admin/+page.svelte b/src/routes/dashboard/admin/admin/+page.svelte index 9610955..ef43689 100644 --- a/src/routes/dashboard/admin/admin/+page.svelte +++ b/src/routes/dashboard/admin/admin/+page.svelte @@ -1,5 +1,6 @@ @@ -9,5 +10,15 @@

Admin

- Users +
From 7cd10d7a61e782b8e3b2fbf6928392335a5e119a Mon Sep 17 00:00:00 2001 From: Arca Ege Cengiz Date: Tue, 2 Dec 2025 23:38:36 +0000 Subject: [PATCH 3/7] Add more user info to admin page --- src/routes/dashboard/admin/admin/+page.svelte | 4 +- .../dashboard/admin/admin/users/+page.svelte | 138 +++--------------- .../admin/admin/users/[id]/+page.server.ts | 4 +- 3 files changed, 21 insertions(+), 125 deletions(-) diff --git a/src/routes/dashboard/admin/admin/+page.svelte b/src/routes/dashboard/admin/admin/+page.svelte index ef43689..8a9cf17 100644 --- a/src/routes/dashboard/admin/admin/+page.svelte +++ b/src/routes/dashboard/admin/admin/+page.svelte @@ -12,10 +12,10 @@
-
+

Users

diff --git a/src/routes/dashboard/admin/admin/users/+page.svelte b/src/routes/dashboard/admin/admin/users/+page.svelte index c533364..7c7300c 100644 --- a/src/routes/dashboard/admin/admin/users/+page.svelte +++ b/src/routes/dashboard/admin/admin/users/+page.svelte @@ -9,12 +9,10 @@ let userSearch = $state(''); - let users = $derived(data.users); //form?.users ?? + let users = $derived(data.users); //form?.users ?? let filteredProjects = $derived( - data.users.filter((user) => - user.name?.toLowerCase().includes(userSearch.toLowerCase()) - ) + data.users.filter((user) => user.name?.toLowerCase().includes(userSearch.toLowerCase())) ); let filteredUsers = $derived( data.users.filter((user) => user.name.toLowerCase().includes(userSearch.toLowerCase())) @@ -28,92 +26,6 @@

Users

- - {#if users.length == 0}
@@ -135,44 +47,28 @@

{user.name}

- + + {user.slackId} + +

Hackatime: {user.hackatimeTrust}

+

Trust: {user.trust}

{/each}
diff --git a/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts b/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts index 0eb9c1b..65ff8a1 100644 --- a/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts +++ b/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts @@ -1,7 +1,7 @@ import { db } from '$lib/server/db/index.js'; import { user, devlog, session } from '$lib/server/db/schema.js'; import { error } from '@sveltejs/kit'; -import { eq, sql } from 'drizzle-orm'; +import { and, eq, sql } from 'drizzle-orm'; import type { Actions } from './$types'; export async function load({ locals, params }) { @@ -20,7 +20,7 @@ export async function load({ locals, params }) { devlogCount: sql`COALESCE(COUNT(${devlog.id}), 0)` }) .from(user) - .leftJoin(devlog, eq(devlog.userId, user.id)) + .leftJoin(devlog, and(eq(devlog.userId, user.id), eq(devlog.deleted, false))) .where(eq(user.id, id)) .groupBy(user.id)) ?? [{ devlogCount: 0 }]; From 5e842f8af615a4dd2cddae54ee45143b33f5a691 Mon Sep 17 00:00:00 2001 From: Arca Ege Cengiz Date: Tue, 2 Dec 2025 23:59:56 +0000 Subject: [PATCH 4/7] Add public profile page link to user admin --- src/routes/dashboard/admin/admin/users/[id]/+page.server.ts | 2 -- src/routes/dashboard/admin/admin/users/[id]/+page.svelte | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts b/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts index 65ff8a1..79160e2 100644 --- a/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts +++ b/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts @@ -51,8 +51,6 @@ export const actions = { const hasAdmin = data.get('has_admin'); const hasProjectAuditLogs = data.get('has_project_audit_logs'); - // TODO: add check to disable un-admining superadmin - await db .update(user) .set({ diff --git a/src/routes/dashboard/admin/admin/users/[id]/+page.svelte b/src/routes/dashboard/admin/admin/users/[id]/+page.svelte index 3a2e1f7..53b3ff1 100644 --- a/src/routes/dashboard/admin/admin/users/[id]/+page.svelte +++ b/src/routes/dashboard/admin/admin/users/[id]/+page.svelte @@ -29,6 +29,8 @@
+ Public profile page +
Date: Wed, 3 Dec 2025 00:28:27 +0000 Subject: [PATCH 5/7] Make currency round down --- src/routes/dashboard/Sidebar.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/dashboard/Sidebar.svelte b/src/routes/dashboard/Sidebar.svelte index 0272aa0..a2f5bf2 100644 --- a/src/routes/dashboard/Sidebar.svelte +++ b/src/routes/dashboard/Sidebar.svelte @@ -60,7 +60,7 @@

{user.name}

-

{user.clay} clay · {user.brick} brick

+

{Math.floor(user.clay)} clay · {Math.floor(user.brick)} brick

Log out From e30651f7e545e74b83c6891b6532683fc3cc17f1 Mon Sep 17 00:00:00 2001 From: Arca Ege Cengiz Date: Wed, 3 Dec 2025 01:56:09 +0000 Subject: [PATCH 6/7] Add currency to admin dashboard --- src/app.css | 4 ++ .../dashboard/admin/admin/users/+page.svelte | 1 + .../admin/admin/users/[id]/+page.server.ts | 53 +++++++++++++++- .../admin/admin/users/[id]/+page.svelte | 61 +++++++++++++++++++ 4 files changed, 118 insertions(+), 1 deletion(-) diff --git a/src/app.css b/src/app.css index adb6e14..243f3d1 100644 --- a/src/app.css +++ b/src/app.css @@ -257,6 +257,10 @@ @apply border-3 border-primary-700 bg-primary-900 fill-primary-50 p-2 text-sm ring-primary-900 placeholder:text-primary-700 active:ring-3; } + .themed-input-on-box { + @apply bg-primary-900 border-3 border-primary-800 ring-primary-700 focus:ring-2 transition-shadow rounded-lg placeholder:text-primary-700; + } + .checkbox { @apply border-2 border-primary-600 bg-primary-900 ring-0 h-4 w-4 rounded-sm; } diff --git a/src/routes/dashboard/admin/admin/users/+page.svelte b/src/routes/dashboard/admin/admin/users/+page.svelte index 7c7300c..05648ec 100644 --- a/src/routes/dashboard/admin/admin/users/+page.svelte +++ b/src/routes/dashboard/admin/admin/users/+page.svelte @@ -69,6 +69,7 @@

Hackatime: {user.hackatimeTrust}

Trust: {user.trust}

+

{user.clay} clay, {user.brick} brick, {user.shopScore} market

{/each}
diff --git a/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts b/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts index 79160e2..048c8a4 100644 --- a/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts +++ b/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts @@ -1,6 +1,6 @@ import { db } from '$lib/server/db/index.js'; import { user, devlog, session } from '$lib/server/db/schema.js'; -import { error } from '@sveltejs/kit'; +import { error, fail } from '@sveltejs/kit'; import { and, eq, sql } from 'drizzle-orm'; import type { Actions } from './$types'; @@ -72,6 +72,57 @@ export const actions = { }; }, + currency: async ({ locals, request, params }) => { + if (!locals.user) { + throw error(500); + } + if (!locals.user.hasAdmin) { + throw error(403, { message: 'get out, peasant' }); + } + + const id: number = parseInt(params.id); + + const data = await request.formData(); + const clay = data.get('clay'); + const brick = data.get('brick'); + const shopScore = data.get('market_score'); + + if ( + !clay || + isNaN(parseFloat(clay.toString())) || + !brick || + isNaN(parseFloat(brick.toString())) || + !shopScore || + isNaN(parseFloat(shopScore.toString())) + ) { + return fail(400, { + currency: { + fields: { clay, brick, shopScore }, + invalidFields: true + } + }); + } + + await db + .update(user) + .set({ + clay: parseFloat(clay.toString()), + brick: parseFloat(brick.toString()), + shopScore: parseFloat(shopScore.toString()) + }) + .where(eq(user.id, id)); + + const [queriedUser] = await db.select().from(user).where(eq(user.id, id)); + + if (!queriedUser) { + throw error(404, { message: 'user not found' }); + } + + return { + queriedUser + }; + }, + refreshHackatime: async ({ locals, params }) => { if (!locals.user) { throw error(500); diff --git a/src/routes/dashboard/admin/admin/users/[id]/+page.svelte b/src/routes/dashboard/admin/admin/users/[id]/+page.svelte index 53b3ff1..f58af57 100644 --- a/src/routes/dashboard/admin/admin/users/[id]/+page.svelte +++ b/src/routes/dashboard/admin/admin/users/[id]/+page.svelte @@ -9,6 +9,7 @@ let user = $derived(form?.queriedUser ?? data.queriedUser); let hackatimePending = $state(false); + let currencyPending = $state(false); let privilegesPending = $state(false); let logoutPending = $state(false); @@ -112,6 +113,66 @@
+

Currency stuff

+
+ { + currencyPending = true; + return async ({ update }) => { + await update({ reset: false }); + currencyPending = false; + }; + }} + > +
+ + + +
+ {#if form?.currency?.invalidFields} +

Invalid fields

+ {/if} + + +
+

Privileges

Date: Wed, 3 Dec 2025 02:27:03 +0000 Subject: [PATCH 7/7] Add ship check for min 2h and description/url --- src/app.css | 2 +- .../projects/[id]/ship/+page.server.ts | 19 ++++++++++--------- .../dashboard/projects/[id]/ship/+page.svelte | 18 +++++++++++++++--- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/app.css b/src/app.css index 243f3d1..523c3a8 100644 --- a/src/app.css +++ b/src/app.css @@ -233,7 +233,7 @@ &:disabled, &.disabled { - @apply cursor-not-allowed opacity-80 hover:outline-0; + @apply cursor-not-allowed opacity-70 hover:outline-0; } &.red { diff --git a/src/routes/dashboard/projects/[id]/ship/+page.server.ts b/src/routes/dashboard/projects/[id]/ship/+page.server.ts index 6b1fc78..d609ef1 100644 --- a/src/routes/dashboard/projects/[id]/ship/+page.server.ts +++ b/src/routes/dashboard/projects/[id]/ship/+page.server.ts @@ -46,11 +46,6 @@ export async function load({ params, locals }) { throw error(404); } - // Make sure it has actual devlogs before shipping - if (queriedProject.devlogCount == 0) { - return error(400, { message: 'project has no devlogs' }); - } - return { project: queriedProject }; @@ -67,6 +62,8 @@ export const actions = { const [queriedProject] = await db .select({ id: project.id, + description: project.description, + url: project.url, timeSpent: sql`COALESCE(SUM(${devlog.timeSpent}), 0)`, devlogCount: sql`COALESCE(COUNT(${devlog.id}), 0)` }) @@ -80,16 +77,20 @@ export const actions = { or(eq(project.status, 'building'), eq(project.status, 'rejected')) ) ) - .groupBy(project.id) + .groupBy(project.id, project.description, project.url) .limit(1); if (!queriedProject) { return error(404, { message: 'project not found' }); } - // Make sure it has actual devlogs before shipping - if (queriedProject.devlogCount == 0) { - return error(400, { message: 'project has no devlogs' }); + // Make sure it has atleast 2h + if (queriedProject.timeSpent < 120) { + return error(400, { message: 'minimum 2h needed to ship' }); + } + + if (queriedProject.description == '' || queriedProject.url == '') { + return error(400, { message: 'project must have a description and Printables url' }); } await db diff --git a/src/routes/dashboard/projects/[id]/ship/+page.svelte b/src/routes/dashboard/projects/[id]/ship/+page.svelte index 38f5cae..57d4152 100644 --- a/src/routes/dashboard/projects/[id]/ship/+page.svelte +++ b/src/routes/dashboard/projects/[id]/ship/+page.svelte @@ -24,8 +24,14 @@ clickable={false} />

- Are you sure you want to ship "{data.project.name}"? You won't be able to edit it or journal again - unless it gets rejected. + {#if data.project.timeSpent < 120} + You need at least 2h to ship + {:else if data.project.description == '' || data.project.url == ''} + Project must have a description and Printables URL to ship + {:else} + Are you sure you want to ship "{data.project.name}"? You won't be able to edit it or journal + again unless it gets rejected. + {/if}

Cancel -