From 37d12784b61783476eddf4dd862d78b52b4b43aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Fri, 17 Jan 2025 21:09:24 +0100 Subject: [PATCH 01/20] lib/server/db/schema/user.ts: add active field --- drizzle/0008_real_stark_industries.sql | 1 + drizzle/meta/0008_snapshot.json | 403 +++++++++++++++++++++++++ drizzle/meta/_journal.json | 7 + src/lib/server/db/schema/user.ts | 3 +- 4 files changed, 413 insertions(+), 1 deletion(-) create mode 100644 drizzle/0008_real_stark_industries.sql create mode 100644 drizzle/meta/0008_snapshot.json diff --git a/drizzle/0008_real_stark_industries.sql b/drizzle/0008_real_stark_industries.sql new file mode 100644 index 0000000..fcd7c6d --- /dev/null +++ b/drizzle/0008_real_stark_industries.sql @@ -0,0 +1 @@ +ALTER TABLE "user" ADD COLUMN "active" boolean DEFAULT true NOT NULL; \ No newline at end of file diff --git a/drizzle/meta/0008_snapshot.json b/drizzle/meta/0008_snapshot.json new file mode 100644 index 0000000..c88fc36 --- /dev/null +++ b/drizzle/meta/0008_snapshot.json @@ -0,0 +1,403 @@ +{ + "id": "a56dbd8b-96ad-467e-b5a0-693600517354", + "prevId": "81ee13a7-fe6d-4b61-828e-edba465e15b5", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.building": { + "name": "building", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "building_name_unique": { + "name": "building_name_unique", + "nullsNotDistinct": false, + "columns": ["name"] + } + } + }, + "public.department": { + "name": "department", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "department_name_unique": { + "name": "department_name_unique", + "nullsNotDistinct": false, + "columns": ["name"] + } + } + }, + "public.person": { + "name": "person", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "fname": { + "name": "fname", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "lname": { + "name": "lname", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "department": { + "name": "department", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "person_department_department_name_fk": { + "name": "person_department_department_name_fk", + "tableFrom": "person", + "tableTo": "department", + "columnsFrom": ["department"], + "columnsTo": ["name"], + "onDelete": "restrict", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "person_identifier_unique": { + "name": "person_identifier_unique", + "nullsNotDistinct": false, + "columns": ["identifier"] + } + } + }, + "public.person_entry": { + "name": "person_entry", + "schema": "", + "columns": { + "person_id": { + "name": "person_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "building": { + "name": "building", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "creator": { + "name": "creator", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "person_entry_person_id_person_id_fk": { + "name": "person_entry_person_id_person_id_fk", + "tableFrom": "person_entry", + "tableTo": "person", + "columnsFrom": ["person_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "person_entry_building_building_name_fk": { + "name": "person_entry_building_building_name_fk", + "tableFrom": "person_entry", + "tableTo": "building", + "columnsFrom": ["building"], + "columnsTo": ["name"], + "onDelete": "restrict", + "onUpdate": "cascade" + }, + "person_entry_creator_user_username_fk": { + "name": "person_entry_creator_user_username_fk", + "tableFrom": "person_entry", + "tableTo": "user", + "columnsFrom": ["creator"], + "columnsTo": ["username"], + "onDelete": "no action", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": { + "person_entry_person_id_timestamp_pk": { + "name": "person_entry_person_id_timestamp_pk", + "columns": ["person_id", "timestamp"] + } + }, + "uniqueConstraints": {} + }, + "public.person_exit": { + "name": "person_exit", + "schema": "", + "columns": { + "person_id": { + "name": "person_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "building": { + "name": "building", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "creator": { + "name": "creator", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "person_exit_person_id_person_id_fk": { + "name": "person_exit_person_id_person_id_fk", + "tableFrom": "person_exit", + "tableTo": "person", + "columnsFrom": ["person_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "person_exit_building_building_name_fk": { + "name": "person_exit_building_building_name_fk", + "tableFrom": "person_exit", + "tableTo": "building", + "columnsFrom": ["building"], + "columnsTo": ["name"], + "onDelete": "restrict", + "onUpdate": "cascade" + }, + "person_exit_creator_user_username_fk": { + "name": "person_exit_creator_user_username_fk", + "tableFrom": "person_exit", + "tableTo": "user", + "columnsFrom": ["creator"], + "columnsTo": ["username"], + "onDelete": "no action", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": { + "person_exit_person_id_timestamp_pk": { + "name": "person_exit_person_id_timestamp_pk", + "columns": ["person_id", "timestamp"] + } + }, + "uniqueConstraints": {} + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "building": { + "name": "building", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "session_building_building_name_fk": { + "name": "session_building_building_name_fk", + "tableFrom": "session", + "tableTo": "building", + "columnsFrom": ["building"], + "columnsTo": ["name"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.ratelimit": { + "name": "ratelimit", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "lock": { + "name": "lock", + "type": "boolean", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "ratelimit_user_id_user_id_fk": { + "name": "ratelimit_user_id_user_id_fk", + "tableFrom": "ratelimit", + "tableTo": "user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_username_unique": { + "name": "user_username_unique", + "nullsNotDistinct": false, + "columns": ["username"] + } + } + } + }, + "enums": {}, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index 04b1183..7954703 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -57,6 +57,13 @@ "when": 1735856957839, "tag": "0007_aspiring_zombie", "breakpoints": true + }, + { + "idx": 8, + "version": "7", + "when": 1737144488824, + "tag": "0008_real_stark_industries", + "breakpoints": true } ] } diff --git a/src/lib/server/db/schema/user.ts b/src/lib/server/db/schema/user.ts index 0656147..9451994 100644 --- a/src/lib/server/db/schema/user.ts +++ b/src/lib/server/db/schema/user.ts @@ -4,7 +4,8 @@ import { boolean, integer, pgTable, serial, text, timestamp } from 'drizzle-orm/ export const userTable = pgTable('user', { id: serial('id').primaryKey(), username: text('username').notNull().unique(), - passwordHash: text('password_hash').notNull() + passwordHash: text('password_hash').notNull(), + active: boolean('active').default(true).notNull() }); export const ratelimitTable = pgTable('ratelimit', { From fe3ec4211c7afe2549782818ea3c335e93ce92b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Fri, 17 Jan 2025 21:58:20 +0100 Subject: [PATCH 02/20] lib/server/db/user.ts: implement isActiveuser --- src/lib/server/db/user.ts | 44 ++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/src/lib/server/db/user.ts b/src/lib/server/db/user.ts index 838d592..3f18da8 100644 --- a/src/lib/server/db/user.ts +++ b/src/lib/server/db/user.ts @@ -3,16 +3,23 @@ import { and, desc, eq, gt } from 'drizzle-orm'; import { ratelimitTable, userTable } from './schema/user'; import { hashPassword, verifyPasswordStrength } from '../password'; -export async function createUser(db: Database, username: string, password: string): Promise { - // Assert that username is valid - if (username === undefined || username === null || username === '') { - throw new Error('Invalid username'); +// If more files make checks like this +// move it to util and export. +function assertValidString(it: string, msg: string): void { + if (it === undefined || it === null || it === '') { + throw new Error(msg); } +} - // Assert that password is valid - if (password === undefined || password === null || password === '') { - throw new Error('Invalid password'); +function assertValidUserId(id: number): void { + if (id === undefined || id === null) { + throw new Error('Invalid user id'); } +} + +export async function createUser(db: Database, username: string, password: string): Promise { + assertValidString(username, 'Invalid username'); + assertValidString(password, 'Invalid password'); // Check the strength of the password const strong = await verifyPasswordStrength(password); @@ -35,10 +42,7 @@ export async function getUserIdAndPasswordHash( db: Database, username: string ): Promise<{ id: number; passwordHash: string }> { - // Assert that username is valid - if (username === null || username === undefined || username === '') { - throw new Error('Invalid username'); - } + assertValidString(username, 'Invalid username'); try { const [{ id, passwordHash }] = await db @@ -67,10 +71,7 @@ export async function checkUserRatelimit( ratelimitMaxAttempts: number, ratelimitTimeout: number ): Promise { - // Assert that id is valid - if (userId === null || userId === undefined) { - throw new Error('Invalid userId'); - } + assertValidUserId(userId); // Assert that ratelimitMaxAttempts is valid if ( @@ -115,3 +116,16 @@ export async function checkUserRatelimit( return false; }); } + +export async function isUserActive(db: Database, userId: number): Promise { + assertValidUserId(userId); + + const [{ active }] = await db + .select({ + active: userTable.active + }) + .from(userTable) + .where(eq(userTable.id, userId)); + + return active; +} From 3a4499c1722dfafa283d266bfd7f543aa838a0e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Fri, 17 Jan 2025 22:04:58 +0100 Subject: [PATCH 03/20] isActiveuser: improve error handling --- src/lib/server/db/user.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/lib/server/db/user.ts b/src/lib/server/db/user.ts index 3f18da8..8304a97 100644 --- a/src/lib/server/db/user.ts +++ b/src/lib/server/db/user.ts @@ -120,12 +120,16 @@ export async function checkUserRatelimit( export async function isUserActive(db: Database, userId: number): Promise { assertValidUserId(userId); - const [{ active }] = await db - .select({ - active: userTable.active - }) - .from(userTable) - .where(eq(userTable.id, userId)); - - return active; + try { + const [{ active }] = await db + .select({ + active: userTable.active + }) + .from(userTable) + .where(eq(userTable.id, userId)); + + return active; + } catch (err: unknown) { + throw new Error(`failed getting user status: ${(err as Error).message}`); + } } From cd98b6b30982059af05d10ade7d074dc9b0bd70b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Fri, 17 Jan 2025 22:47:47 +0100 Subject: [PATCH 04/20] lib/server//db/user.ts: implement updateUserActive --- src/lib/server/db/user.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/lib/server/db/user.ts b/src/lib/server/db/user.ts index 8304a97..3cfdead 100644 --- a/src/lib/server/db/user.ts +++ b/src/lib/server/db/user.ts @@ -133,3 +133,21 @@ export async function isUserActive(db: Database, userId: number): Promise { + assertValidUserId(userId); + + try { + db.update(userTable) + .set({ + active: newActive + }) + .where(eq(userTable.id, userId)); + } catch (err: unknown) { + throw new Error(`Couldn't update user.active: ${(err as Error).message}`); + } +} From d01062d31474de0cf1e9cdc8076c4f3fd8ac2440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Mon, 27 Jan 2025 05:39:56 +0100 Subject: [PATCH 05/20] lib/server/db/user.ts: await the update --- src/lib/server/db/user.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/server/db/user.ts b/src/lib/server/db/user.ts index 3cfdead..e033892 100644 --- a/src/lib/server/db/user.ts +++ b/src/lib/server/db/user.ts @@ -142,11 +142,13 @@ export async function updateUserActive( assertValidUserId(userId); try { - db.update(userTable) + await db + .update(userTable) .set({ active: newActive }) .where(eq(userTable.id, userId)); + console.log(`date active for user ${userId} set to ${newActive}`); } catch (err: unknown) { throw new Error(`Couldn't update user.active: ${(err as Error).message}`); } From 2093c9d9ba9fb1612124bc5d5faa10f4fdb26e30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Mon, 27 Jan 2025 05:42:46 +0100 Subject: [PATCH 06/20] routes/admin/activate: implement the route for activating users For now it's all a part of a single page. Perhaps it should be a part of a bigger user settings page? --- src/routes/admin/activate/+page.server.ts | 93 +++++++++++++++++++++++ src/routes/admin/activate/+page.svelte | 61 +++++++++++++++ src/routes/admin/activate/schema.ts | 9 +++ 3 files changed, 163 insertions(+) create mode 100644 src/routes/admin/activate/+page.server.ts create mode 100644 src/routes/admin/activate/+page.svelte create mode 100644 src/routes/admin/activate/schema.ts diff --git a/src/routes/admin/activate/+page.server.ts b/src/routes/admin/activate/+page.server.ts new file mode 100644 index 0000000..4ce0ff9 --- /dev/null +++ b/src/routes/admin/activate/+page.server.ts @@ -0,0 +1,93 @@ +import { getUserIdAndPasswordHash, updateUserActive } from '$lib/server/db/user'; +import { validateSecret } from '$lib/server/secret'; +import { fail, type Actions } from '@sveltejs/kit'; +import { superValidate } from 'sveltekit-superforms'; +import { zod } from 'sveltekit-superforms/adapters'; +import type { PageServerLoad } from './$types'; +import { formSchema } from './schema'; + +export const load: PageServerLoad = async () => { + const form = await superValidate(zod(formSchema)); + + return { + form + }; +}; + +export const actions: Actions = { + activate: async (event) => { + const { locals, request } = event; + const { database } = locals; + const form = await superValidate(request, zod(formSchema)); + if (!form.valid) { + return fail(400, { + form, + message: 'Invalid form inputs' + }); + } + + // Check if the secret is correct + const secretOk = await validateSecret(form.data.secret); + if (!secretOk) { + return fail(401, { + form, + message: 'Invalid secret' + }); + } + + try { + const { username } = form.data; + const { id } = await getUserIdAndPasswordHash(database, username); + await updateUserActive(database, id, true); + } catch (err: unknown) { + console.debug(`Failed to activate user ${username}: ${(err as Error).message}`); + return fail(400, { + form, + message: 'username does not exist' + }); + } + + return { + form, + message: 'User activated!' + }; + }, + deactivate: async (event) => { + console.log('Got to action deactivate'); + const { locals, request } = event; + const { database } = locals; + const form = await superValidate(request, zod(formSchema)); + if (!form.valid) { + return fail(400, { + form, + message: 'Invalid form inputs' + }); + } + + // Check if the secret is correct + const secretOk = await validateSecret(form.data.secret); + if (!secretOk) { + return fail(401, { + form, + message: 'Invalid secret' + }); + } + + try { + const { username } = form.data; + const { id } = await getUserIdAndPasswordHash(database, username); + await updateUserActive(database, id, false); + } catch (err: unknown) { + console.debug(`Failed to deactivate user ${username}: ${(err as Error).message}`); + return fail(400, { + form, + message: 'username does not exist' + }); + } + + return { + form, + message: 'User deactivated!' + }; + } +}; diff --git a/src/routes/admin/activate/+page.svelte b/src/routes/admin/activate/+page.svelte new file mode 100644 index 0000000..c0e9052 --- /dev/null +++ b/src/routes/admin/activate/+page.svelte @@ -0,0 +1,61 @@ + + +
+ + + Activate / deactivate users + Type in the id of the user you want to activate / deactivate. + + + + + {#snippet children({ props })} + Username + + {/snippet} + + + + + + {#snippet children({ props })} + Secret + + {/snippet} + + + + Activate + Deactivate + + +
diff --git a/src/routes/admin/activate/schema.ts b/src/routes/admin/activate/schema.ts new file mode 100644 index 0000000..d528b4e --- /dev/null +++ b/src/routes/admin/activate/schema.ts @@ -0,0 +1,9 @@ +import { indexRegExp, indexRegExpMsg } from '$lib/utils/regexp'; +import { z } from 'zod'; + +export const formSchema = z.object({ + username: z.string().regex(indexRegExp, indexRegExpMsg), + secret: z.string().min(32).max(255) +}); + +export type FormSchema = typeof formSchema; From bafc5dfb8a94a4f3b4510c3749f0358ff0a88e4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Mon, 27 Jan 2025 06:21:29 +0100 Subject: [PATCH 07/20] remove debug printing --- src/lib/server/db/user.ts | 1 - src/routes/admin/activate/+page.server.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/src/lib/server/db/user.ts b/src/lib/server/db/user.ts index e033892..866e15e 100644 --- a/src/lib/server/db/user.ts +++ b/src/lib/server/db/user.ts @@ -148,7 +148,6 @@ export async function updateUserActive( active: newActive }) .where(eq(userTable.id, userId)); - console.log(`date active for user ${userId} set to ${newActive}`); } catch (err: unknown) { throw new Error(`Couldn't update user.active: ${(err as Error).message}`); } diff --git a/src/routes/admin/activate/+page.server.ts b/src/routes/admin/activate/+page.server.ts index 4ce0ff9..592bb7d 100644 --- a/src/routes/admin/activate/+page.server.ts +++ b/src/routes/admin/activate/+page.server.ts @@ -53,7 +53,6 @@ export const actions: Actions = { }; }, deactivate: async (event) => { - console.log('Got to action deactivate'); const { locals, request } = event; const { database } = locals; const form = await superValidate(request, zod(formSchema)); From 7443ffe5ab903b1a36c711c6dfe30e1307fbf727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Mon, 27 Jan 2025 06:21:48 +0100 Subject: [PATCH 08/20] routes/login: don't let deactivated users log in --- src/routes/login/+page.server.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/routes/login/+page.server.ts b/src/routes/login/+page.server.ts index 6e9a6ec..5a5a23e 100644 --- a/src/routes/login/+page.server.ts +++ b/src/routes/login/+page.server.ts @@ -1,5 +1,5 @@ import { createSession, invalidateExcessSessions } from '$lib/server/db/session'; -import { checkUserRatelimit, getUserIdAndPasswordHash } from '$lib/server/db/user'; +import { checkUserRatelimit, getUserIdAndPasswordHash, isUserActive } from '$lib/server/db/user'; import { verifyPasswordHash } from '$lib/server/password'; import { generateSessionToken, setSessionTokenCookie } from '$lib/server/session'; import { fail, redirect, type Actions } from '@sveltejs/kit'; @@ -63,6 +63,10 @@ export const actions: Actions = { throw new Error('Incorrect password'); } + if (!(await isUserActive(database, id))) { + throw new Error('user is deactivated: contact the administrator'); + } + // Create a new session token const sessionToken = generateSessionToken(); const session = await createSession(database, sessionToken, id, building); From ba0203de5e181678a822b1cb796d00e61c22845b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Mon, 27 Jan 2025 12:20:43 +0100 Subject: [PATCH 09/20] routes/admin/activate: username is not in scope, fully qualify --- src/routes/admin/activate/+page.server.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/admin/activate/+page.server.ts b/src/routes/admin/activate/+page.server.ts index 592bb7d..5abbf87 100644 --- a/src/routes/admin/activate/+page.server.ts +++ b/src/routes/admin/activate/+page.server.ts @@ -40,7 +40,7 @@ export const actions: Actions = { const { id } = await getUserIdAndPasswordHash(database, username); await updateUserActive(database, id, true); } catch (err: unknown) { - console.debug(`Failed to activate user ${username}: ${(err as Error).message}`); + console.debug(`Failed to activate user ${form.data.username}: ${(err as Error).message}`); return fail(400, { form, message: 'username does not exist' @@ -77,7 +77,7 @@ export const actions: Actions = { const { id } = await getUserIdAndPasswordHash(database, username); await updateUserActive(database, id, false); } catch (err: unknown) { - console.debug(`Failed to deactivate user ${username}: ${(err as Error).message}`); + console.debug(`Failed to deactivate user ${form.data.username}: ${(err as Error).message}`); return fail(400, { form, message: 'username does not exist' From 727344a887d53456eaf78423fbf0147551beaee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Mon, 27 Jan 2025 16:10:31 +0100 Subject: [PATCH 10/20] routes/admin/activate: remove an unnecessary import --- src/routes/admin/activate/+page.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/src/routes/admin/activate/+page.svelte b/src/routes/admin/activate/+page.svelte index c0e9052..edef552 100644 --- a/src/routes/admin/activate/+page.svelte +++ b/src/routes/admin/activate/+page.svelte @@ -7,7 +7,6 @@ import { zodClient } from 'sveltekit-superforms/adapters'; import { formSchema } from './schema'; import { page } from '$app/stores'; - import { Button } from '$lib/components/ui/button'; let { data, form: actionData } = $props(); From 8c52a66b4a483cb519592bb926ef3b2a9f6d2972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Tue, 28 Jan 2025 18:15:07 +0100 Subject: [PATCH 11/20] admin/layout: activate page has a title now --- src/routes/admin/+layout.svelte | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/routes/admin/+layout.svelte b/src/routes/admin/+layout.svelte index 352c418..25fa5a8 100644 --- a/src/routes/admin/+layout.svelte +++ b/src/routes/admin/+layout.svelte @@ -20,6 +20,8 @@ Create Building {:else if $page.url.pathname === '/admin/create/department'} Create Department + {:else if $page.url.pathname === '/admin/activate'} + Activate / deactivate users {:else} Admin Homepage {/if} From 9c83a9c288f5d008cb6994379e272ada434a5af9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Tue, 28 Jan 2025 19:59:55 +0100 Subject: [PATCH 12/20] admin/sidebar: add activate / deactivate users --- src/lib/components/custom/sidebar/admin-sidebar.svelte | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lib/components/custom/sidebar/admin-sidebar.svelte b/src/lib/components/custom/sidebar/admin-sidebar.svelte index bd4ae7f..0c36f9b 100644 --- a/src/lib/components/custom/sidebar/admin-sidebar.svelte +++ b/src/lib/components/custom/sidebar/admin-sidebar.svelte @@ -3,6 +3,7 @@ import Building from 'lucide-svelte/icons/building'; import Cuboid from 'lucide-svelte/icons/cuboid'; import KeyRound from 'lucide-svelte/icons/key-round'; + import Lock from 'lucide-svelte/icons/lock'; import Bomb from 'lucide-svelte/icons/bomb'; import Github from 'lucide-svelte/icons/github'; import * as Sidebar from '$lib/components/ui/sidebar/index.js'; @@ -34,6 +35,11 @@ url: '/admin/register', icon: KeyRound }, + { + title: 'Activate / deactivate user', + url: '/admin/activate', + icon: Lock + }, { title: 'Nuke Building', url: '/admin/nuke', From c151df83b36509bccf0579e0e55decc2888c086d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Wed, 29 Jan 2025 14:53:09 +0100 Subject: [PATCH 13/20] routes/admin/activate: remove unnecessary type=submit on the buttons --- src/routes/admin/activate/+page.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/admin/activate/+page.svelte b/src/routes/admin/activate/+page.svelte index edef552..b116a68 100644 --- a/src/routes/admin/activate/+page.svelte +++ b/src/routes/admin/activate/+page.svelte @@ -53,8 +53,8 @@ - Activate - Deactivate + Activate + Deactivate From b3906c26c247a8ed22e8b44b30f4bd4d240e0fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Wed, 29 Jan 2025 15:28:55 +0100 Subject: [PATCH 14/20] hooks.server.ts: log out a deactivated user --- src/hooks.server.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hooks.server.ts b/src/hooks.server.ts index ae602d1..a106083 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -1,6 +1,7 @@ import { connectDatabase } from '$lib/server/db/connect'; import { validateSessionToken } from '$lib/server/db/session'; import { setSessionTokenCookie, deleteSessionTokenCookie } from '$lib/server/session'; +import { isUserActive } from '$lib/server/db/user'; import type { Handle } from '@sveltejs/kit'; import { redirect } from '@sveltejs/kit'; @@ -31,7 +32,7 @@ export const handle: Handle = async ({ event, resolve }) => { // Validate session token const { session, user } = await validateSessionToken(database, token); - if (session !== null) { + if (session !== null && await isUserActive(database, user.id)) { // If session is valid, ensure the token is up-to-date setSessionTokenCookie(event, token, session.timestamp); From e7bbc717a2f449c43a92a609b196f938fbf8ab4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Wed, 29 Jan 2025 16:30:25 +0100 Subject: [PATCH 15/20] rename [de]active to disable / enable --- drizzle/0009_old_tenebrous.sql | 2 + drizzle/meta/0009_snapshot.json | 403 ++++++++++++++++++ drizzle/meta/_journal.json | 7 + src/hooks.server.ts | 4 +- .../custom/sidebar/admin-sidebar.svelte | 4 +- src/lib/server/db/schema/user.ts | 2 +- src/lib/server/db/user.ts | 16 +- src/routes/admin/+layout.svelte | 4 +- .../{activate => disable}/+page.server.ts | 18 +- .../admin/{activate => disable}/+page.svelte | 10 +- .../admin/{activate => disable}/schema.ts | 0 src/routes/login/+page.server.ts | 6 +- 12 files changed, 443 insertions(+), 33 deletions(-) create mode 100644 drizzle/0009_old_tenebrous.sql create mode 100644 drizzle/meta/0009_snapshot.json rename src/routes/admin/{activate => disable}/+page.server.ts (78%) rename src/routes/admin/{activate => disable}/+page.svelte (83%) rename src/routes/admin/{activate => disable}/schema.ts (100%) diff --git a/drizzle/0009_old_tenebrous.sql b/drizzle/0009_old_tenebrous.sql new file mode 100644 index 0000000..e1d8ca6 --- /dev/null +++ b/drizzle/0009_old_tenebrous.sql @@ -0,0 +1,2 @@ +ALTER TABLE "user" RENAME COLUMN "active" TO "disabled";--> statement-breakpoint +ALTER TABLE "user" ALTER COLUMN "disabled" SET DEFAULT false; \ No newline at end of file diff --git a/drizzle/meta/0009_snapshot.json b/drizzle/meta/0009_snapshot.json new file mode 100644 index 0000000..c080bf6 --- /dev/null +++ b/drizzle/meta/0009_snapshot.json @@ -0,0 +1,403 @@ +{ + "id": "6b86fa79-f971-4873-a18b-fac6b8ae6896", + "prevId": "a56dbd8b-96ad-467e-b5a0-693600517354", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.building": { + "name": "building", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "building_name_unique": { + "name": "building_name_unique", + "nullsNotDistinct": false, + "columns": ["name"] + } + } + }, + "public.department": { + "name": "department", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "department_name_unique": { + "name": "department_name_unique", + "nullsNotDistinct": false, + "columns": ["name"] + } + } + }, + "public.person": { + "name": "person", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "fname": { + "name": "fname", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "lname": { + "name": "lname", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "department": { + "name": "department", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "person_department_department_name_fk": { + "name": "person_department_department_name_fk", + "tableFrom": "person", + "tableTo": "department", + "columnsFrom": ["department"], + "columnsTo": ["name"], + "onDelete": "restrict", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "person_identifier_unique": { + "name": "person_identifier_unique", + "nullsNotDistinct": false, + "columns": ["identifier"] + } + } + }, + "public.person_entry": { + "name": "person_entry", + "schema": "", + "columns": { + "person_id": { + "name": "person_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "building": { + "name": "building", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "creator": { + "name": "creator", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "person_entry_person_id_person_id_fk": { + "name": "person_entry_person_id_person_id_fk", + "tableFrom": "person_entry", + "tableTo": "person", + "columnsFrom": ["person_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "person_entry_building_building_name_fk": { + "name": "person_entry_building_building_name_fk", + "tableFrom": "person_entry", + "tableTo": "building", + "columnsFrom": ["building"], + "columnsTo": ["name"], + "onDelete": "restrict", + "onUpdate": "cascade" + }, + "person_entry_creator_user_username_fk": { + "name": "person_entry_creator_user_username_fk", + "tableFrom": "person_entry", + "tableTo": "user", + "columnsFrom": ["creator"], + "columnsTo": ["username"], + "onDelete": "no action", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": { + "person_entry_person_id_timestamp_pk": { + "name": "person_entry_person_id_timestamp_pk", + "columns": ["person_id", "timestamp"] + } + }, + "uniqueConstraints": {} + }, + "public.person_exit": { + "name": "person_exit", + "schema": "", + "columns": { + "person_id": { + "name": "person_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "building": { + "name": "building", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "creator": { + "name": "creator", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "person_exit_person_id_person_id_fk": { + "name": "person_exit_person_id_person_id_fk", + "tableFrom": "person_exit", + "tableTo": "person", + "columnsFrom": ["person_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "person_exit_building_building_name_fk": { + "name": "person_exit_building_building_name_fk", + "tableFrom": "person_exit", + "tableTo": "building", + "columnsFrom": ["building"], + "columnsTo": ["name"], + "onDelete": "restrict", + "onUpdate": "cascade" + }, + "person_exit_creator_user_username_fk": { + "name": "person_exit_creator_user_username_fk", + "tableFrom": "person_exit", + "tableTo": "user", + "columnsFrom": ["creator"], + "columnsTo": ["username"], + "onDelete": "no action", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": { + "person_exit_person_id_timestamp_pk": { + "name": "person_exit_person_id_timestamp_pk", + "columns": ["person_id", "timestamp"] + } + }, + "uniqueConstraints": {} + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "building": { + "name": "building", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "session_building_building_name_fk": { + "name": "session_building_building_name_fk", + "tableFrom": "session", + "tableTo": "building", + "columnsFrom": ["building"], + "columnsTo": ["name"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.ratelimit": { + "name": "ratelimit", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "lock": { + "name": "lock", + "type": "boolean", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "ratelimit_user_id_user_id_fk": { + "name": "ratelimit_user_id_user_id_fk", + "tableFrom": "ratelimit", + "tableTo": "user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "disabled": { + "name": "disabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_username_unique": { + "name": "user_username_unique", + "nullsNotDistinct": false, + "columns": ["username"] + } + } + } + }, + "enums": {}, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index 7954703..f8fd216 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -64,6 +64,13 @@ "when": 1737144488824, "tag": "0008_real_stark_industries", "breakpoints": true + }, + { + "idx": 9, + "version": "7", + "when": 1738163117927, + "tag": "0009_old_tenebrous", + "breakpoints": true } ] } diff --git a/src/hooks.server.ts b/src/hooks.server.ts index a106083..a1c668f 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -1,7 +1,7 @@ import { connectDatabase } from '$lib/server/db/connect'; import { validateSessionToken } from '$lib/server/db/session'; import { setSessionTokenCookie, deleteSessionTokenCookie } from '$lib/server/session'; -import { isUserActive } from '$lib/server/db/user'; +import { isUserDisabled } from '$lib/server/db/user'; import type { Handle } from '@sveltejs/kit'; import { redirect } from '@sveltejs/kit'; @@ -32,7 +32,7 @@ export const handle: Handle = async ({ event, resolve }) => { // Validate session token const { session, user } = await validateSessionToken(database, token); - if (session !== null && await isUserActive(database, user.id)) { + if (session !== null && !(await isUserDisabled(database, user.id))) { // If session is valid, ensure the token is up-to-date setSessionTokenCookie(event, token, session.timestamp); diff --git a/src/lib/components/custom/sidebar/admin-sidebar.svelte b/src/lib/components/custom/sidebar/admin-sidebar.svelte index 0c36f9b..652be78 100644 --- a/src/lib/components/custom/sidebar/admin-sidebar.svelte +++ b/src/lib/components/custom/sidebar/admin-sidebar.svelte @@ -36,8 +36,8 @@ icon: KeyRound }, { - title: 'Activate / deactivate user', - url: '/admin/activate', + title: 'Disable users', + url: '/admin/disable', icon: Lock }, { diff --git a/src/lib/server/db/schema/user.ts b/src/lib/server/db/schema/user.ts index 9451994..d921920 100644 --- a/src/lib/server/db/schema/user.ts +++ b/src/lib/server/db/schema/user.ts @@ -5,7 +5,7 @@ export const userTable = pgTable('user', { id: serial('id').primaryKey(), username: text('username').notNull().unique(), passwordHash: text('password_hash').notNull(), - active: boolean('active').default(true).notNull() + disabled: boolean('disabled').default(false).notNull() }); export const ratelimitTable = pgTable('ratelimit', { diff --git a/src/lib/server/db/user.ts b/src/lib/server/db/user.ts index 866e15e..a8882ba 100644 --- a/src/lib/server/db/user.ts +++ b/src/lib/server/db/user.ts @@ -117,27 +117,27 @@ export async function checkUserRatelimit( }); } -export async function isUserActive(db: Database, userId: number): Promise { +export async function isUserDisabled(db: Database, userId: number): Promise { assertValidUserId(userId); try { - const [{ active }] = await db + const [{ disabled }] = await db .select({ - active: userTable.active + disabled: userTable.disabled }) .from(userTable) .where(eq(userTable.id, userId)); - return active; + return disabled; } catch (err: unknown) { throw new Error(`failed getting user status: ${(err as Error).message}`); } } -export async function updateUserActive( +export async function updateUserDisabled( db: Database, userId: number, - newActive: boolean + newDisabled: boolean ): Promise { assertValidUserId(userId); @@ -145,10 +145,10 @@ export async function updateUserActive( await db .update(userTable) .set({ - active: newActive + disabled: newDisabled }) .where(eq(userTable.id, userId)); } catch (err: unknown) { - throw new Error(`Couldn't update user.active: ${(err as Error).message}`); + throw new Error(`Couldn't update user.disabled: ${(err as Error).message}`); } } diff --git a/src/routes/admin/+layout.svelte b/src/routes/admin/+layout.svelte index 25fa5a8..83d7cf1 100644 --- a/src/routes/admin/+layout.svelte +++ b/src/routes/admin/+layout.svelte @@ -20,8 +20,8 @@ Create Building {:else if $page.url.pathname === '/admin/create/department'} Create Department - {:else if $page.url.pathname === '/admin/activate'} - Activate / deactivate users + {:else if $page.url.pathname === '/admin/disable'} + Disable users {:else} Admin Homepage {/if} diff --git a/src/routes/admin/activate/+page.server.ts b/src/routes/admin/disable/+page.server.ts similarity index 78% rename from src/routes/admin/activate/+page.server.ts rename to src/routes/admin/disable/+page.server.ts index 5abbf87..5a035e4 100644 --- a/src/routes/admin/activate/+page.server.ts +++ b/src/routes/admin/disable/+page.server.ts @@ -1,4 +1,4 @@ -import { getUserIdAndPasswordHash, updateUserActive } from '$lib/server/db/user'; +import { getUserIdAndPasswordHash, updateUserDisabled } from '$lib/server/db/user'; import { validateSecret } from '$lib/server/secret'; import { fail, type Actions } from '@sveltejs/kit'; import { superValidate } from 'sveltekit-superforms'; @@ -15,7 +15,7 @@ export const load: PageServerLoad = async () => { }; export const actions: Actions = { - activate: async (event) => { + disable: async (event) => { const { locals, request } = event; const { database } = locals; const form = await superValidate(request, zod(formSchema)); @@ -38,9 +38,9 @@ export const actions: Actions = { try { const { username } = form.data; const { id } = await getUserIdAndPasswordHash(database, username); - await updateUserActive(database, id, true); + await updateUserDisabled(database, id, true); } catch (err: unknown) { - console.debug(`Failed to activate user ${form.data.username}: ${(err as Error).message}`); + console.debug(`Failed to disable user ${form.data.username}: ${(err as Error).message}`); return fail(400, { form, message: 'username does not exist' @@ -49,10 +49,10 @@ export const actions: Actions = { return { form, - message: 'User activated!' + message: 'User disabled!' }; }, - deactivate: async (event) => { + enable: async (event) => { const { locals, request } = event; const { database } = locals; const form = await superValidate(request, zod(formSchema)); @@ -75,9 +75,9 @@ export const actions: Actions = { try { const { username } = form.data; const { id } = await getUserIdAndPasswordHash(database, username); - await updateUserActive(database, id, false); + await updateUserDisabled(database, id, false); } catch (err: unknown) { - console.debug(`Failed to deactivate user ${form.data.username}: ${(err as Error).message}`); + console.debug(`Failed to enable user ${form.data.username}: ${(err as Error).message}`); return fail(400, { form, message: 'username does not exist' @@ -86,7 +86,7 @@ export const actions: Actions = { return { form, - message: 'User deactivated!' + message: 'User enabled!' }; } }; diff --git a/src/routes/admin/activate/+page.svelte b/src/routes/admin/disable/+page.svelte similarity index 83% rename from src/routes/admin/activate/+page.svelte rename to src/routes/admin/disable/+page.svelte index b116a68..28a8c3a 100644 --- a/src/routes/admin/activate/+page.svelte +++ b/src/routes/admin/disable/+page.svelte @@ -29,10 +29,8 @@
- Activate / deactivate users - Type in the id of the user you want to activate / deactivate. + Disable users + Type in the id of the user you want to disable or enable. @@ -53,8 +51,8 @@ - Activate - Deactivate + Disable + Enable
diff --git a/src/routes/admin/activate/schema.ts b/src/routes/admin/disable/schema.ts similarity index 100% rename from src/routes/admin/activate/schema.ts rename to src/routes/admin/disable/schema.ts diff --git a/src/routes/login/+page.server.ts b/src/routes/login/+page.server.ts index 5a5a23e..245a642 100644 --- a/src/routes/login/+page.server.ts +++ b/src/routes/login/+page.server.ts @@ -1,5 +1,5 @@ import { createSession, invalidateExcessSessions } from '$lib/server/db/session'; -import { checkUserRatelimit, getUserIdAndPasswordHash, isUserActive } from '$lib/server/db/user'; +import { checkUserRatelimit, getUserIdAndPasswordHash, isUserDisabled } from '$lib/server/db/user'; import { verifyPasswordHash } from '$lib/server/password'; import { generateSessionToken, setSessionTokenCookie } from '$lib/server/session'; import { fail, redirect, type Actions } from '@sveltejs/kit'; @@ -63,8 +63,8 @@ export const actions: Actions = { throw new Error('Incorrect password'); } - if (!(await isUserActive(database, id))) { - throw new Error('user is deactivated: contact the administrator'); + if (await isUserDisabled(database, id)) { + throw new Error('user is disabled: contact the administrator'); } // Create a new session token From 563eca259b85068915cbfcbfcfef0834204579d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Wed, 29 Jan 2025 18:32:22 +0100 Subject: [PATCH 16/20] drizzle: reset migrations --- drizzle/0008_real_stark_industries.sql | 1 - drizzle/0009_old_tenebrous.sql | 2 - drizzle/meta/0008_snapshot.json | 403 ------------------------- drizzle/meta/0009_snapshot.json | 403 ------------------------- 4 files changed, 809 deletions(-) delete mode 100644 drizzle/0008_real_stark_industries.sql delete mode 100644 drizzle/0009_old_tenebrous.sql delete mode 100644 drizzle/meta/0008_snapshot.json delete mode 100644 drizzle/meta/0009_snapshot.json diff --git a/drizzle/0008_real_stark_industries.sql b/drizzle/0008_real_stark_industries.sql deleted file mode 100644 index fcd7c6d..0000000 --- a/drizzle/0008_real_stark_industries.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE "user" ADD COLUMN "active" boolean DEFAULT true NOT NULL; \ No newline at end of file diff --git a/drizzle/0009_old_tenebrous.sql b/drizzle/0009_old_tenebrous.sql deleted file mode 100644 index e1d8ca6..0000000 --- a/drizzle/0009_old_tenebrous.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE "user" RENAME COLUMN "active" TO "disabled";--> statement-breakpoint -ALTER TABLE "user" ALTER COLUMN "disabled" SET DEFAULT false; \ No newline at end of file diff --git a/drizzle/meta/0008_snapshot.json b/drizzle/meta/0008_snapshot.json deleted file mode 100644 index c88fc36..0000000 --- a/drizzle/meta/0008_snapshot.json +++ /dev/null @@ -1,403 +0,0 @@ -{ - "id": "a56dbd8b-96ad-467e-b5a0-693600517354", - "prevId": "81ee13a7-fe6d-4b61-828e-edba465e15b5", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.building": { - "name": "building", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "building_name_unique": { - "name": "building_name_unique", - "nullsNotDistinct": false, - "columns": ["name"] - } - } - }, - "public.department": { - "name": "department", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "department_name_unique": { - "name": "department_name_unique", - "nullsNotDistinct": false, - "columns": ["name"] - } - } - }, - "public.person": { - "name": "person", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "identifier": { - "name": "identifier", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "fname": { - "name": "fname", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "lname": { - "name": "lname", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "department": { - "name": "department", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "person_department_department_name_fk": { - "name": "person_department_department_name_fk", - "tableFrom": "person", - "tableTo": "department", - "columnsFrom": ["department"], - "columnsTo": ["name"], - "onDelete": "restrict", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "person_identifier_unique": { - "name": "person_identifier_unique", - "nullsNotDistinct": false, - "columns": ["identifier"] - } - } - }, - "public.person_entry": { - "name": "person_entry", - "schema": "", - "columns": { - "person_id": { - "name": "person_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "timestamp": { - "name": "timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "building": { - "name": "building", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "creator": { - "name": "creator", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "person_entry_person_id_person_id_fk": { - "name": "person_entry_person_id_person_id_fk", - "tableFrom": "person_entry", - "tableTo": "person", - "columnsFrom": ["person_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "person_entry_building_building_name_fk": { - "name": "person_entry_building_building_name_fk", - "tableFrom": "person_entry", - "tableTo": "building", - "columnsFrom": ["building"], - "columnsTo": ["name"], - "onDelete": "restrict", - "onUpdate": "cascade" - }, - "person_entry_creator_user_username_fk": { - "name": "person_entry_creator_user_username_fk", - "tableFrom": "person_entry", - "tableTo": "user", - "columnsFrom": ["creator"], - "columnsTo": ["username"], - "onDelete": "no action", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": { - "person_entry_person_id_timestamp_pk": { - "name": "person_entry_person_id_timestamp_pk", - "columns": ["person_id", "timestamp"] - } - }, - "uniqueConstraints": {} - }, - "public.person_exit": { - "name": "person_exit", - "schema": "", - "columns": { - "person_id": { - "name": "person_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "timestamp": { - "name": "timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "building": { - "name": "building", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "creator": { - "name": "creator", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "person_exit_person_id_person_id_fk": { - "name": "person_exit_person_id_person_id_fk", - "tableFrom": "person_exit", - "tableTo": "person", - "columnsFrom": ["person_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "person_exit_building_building_name_fk": { - "name": "person_exit_building_building_name_fk", - "tableFrom": "person_exit", - "tableTo": "building", - "columnsFrom": ["building"], - "columnsTo": ["name"], - "onDelete": "restrict", - "onUpdate": "cascade" - }, - "person_exit_creator_user_username_fk": { - "name": "person_exit_creator_user_username_fk", - "tableFrom": "person_exit", - "tableTo": "user", - "columnsFrom": ["creator"], - "columnsTo": ["username"], - "onDelete": "no action", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": { - "person_exit_person_id_timestamp_pk": { - "name": "person_exit_person_id_timestamp_pk", - "columns": ["person_id", "timestamp"] - } - }, - "uniqueConstraints": {} - }, - "public.session": { - "name": "session", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "building": { - "name": "building", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "timestamp": { - "name": "timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "session_user_id_user_id_fk": { - "name": "session_user_id_user_id_fk", - "tableFrom": "session", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "no action", - "onUpdate": "no action" - }, - "session_building_building_name_fk": { - "name": "session_building_building_name_fk", - "tableFrom": "session", - "tableTo": "building", - "columnsFrom": ["building"], - "columnsTo": ["name"], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.ratelimit": { - "name": "ratelimit", - "schema": "", - "columns": { - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "timestamp": { - "name": "timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "lock": { - "name": "lock", - "type": "boolean", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "ratelimit_user_id_user_id_fk": { - "name": "ratelimit_user_id_user_id_fk", - "tableFrom": "ratelimit", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.user": { - "name": "user", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "username": { - "name": "username", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "password_hash": { - "name": "password_hash", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "active": { - "name": "active", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "user_username_unique": { - "name": "user_username_unique", - "nullsNotDistinct": false, - "columns": ["username"] - } - } - } - }, - "enums": {}, - "schemas": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} diff --git a/drizzle/meta/0009_snapshot.json b/drizzle/meta/0009_snapshot.json deleted file mode 100644 index c080bf6..0000000 --- a/drizzle/meta/0009_snapshot.json +++ /dev/null @@ -1,403 +0,0 @@ -{ - "id": "6b86fa79-f971-4873-a18b-fac6b8ae6896", - "prevId": "a56dbd8b-96ad-467e-b5a0-693600517354", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.building": { - "name": "building", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "building_name_unique": { - "name": "building_name_unique", - "nullsNotDistinct": false, - "columns": ["name"] - } - } - }, - "public.department": { - "name": "department", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "department_name_unique": { - "name": "department_name_unique", - "nullsNotDistinct": false, - "columns": ["name"] - } - } - }, - "public.person": { - "name": "person", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "identifier": { - "name": "identifier", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "fname": { - "name": "fname", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "lname": { - "name": "lname", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "department": { - "name": "department", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "person_department_department_name_fk": { - "name": "person_department_department_name_fk", - "tableFrom": "person", - "tableTo": "department", - "columnsFrom": ["department"], - "columnsTo": ["name"], - "onDelete": "restrict", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "person_identifier_unique": { - "name": "person_identifier_unique", - "nullsNotDistinct": false, - "columns": ["identifier"] - } - } - }, - "public.person_entry": { - "name": "person_entry", - "schema": "", - "columns": { - "person_id": { - "name": "person_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "timestamp": { - "name": "timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "building": { - "name": "building", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "creator": { - "name": "creator", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "person_entry_person_id_person_id_fk": { - "name": "person_entry_person_id_person_id_fk", - "tableFrom": "person_entry", - "tableTo": "person", - "columnsFrom": ["person_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "person_entry_building_building_name_fk": { - "name": "person_entry_building_building_name_fk", - "tableFrom": "person_entry", - "tableTo": "building", - "columnsFrom": ["building"], - "columnsTo": ["name"], - "onDelete": "restrict", - "onUpdate": "cascade" - }, - "person_entry_creator_user_username_fk": { - "name": "person_entry_creator_user_username_fk", - "tableFrom": "person_entry", - "tableTo": "user", - "columnsFrom": ["creator"], - "columnsTo": ["username"], - "onDelete": "no action", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": { - "person_entry_person_id_timestamp_pk": { - "name": "person_entry_person_id_timestamp_pk", - "columns": ["person_id", "timestamp"] - } - }, - "uniqueConstraints": {} - }, - "public.person_exit": { - "name": "person_exit", - "schema": "", - "columns": { - "person_id": { - "name": "person_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "timestamp": { - "name": "timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "building": { - "name": "building", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "creator": { - "name": "creator", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "person_exit_person_id_person_id_fk": { - "name": "person_exit_person_id_person_id_fk", - "tableFrom": "person_exit", - "tableTo": "person", - "columnsFrom": ["person_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "person_exit_building_building_name_fk": { - "name": "person_exit_building_building_name_fk", - "tableFrom": "person_exit", - "tableTo": "building", - "columnsFrom": ["building"], - "columnsTo": ["name"], - "onDelete": "restrict", - "onUpdate": "cascade" - }, - "person_exit_creator_user_username_fk": { - "name": "person_exit_creator_user_username_fk", - "tableFrom": "person_exit", - "tableTo": "user", - "columnsFrom": ["creator"], - "columnsTo": ["username"], - "onDelete": "no action", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": { - "person_exit_person_id_timestamp_pk": { - "name": "person_exit_person_id_timestamp_pk", - "columns": ["person_id", "timestamp"] - } - }, - "uniqueConstraints": {} - }, - "public.session": { - "name": "session", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "building": { - "name": "building", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "timestamp": { - "name": "timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "session_user_id_user_id_fk": { - "name": "session_user_id_user_id_fk", - "tableFrom": "session", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "no action", - "onUpdate": "no action" - }, - "session_building_building_name_fk": { - "name": "session_building_building_name_fk", - "tableFrom": "session", - "tableTo": "building", - "columnsFrom": ["building"], - "columnsTo": ["name"], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.ratelimit": { - "name": "ratelimit", - "schema": "", - "columns": { - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "timestamp": { - "name": "timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "lock": { - "name": "lock", - "type": "boolean", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "ratelimit_user_id_user_id_fk": { - "name": "ratelimit_user_id_user_id_fk", - "tableFrom": "ratelimit", - "tableTo": "user", - "columnsFrom": ["user_id"], - "columnsTo": ["id"], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.user": { - "name": "user", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "username": { - "name": "username", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "password_hash": { - "name": "password_hash", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "disabled": { - "name": "disabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "user_username_unique": { - "name": "user_username_unique", - "nullsNotDistinct": false, - "columns": ["username"] - } - } - } - }, - "enums": {}, - "schemas": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} From ad6fcbc36c7878eaf53da115eb7b99eebb694009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Wed, 29 Jan 2025 18:37:31 +0100 Subject: [PATCH 17/20] reset migrations take 2 --- drizzle/meta/_journal.json | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index f8fd216..04b1183 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -57,20 +57,6 @@ "when": 1735856957839, "tag": "0007_aspiring_zombie", "breakpoints": true - }, - { - "idx": 8, - "version": "7", - "when": 1737144488824, - "tag": "0008_real_stark_industries", - "breakpoints": true - }, - { - "idx": 9, - "version": "7", - "when": 1738163117927, - "tag": "0009_old_tenebrous", - "breakpoints": true } ] } From 6e3b0680cd63a6a5a3aaab3811824a5399f8d076 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Wed, 29 Jan 2025 19:00:45 +0100 Subject: [PATCH 18/20] hooks.server.ts: don't bother the database --- src/hooks.server.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hooks.server.ts b/src/hooks.server.ts index a1c668f..c29669c 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -1,7 +1,6 @@ import { connectDatabase } from '$lib/server/db/connect'; import { validateSessionToken } from '$lib/server/db/session'; import { setSessionTokenCookie, deleteSessionTokenCookie } from '$lib/server/session'; -import { isUserDisabled } from '$lib/server/db/user'; import type { Handle } from '@sveltejs/kit'; import { redirect } from '@sveltejs/kit'; @@ -32,7 +31,7 @@ export const handle: Handle = async ({ event, resolve }) => { // Validate session token const { session, user } = await validateSessionToken(database, token); - if (session !== null && !(await isUserDisabled(database, user.id))) { + if (session !== null && !user.disabled) { // If session is valid, ensure the token is up-to-date setSessionTokenCookie(event, token, session.timestamp); From 14790b22da9caa633d12d91ac54f4fbf0c3a2c4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Wed, 29 Jan 2025 19:02:23 +0100 Subject: [PATCH 19/20] drizzle: generate migrations again --- drizzle/0008_lush_selene.sql | 1 + drizzle/meta/0008_snapshot.json | 457 ++++++++++++++++++++++++++++++++ drizzle/meta/_journal.json | 129 ++++----- 3 files changed, 526 insertions(+), 61 deletions(-) create mode 100644 drizzle/0008_lush_selene.sql create mode 100644 drizzle/meta/0008_snapshot.json diff --git a/drizzle/0008_lush_selene.sql b/drizzle/0008_lush_selene.sql new file mode 100644 index 0000000..4bdcea6 --- /dev/null +++ b/drizzle/0008_lush_selene.sql @@ -0,0 +1 @@ +ALTER TABLE "user" ADD COLUMN "disabled" boolean DEFAULT false NOT NULL; \ No newline at end of file diff --git a/drizzle/meta/0008_snapshot.json b/drizzle/meta/0008_snapshot.json new file mode 100644 index 0000000..7f25ce9 --- /dev/null +++ b/drizzle/meta/0008_snapshot.json @@ -0,0 +1,457 @@ +{ + "id": "d976ece0-5c81-46bc-a88e-0f6189316565", + "prevId": "81ee13a7-fe6d-4b61-828e-edba465e15b5", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.building": { + "name": "building", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "building_name_unique": { + "name": "building_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + } + }, + "public.department": { + "name": "department", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "department_name_unique": { + "name": "department_name_unique", + "nullsNotDistinct": false, + "columns": [ + "name" + ] + } + } + }, + "public.person": { + "name": "person", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "fname": { + "name": "fname", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "lname": { + "name": "lname", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "department": { + "name": "department", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "person_department_department_name_fk": { + "name": "person_department_department_name_fk", + "tableFrom": "person", + "tableTo": "department", + "columnsFrom": [ + "department" + ], + "columnsTo": [ + "name" + ], + "onDelete": "restrict", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "person_identifier_unique": { + "name": "person_identifier_unique", + "nullsNotDistinct": false, + "columns": [ + "identifier" + ] + } + } + }, + "public.person_entry": { + "name": "person_entry", + "schema": "", + "columns": { + "person_id": { + "name": "person_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "building": { + "name": "building", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "creator": { + "name": "creator", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "person_entry_person_id_person_id_fk": { + "name": "person_entry_person_id_person_id_fk", + "tableFrom": "person_entry", + "tableTo": "person", + "columnsFrom": [ + "person_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "person_entry_building_building_name_fk": { + "name": "person_entry_building_building_name_fk", + "tableFrom": "person_entry", + "tableTo": "building", + "columnsFrom": [ + "building" + ], + "columnsTo": [ + "name" + ], + "onDelete": "restrict", + "onUpdate": "cascade" + }, + "person_entry_creator_user_username_fk": { + "name": "person_entry_creator_user_username_fk", + "tableFrom": "person_entry", + "tableTo": "user", + "columnsFrom": [ + "creator" + ], + "columnsTo": [ + "username" + ], + "onDelete": "no action", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": { + "person_entry_person_id_timestamp_pk": { + "name": "person_entry_person_id_timestamp_pk", + "columns": [ + "person_id", + "timestamp" + ] + } + }, + "uniqueConstraints": {} + }, + "public.person_exit": { + "name": "person_exit", + "schema": "", + "columns": { + "person_id": { + "name": "person_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "building": { + "name": "building", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "creator": { + "name": "creator", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "person_exit_person_id_person_id_fk": { + "name": "person_exit_person_id_person_id_fk", + "tableFrom": "person_exit", + "tableTo": "person", + "columnsFrom": [ + "person_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "person_exit_building_building_name_fk": { + "name": "person_exit_building_building_name_fk", + "tableFrom": "person_exit", + "tableTo": "building", + "columnsFrom": [ + "building" + ], + "columnsTo": [ + "name" + ], + "onDelete": "restrict", + "onUpdate": "cascade" + }, + "person_exit_creator_user_username_fk": { + "name": "person_exit_creator_user_username_fk", + "tableFrom": "person_exit", + "tableTo": "user", + "columnsFrom": [ + "creator" + ], + "columnsTo": [ + "username" + ], + "onDelete": "no action", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": { + "person_exit_person_id_timestamp_pk": { + "name": "person_exit_person_id_timestamp_pk", + "columns": [ + "person_id", + "timestamp" + ] + } + }, + "uniqueConstraints": {} + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "building": { + "name": "building", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "session_building_building_name_fk": { + "name": "session_building_building_name_fk", + "tableFrom": "session", + "tableTo": "building", + "columnsFrom": [ + "building" + ], + "columnsTo": [ + "name" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.ratelimit": { + "name": "ratelimit", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "lock": { + "name": "lock", + "type": "boolean", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "ratelimit_user_id_user_id_fk": { + "name": "ratelimit_user_id_user_id_fk", + "tableFrom": "ratelimit", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "disabled": { + "name": "disabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_username_unique": { + "name": "user_username_unique", + "nullsNotDistinct": false, + "columns": [ + "username" + ] + } + } + } + }, + "enums": {}, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index 04b1183..3686ea3 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -1,62 +1,69 @@ { - "version": "7", - "dialect": "postgresql", - "entries": [ - { - "idx": 0, - "version": "7", - "when": 1734108654159, - "tag": "0000_early_jimmy_woo", - "breakpoints": true - }, - { - "idx": 1, - "version": "7", - "when": 1734543952685, - "tag": "0001_steady_luke_cage", - "breakpoints": true - }, - { - "idx": 2, - "version": "7", - "when": 1735346155508, - "tag": "0002_known_marvel_apes", - "breakpoints": true - }, - { - "idx": 3, - "version": "7", - "when": 1735490914685, - "tag": "0003_bumpy_hardball", - "breakpoints": true - }, - { - "idx": 4, - "version": "7", - "when": 1735611551493, - "tag": "0004_lush_miss_america", - "breakpoints": true - }, - { - "idx": 5, - "version": "7", - "when": 1735611722346, - "tag": "0005_lucky_madame_web", - "breakpoints": true - }, - { - "idx": 6, - "version": "7", - "when": 1735613817511, - "tag": "0006_fearless_photon", - "breakpoints": true - }, - { - "idx": 7, - "version": "7", - "when": 1735856957839, - "tag": "0007_aspiring_zombie", - "breakpoints": true - } - ] -} + "version": "7", + "dialect": "postgresql", + "entries": [ + { + "idx": 0, + "version": "7", + "when": 1734108654159, + "tag": "0000_early_jimmy_woo", + "breakpoints": true + }, + { + "idx": 1, + "version": "7", + "when": 1734543952685, + "tag": "0001_steady_luke_cage", + "breakpoints": true + }, + { + "idx": 2, + "version": "7", + "when": 1735346155508, + "tag": "0002_known_marvel_apes", + "breakpoints": true + }, + { + "idx": 3, + "version": "7", + "when": 1735490914685, + "tag": "0003_bumpy_hardball", + "breakpoints": true + }, + { + "idx": 4, + "version": "7", + "when": 1735611551493, + "tag": "0004_lush_miss_america", + "breakpoints": true + }, + { + "idx": 5, + "version": "7", + "when": 1735611722346, + "tag": "0005_lucky_madame_web", + "breakpoints": true + }, + { + "idx": 6, + "version": "7", + "when": 1735613817511, + "tag": "0006_fearless_photon", + "breakpoints": true + }, + { + "idx": 7, + "version": "7", + "when": 1735856957839, + "tag": "0007_aspiring_zombie", + "breakpoints": true + }, + { + "idx": 8, + "version": "7", + "when": 1738173678327, + "tag": "0008_lush_selene", + "breakpoints": true + } + ] +} \ No newline at end of file From 754c087417f7e0d7bfc7191ec42ad4a61ece7b29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aleksandar=20Sredojevi=C4=87?= Date: Thu, 30 Jan 2025 11:53:47 +0100 Subject: [PATCH 20/20] fomratting --- drizzle/meta/0008_snapshot.json | 858 +++++++++++++++----------------- drizzle/meta/_journal.json | 136 ++--- 2 files changed, 470 insertions(+), 524 deletions(-) diff --git a/drizzle/meta/0008_snapshot.json b/drizzle/meta/0008_snapshot.json index 7f25ce9..a720f4c 100644 --- a/drizzle/meta/0008_snapshot.json +++ b/drizzle/meta/0008_snapshot.json @@ -1,457 +1,403 @@ { - "id": "d976ece0-5c81-46bc-a88e-0f6189316565", - "prevId": "81ee13a7-fe6d-4b61-828e-edba465e15b5", - "version": "7", - "dialect": "postgresql", - "tables": { - "public.building": { - "name": "building", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "building_name_unique": { - "name": "building_name_unique", - "nullsNotDistinct": false, - "columns": [ - "name" - ] - } - } - }, - "public.department": { - "name": "department", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "name": { - "name": "name", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "department_name_unique": { - "name": "department_name_unique", - "nullsNotDistinct": false, - "columns": [ - "name" - ] - } - } - }, - "public.person": { - "name": "person", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "identifier": { - "name": "identifier", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "type": { - "name": "type", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "fname": { - "name": "fname", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "lname": { - "name": "lname", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "department": { - "name": "department", - "type": "text", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "person_department_department_name_fk": { - "name": "person_department_department_name_fk", - "tableFrom": "person", - "tableTo": "department", - "columnsFrom": [ - "department" - ], - "columnsTo": [ - "name" - ], - "onDelete": "restrict", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "person_identifier_unique": { - "name": "person_identifier_unique", - "nullsNotDistinct": false, - "columns": [ - "identifier" - ] - } - } - }, - "public.person_entry": { - "name": "person_entry", - "schema": "", - "columns": { - "person_id": { - "name": "person_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "timestamp": { - "name": "timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "building": { - "name": "building", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "creator": { - "name": "creator", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "person_entry_person_id_person_id_fk": { - "name": "person_entry_person_id_person_id_fk", - "tableFrom": "person_entry", - "tableTo": "person", - "columnsFrom": [ - "person_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "person_entry_building_building_name_fk": { - "name": "person_entry_building_building_name_fk", - "tableFrom": "person_entry", - "tableTo": "building", - "columnsFrom": [ - "building" - ], - "columnsTo": [ - "name" - ], - "onDelete": "restrict", - "onUpdate": "cascade" - }, - "person_entry_creator_user_username_fk": { - "name": "person_entry_creator_user_username_fk", - "tableFrom": "person_entry", - "tableTo": "user", - "columnsFrom": [ - "creator" - ], - "columnsTo": [ - "username" - ], - "onDelete": "no action", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": { - "person_entry_person_id_timestamp_pk": { - "name": "person_entry_person_id_timestamp_pk", - "columns": [ - "person_id", - "timestamp" - ] - } - }, - "uniqueConstraints": {} - }, - "public.person_exit": { - "name": "person_exit", - "schema": "", - "columns": { - "person_id": { - "name": "person_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "timestamp": { - "name": "timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "building": { - "name": "building", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "creator": { - "name": "creator", - "type": "text", - "primaryKey": false, - "notNull": false - } - }, - "indexes": {}, - "foreignKeys": { - "person_exit_person_id_person_id_fk": { - "name": "person_exit_person_id_person_id_fk", - "tableFrom": "person_exit", - "tableTo": "person", - "columnsFrom": [ - "person_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "cascade" - }, - "person_exit_building_building_name_fk": { - "name": "person_exit_building_building_name_fk", - "tableFrom": "person_exit", - "tableTo": "building", - "columnsFrom": [ - "building" - ], - "columnsTo": [ - "name" - ], - "onDelete": "restrict", - "onUpdate": "cascade" - }, - "person_exit_creator_user_username_fk": { - "name": "person_exit_creator_user_username_fk", - "tableFrom": "person_exit", - "tableTo": "user", - "columnsFrom": [ - "creator" - ], - "columnsTo": [ - "username" - ], - "onDelete": "no action", - "onUpdate": "cascade" - } - }, - "compositePrimaryKeys": { - "person_exit_person_id_timestamp_pk": { - "name": "person_exit_person_id_timestamp_pk", - "columns": [ - "person_id", - "timestamp" - ] - } - }, - "uniqueConstraints": {} - }, - "public.session": { - "name": "session", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "text", - "primaryKey": true, - "notNull": true - }, - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "building": { - "name": "building", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "timestamp": { - "name": "timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - } - }, - "indexes": {}, - "foreignKeys": { - "session_user_id_user_id_fk": { - "name": "session_user_id_user_id_fk", - "tableFrom": "session", - "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "no action", - "onUpdate": "no action" - }, - "session_building_building_name_fk": { - "name": "session_building_building_name_fk", - "tableFrom": "session", - "tableTo": "building", - "columnsFrom": [ - "building" - ], - "columnsTo": [ - "name" - ], - "onDelete": "no action", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.ratelimit": { - "name": "ratelimit", - "schema": "", - "columns": { - "user_id": { - "name": "user_id", - "type": "integer", - "primaryKey": false, - "notNull": true - }, - "timestamp": { - "name": "timestamp", - "type": "timestamp", - "primaryKey": false, - "notNull": true, - "default": "now()" - }, - "lock": { - "name": "lock", - "type": "boolean", - "primaryKey": false, - "notNull": true - } - }, - "indexes": {}, - "foreignKeys": { - "ratelimit_user_id_user_id_fk": { - "name": "ratelimit_user_id_user_id_fk", - "tableFrom": "ratelimit", - "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], - "onDelete": "cascade", - "onUpdate": "no action" - } - }, - "compositePrimaryKeys": {}, - "uniqueConstraints": {} - }, - "public.user": { - "name": "user", - "schema": "", - "columns": { - "id": { - "name": "id", - "type": "serial", - "primaryKey": true, - "notNull": true - }, - "username": { - "name": "username", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "password_hash": { - "name": "password_hash", - "type": "text", - "primaryKey": false, - "notNull": true - }, - "disabled": { - "name": "disabled", - "type": "boolean", - "primaryKey": false, - "notNull": true, - "default": false - } - }, - "indexes": {}, - "foreignKeys": {}, - "compositePrimaryKeys": {}, - "uniqueConstraints": { - "user_username_unique": { - "name": "user_username_unique", - "nullsNotDistinct": false, - "columns": [ - "username" - ] - } - } - } - }, - "enums": {}, - "schemas": {}, - "_meta": { - "columns": {}, - "schemas": {}, - "tables": {} - } -} \ No newline at end of file + "id": "d976ece0-5c81-46bc-a88e-0f6189316565", + "prevId": "81ee13a7-fe6d-4b61-828e-edba465e15b5", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.building": { + "name": "building", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "building_name_unique": { + "name": "building_name_unique", + "nullsNotDistinct": false, + "columns": ["name"] + } + } + }, + "public.department": { + "name": "department", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "department_name_unique": { + "name": "department_name_unique", + "nullsNotDistinct": false, + "columns": ["name"] + } + } + }, + "public.person": { + "name": "person", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "fname": { + "name": "fname", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "lname": { + "name": "lname", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "department": { + "name": "department", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "person_department_department_name_fk": { + "name": "person_department_department_name_fk", + "tableFrom": "person", + "tableTo": "department", + "columnsFrom": ["department"], + "columnsTo": ["name"], + "onDelete": "restrict", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "person_identifier_unique": { + "name": "person_identifier_unique", + "nullsNotDistinct": false, + "columns": ["identifier"] + } + } + }, + "public.person_entry": { + "name": "person_entry", + "schema": "", + "columns": { + "person_id": { + "name": "person_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "building": { + "name": "building", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "creator": { + "name": "creator", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "person_entry_person_id_person_id_fk": { + "name": "person_entry_person_id_person_id_fk", + "tableFrom": "person_entry", + "tableTo": "person", + "columnsFrom": ["person_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "person_entry_building_building_name_fk": { + "name": "person_entry_building_building_name_fk", + "tableFrom": "person_entry", + "tableTo": "building", + "columnsFrom": ["building"], + "columnsTo": ["name"], + "onDelete": "restrict", + "onUpdate": "cascade" + }, + "person_entry_creator_user_username_fk": { + "name": "person_entry_creator_user_username_fk", + "tableFrom": "person_entry", + "tableTo": "user", + "columnsFrom": ["creator"], + "columnsTo": ["username"], + "onDelete": "no action", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": { + "person_entry_person_id_timestamp_pk": { + "name": "person_entry_person_id_timestamp_pk", + "columns": ["person_id", "timestamp"] + } + }, + "uniqueConstraints": {} + }, + "public.person_exit": { + "name": "person_exit", + "schema": "", + "columns": { + "person_id": { + "name": "person_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "building": { + "name": "building", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "creator": { + "name": "creator", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "person_exit_person_id_person_id_fk": { + "name": "person_exit_person_id_person_id_fk", + "tableFrom": "person_exit", + "tableTo": "person", + "columnsFrom": ["person_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "person_exit_building_building_name_fk": { + "name": "person_exit_building_building_name_fk", + "tableFrom": "person_exit", + "tableTo": "building", + "columnsFrom": ["building"], + "columnsTo": ["name"], + "onDelete": "restrict", + "onUpdate": "cascade" + }, + "person_exit_creator_user_username_fk": { + "name": "person_exit_creator_user_username_fk", + "tableFrom": "person_exit", + "tableTo": "user", + "columnsFrom": ["creator"], + "columnsTo": ["username"], + "onDelete": "no action", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": { + "person_exit_person_id_timestamp_pk": { + "name": "person_exit_person_id_timestamp_pk", + "columns": ["person_id", "timestamp"] + } + }, + "uniqueConstraints": {} + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "building": { + "name": "building", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "no action", + "onUpdate": "no action" + }, + "session_building_building_name_fk": { + "name": "session_building_building_name_fk", + "tableFrom": "session", + "tableTo": "building", + "columnsFrom": ["building"], + "columnsTo": ["name"], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.ratelimit": { + "name": "ratelimit", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "lock": { + "name": "lock", + "type": "boolean", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "ratelimit_user_id_user_id_fk": { + "name": "ratelimit_user_id_user_id_fk", + "tableFrom": "ratelimit", + "tableTo": "user", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "disabled": { + "name": "disabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_username_unique": { + "name": "user_username_unique", + "nullsNotDistinct": false, + "columns": ["username"] + } + } + } + }, + "enums": {}, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index 3686ea3..c76fac1 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -1,69 +1,69 @@ { - "version": "7", - "dialect": "postgresql", - "entries": [ - { - "idx": 0, - "version": "7", - "when": 1734108654159, - "tag": "0000_early_jimmy_woo", - "breakpoints": true - }, - { - "idx": 1, - "version": "7", - "when": 1734543952685, - "tag": "0001_steady_luke_cage", - "breakpoints": true - }, - { - "idx": 2, - "version": "7", - "when": 1735346155508, - "tag": "0002_known_marvel_apes", - "breakpoints": true - }, - { - "idx": 3, - "version": "7", - "when": 1735490914685, - "tag": "0003_bumpy_hardball", - "breakpoints": true - }, - { - "idx": 4, - "version": "7", - "when": 1735611551493, - "tag": "0004_lush_miss_america", - "breakpoints": true - }, - { - "idx": 5, - "version": "7", - "when": 1735611722346, - "tag": "0005_lucky_madame_web", - "breakpoints": true - }, - { - "idx": 6, - "version": "7", - "when": 1735613817511, - "tag": "0006_fearless_photon", - "breakpoints": true - }, - { - "idx": 7, - "version": "7", - "when": 1735856957839, - "tag": "0007_aspiring_zombie", - "breakpoints": true - }, - { - "idx": 8, - "version": "7", - "when": 1738173678327, - "tag": "0008_lush_selene", - "breakpoints": true - } - ] -} \ No newline at end of file + "version": "7", + "dialect": "postgresql", + "entries": [ + { + "idx": 0, + "version": "7", + "when": 1734108654159, + "tag": "0000_early_jimmy_woo", + "breakpoints": true + }, + { + "idx": 1, + "version": "7", + "when": 1734543952685, + "tag": "0001_steady_luke_cage", + "breakpoints": true + }, + { + "idx": 2, + "version": "7", + "when": 1735346155508, + "tag": "0002_known_marvel_apes", + "breakpoints": true + }, + { + "idx": 3, + "version": "7", + "when": 1735490914685, + "tag": "0003_bumpy_hardball", + "breakpoints": true + }, + { + "idx": 4, + "version": "7", + "when": 1735611551493, + "tag": "0004_lush_miss_america", + "breakpoints": true + }, + { + "idx": 5, + "version": "7", + "when": 1735611722346, + "tag": "0005_lucky_madame_web", + "breakpoints": true + }, + { + "idx": 6, + "version": "7", + "when": 1735613817511, + "tag": "0006_fearless_photon", + "breakpoints": true + }, + { + "idx": 7, + "version": "7", + "when": 1735856957839, + "tag": "0007_aspiring_zombie", + "breakpoints": true + }, + { + "idx": 8, + "version": "7", + "when": 1738173678327, + "tag": "0008_lush_selene", + "breakpoints": true + } + ] +}