From 7494267fed179a42dd891e0e0d47f77adc7e5039 Mon Sep 17 00:00:00 2001
From: Arca Ege Cengiz
Date: Fri, 19 Dec 2025 00:26:44 +0000
Subject: [PATCH 1/4] Fix ysws review bug
---
.../dashboard/admin/ysws-review/[id]/+page.server.ts | 9 +++++++--
src/routes/dashboard/admin/ysws-review/[id]/+page.svelte | 1 +
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/routes/dashboard/admin/ysws-review/[id]/+page.server.ts b/src/routes/dashboard/admin/ysws-review/[id]/+page.server.ts
index c7103f4..3739949 100644
--- a/src/routes/dashboard/admin/ysws-review/[id]/+page.server.ts
+++ b/src/routes/dashboard/admin/ysws-review/[id]/+page.server.ts
@@ -32,6 +32,8 @@ export async function load({ locals, params }) {
uploadedFileUrl: project.uploadedFileUrl,
modelFile: project.modelFile,
+ submittedToAirtable: project.submittedToAirtable,
+
createdAt: project.createdAt,
updatedAt: project.updatedAt,
status: project.status
@@ -59,6 +61,7 @@ export async function load({ locals, params }) {
project.editorUrl,
project.uploadedFileUrl,
project.modelFile,
+ project.submittedToAirtable,
project.createdAt,
project.status,
user.id,
@@ -132,6 +135,7 @@ export const actions = {
name: user.name,
slackId: user.slackId,
idvId: user.idvId,
+ idvToken: user.idvToken,
trust: user.trust,
hackatimeTrust: user.hackatimeTrust
},
@@ -154,6 +158,7 @@ export const actions = {
user.name,
user.slackId,
user.idvId,
+ user.idvToken,
user.trust,
user.hackatimeTrust
)
@@ -184,13 +189,13 @@ export const actions = {
.orderBy(desc(devlog.createdAt))
.limit(1);
- if (!locals.user.idvToken) {
+ if (!queriedProject.user?.idvToken) {
return fail(400, {
message: 'IDV token revoked/expired, ask them to reauthenticate'
});
}
- const token = decrypt(locals.user.idvToken);
+ const token = decrypt(queriedProject.user.idvToken);
let userData;
try {
diff --git a/src/routes/dashboard/admin/ysws-review/[id]/+page.svelte b/src/routes/dashboard/admin/ysws-review/[id]/+page.svelte
index d489fc4..f1cd43a 100644
--- a/src/routes/dashboard/admin/ysws-review/[id]/+page.svelte
+++ b/src/routes/dashboard/admin/ysws-review/[id]/+page.svelte
@@ -40,6 +40,7 @@
.project.timeSpent % 60}min
Status: {projectStatuses[data.project.project.status]}
+ Submitted to Airtable: {data.project.project.submittedToAirtable ?? 'null (false)'}
Date: Fri, 19 Dec 2025 01:34:38 +0000
Subject: [PATCH 2/4] Add idv PII info fetching to user admin page
---
.../admin/admin/users/[id]/+page.server.ts | 88 +++++++++++++++++-
.../admin/admin/users/[id]/+page.svelte | 90 ++++++++++++++++---
2 files changed, 167 insertions(+), 11 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 3f79cb7..55453de 100644
--- a/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts
+++ b/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts
@@ -3,7 +3,15 @@ import { user, devlog, session } from '$lib/server/db/schema.js';
import { error, fail, redirect } from '@sveltejs/kit';
import { and, eq, sql } from 'drizzle-orm';
import type { Actions } from './$types';
-import { createSession, DAY_IN_MS, generateSessionToken, SESSION_EXPIRY_DAYS, setSessionTokenCookie } from '$lib/server/auth';
+import {
+ createSession,
+ DAY_IN_MS,
+ generateSessionToken,
+ SESSION_EXPIRY_DAYS,
+ setSessionTokenCookie
+} from '$lib/server/auth';
+import { decrypt } from '$lib/server/encryption';
+import { getUserData } from '$lib/server/idvUserData';
export async function load({ locals, params }) {
if (!locals.user) {
@@ -233,5 +241,83 @@ export const actions = {
);
return redirect(302, '/dashboard');
+ },
+
+ fetchPII: async (event) => {
+ const { locals, params } = event;
+
+ if (!locals.user) {
+ throw error(500);
+ }
+
+ // Pretty important line
+ if (!locals.user.hasAdmin) {
+ throw error(403, { message: 'get out, peasant' });
+ }
+
+ const id: number = parseInt(params.id);
+
+ const [queriedUser] = await db
+ .select({
+ idvToken: user.idvToken
+ })
+ .from(user)
+ .where(eq(user.id, id));
+
+ if (!queriedUser) {
+ throw error(404, { message: 'user not found' });
+ }
+
+ if (!queriedUser.idvToken) {
+ return fail(400, {
+ fetchPII: {
+ success: false,
+ errorMessage: 'IDV token not found, ask them to re-login',
+ first_name: null,
+ last_name: null,
+ primary_email: null,
+ phone_number: null,
+ birthday: null,
+ address: null
+ }
+ });
+ }
+
+ const token = decrypt(queriedUser.idvToken);
+ let userData;
+
+ try {
+ userData = await getUserData(token);
+ } catch {
+ return fail(400, {
+ fetchPII: {
+ success: false,
+ errorMessage: 'IDV token revoked/expired, ask them to re-login',
+ first_name: null,
+ last_name: null,
+ primary_email: null,
+ phone_number: null,
+ birthday: null,
+ address: null
+ }
+ });
+ }
+
+ const { first_name, last_name, primary_email, birthday, phone_number, addresses } = userData;
+
+ const address = addresses.find((address: { primary: boolean }) => address.primary);
+
+ return {
+ fetchPII: {
+ success: true,
+ errorMessage: '',
+ first_name,
+ last_name,
+ primary_email,
+ phone_number,
+ birthday,
+ address
+ }
+ };
}
} satisfies Actions;
diff --git a/src/routes/dashboard/admin/admin/users/[id]/+page.svelte b/src/routes/dashboard/admin/admin/users/[id]/+page.svelte
index 7b76569..f18e3dd 100644
--- a/src/routes/dashboard/admin/admin/users/[id]/+page.svelte
+++ b/src/routes/dashboard/admin/admin/users/[id]/+page.svelte
@@ -13,6 +13,7 @@
let privilegesPending = $state(false);
let impersonatePending = $state(false);
let logoutPending = $state(false);
+ let fetchPIIPending = $state(false);
@@ -26,7 +27,7 @@
@@ -146,7 +147,7 @@
>
From f7e1efaa0313899af9ec97ab5a1a543330522a54 Mon Sep 17 00:00:00 2001
From: Arca Ege Cengiz
Date: Fri, 19 Dec 2025 01:53:30 +0000
Subject: [PATCH 3/4] Add logout everyone feature
---
.../admin/admin/users/+page.server.ts | 24 ++-----
.../dashboard/admin/admin/users/+page.svelte | 32 +++++++---
.../admin/admin/users/[id]/+page.server.ts | 2 +-
.../admin/admin/users/[id]/+page.svelte | 64 ++++++++++---------
4 files changed, 63 insertions(+), 59 deletions(-)
diff --git a/src/routes/dashboard/admin/admin/users/+page.server.ts b/src/routes/dashboard/admin/admin/users/+page.server.ts
index 4b7b8b8..37403cb 100644
--- a/src/routes/dashboard/admin/admin/users/+page.server.ts
+++ b/src/routes/dashboard/admin/admin/users/+page.server.ts
@@ -1,7 +1,6 @@
import { db } from '$lib/server/db/index.js';
-import { project, user, devlog } from '$lib/server/db/schema.js';
+import { user, session } from '$lib/server/db/schema.js';
import { error } from '@sveltejs/kit';
-import { eq, sql } from 'drizzle-orm';
import type { Actions } from './$types';
export async function load({ locals }) {
@@ -20,7 +19,7 @@ export async function load({ locals }) {
}
export const actions = {
- default: async ({ locals, request }) => {
+ logoutEveryone: async ({ locals }) => {
if (!locals.user) {
throw error(500);
}
@@ -28,21 +27,8 @@ export const actions = {
throw error(403, { message: 'get out, peasant' });
}
- const data = await request.formData();
- const statusFilter = data.getAll('status') as (typeof project.status._.data)[];
-
- const userFilter = data.getAll('user').map((userId) => {
- const parsedInt = parseInt(userId.toString());
- if (!parsedInt) throw error(400, { message: 'malformed user filter' });
- return parseInt(userId.toString());
- });
-
- return {
- // users,
- fields: {
- status: statusFilter,
- user: userFilter
- }
- };
+ await db.delete(session);
+
+ return {};
}
} satisfies Actions;
diff --git a/src/routes/dashboard/admin/admin/users/+page.svelte b/src/routes/dashboard/admin/admin/users/+page.svelte
index cca6cbf..9d85401 100644
--- a/src/routes/dashboard/admin/admin/users/+page.svelte
+++ b/src/routes/dashboard/admin/admin/users/+page.svelte
@@ -1,31 +1,47 @@
-
Users
+
+
Users
+
+
Showing {filteredUsers.length} users
-
+
{#if filteredUsers.length == 0}
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 55453de..0e277c6 100644
--- a/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts
+++ b/src/routes/dashboard/admin/admin/users/[id]/+page.server.ts
@@ -305,7 +305,7 @@ export const actions = {
const { first_name, last_name, primary_email, birthday, phone_number, addresses } = userData;
- const address = addresses.find((address: { primary: boolean }) => address.primary);
+ const address = addresses?.find((address: { primary: boolean }) => address.primary);
return {
fetchPII: {
diff --git a/src/routes/dashboard/admin/admin/users/[id]/+page.svelte b/src/routes/dashboard/admin/admin/users/[id]/+page.svelte
index f18e3dd..547ddbf 100644
--- a/src/routes/dashboard/admin/admin/users/[id]/+page.svelte
+++ b/src/routes/dashboard/admin/admin/users/[id]/+page.svelte
@@ -262,37 +262,39 @@
address
-
-
- {form.fetchPII.address.id}
-
-
- {form.fetchPII.address.first_name}
-
-
- {form.fetchPII.address.last_name}
-
-
- {form.fetchPII.address.line_1}
-
- {#if form.fetchPII.address.line_2}
-
- {form.fetchPII.address.line_1}
-
- {/if}
-
- {form.fetchPII.address.city}
-
-
- {form.fetchPII.address.state}
-
-
- {form.fetchPII.address.postal_code}
-
-
- {form.fetchPII.address.country}
-
-
+ {#if form?.fetchPII.address}
+
+
+ {form.fetchPII.address.id}
+
+
+ {form.fetchPII.address.first_name}
+
+
+ {form.fetchPII.address.last_name}
+
+
+ {form.fetchPII.address.line_1}
+
+ {#if form.fetchPII.address.line_2}
+
+ {form.fetchPII.address.line_1}
+
+ {/if}
+
+ {form.fetchPII.address.city}
+
+
+ {form.fetchPII.address.state}
+
+
+ {form.fetchPII.address.postal_code}
+
+
+ {form.fetchPII.address.country}
+
+
+ {/if}
{:else}