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

+
{ + logoutEveryonePending = true; + return async ({ update }) => { + await update({ reset: false }); + logoutEveryonePending = false; + }; + }} + onsubmit={() => { + return confirm('really really log everyone out?'); + }} + > + +
+

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 3f79cb7..0e277c6 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..bc69958 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 @@ user profile
@@ -146,7 +147,7 @@ >
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)'}