diff --git a/migrations/0004_smart_maelstrom.sql b/migrations/0004_smart_maelstrom.sql new file mode 100644 index 0000000..5982edc --- /dev/null +++ b/migrations/0004_smart_maelstrom.sql @@ -0,0 +1,15 @@ +CREATE TABLE IF NOT EXISTS "session" ( + "id" text PRIMARY KEY NOT NULL, + "user_id" text NOT NULL, + "expires_at" timestamp with time zone NOT NULL +); +--> statement-breakpoint +CREATE TABLE IF NOT EXISTS "user" ( + "id" text PRIMARY KEY NOT NULL +); +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "session" ADD CONSTRAINT "session_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE no action ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; diff --git a/migrations/0005_glamorous_pixie.sql b/migrations/0005_glamorous_pixie.sql new file mode 100644 index 0000000..c50335d --- /dev/null +++ b/migrations/0005_glamorous_pixie.sql @@ -0,0 +1,2 @@ +ALTER TABLE "user" ADD COLUMN "username" text NOT NULL;--> statement-breakpoint +ALTER TABLE "user" ADD COLUMN "hashed_password" text NOT NULL; \ No newline at end of file diff --git a/migrations/0006_melted_leech.sql b/migrations/0006_melted_leech.sql new file mode 100644 index 0000000..202d31b --- /dev/null +++ b/migrations/0006_melted_leech.sql @@ -0,0 +1 @@ +ALTER TABLE "user" ALTER COLUMN "hashed_password" SET DATA TYPE varchar; \ No newline at end of file diff --git a/migrations/meta/0004_snapshot.json b/migrations/meta/0004_snapshot.json new file mode 100644 index 0000000..9d59b97 --- /dev/null +++ b/migrations/meta/0004_snapshot.json @@ -0,0 +1,123 @@ +{ + "id": "ccf7c336-c61f-452f-822b-b3b039bb20f9", + "prevId": "45d98527-f0a9-44fc-9658-d3c461afed95", + "version": "5", + "dialect": "pg", + "tables": { + "featuredAdventures": { + "name": "featuredAdventures", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "location": { + "name": "location", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "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" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "sharedAdventures": { + "name": "sharedAdventures", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "data": { + "name": "data", + "type": "json", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": {}, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/migrations/meta/0005_snapshot.json b/migrations/meta/0005_snapshot.json new file mode 100644 index 0000000..116f836 --- /dev/null +++ b/migrations/meta/0005_snapshot.json @@ -0,0 +1,135 @@ +{ + "id": "e91dda33-e04e-4e99-a297-21a34aa35493", + "prevId": "ccf7c336-c61f-452f-822b-b3b039bb20f9", + "version": "5", + "dialect": "pg", + "tables": { + "featuredAdventures": { + "name": "featuredAdventures", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "location": { + "name": "location", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "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" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "sharedAdventures": { + "name": "sharedAdventures", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "data": { + "name": "data", + "type": "json", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hashed_password": { + "name": "hashed_password", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": {}, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/migrations/meta/0006_snapshot.json b/migrations/meta/0006_snapshot.json new file mode 100644 index 0000000..2b36a76 --- /dev/null +++ b/migrations/meta/0006_snapshot.json @@ -0,0 +1,135 @@ +{ + "id": "b0849b3e-02e1-42e1-b07c-6fa613c98e82", + "prevId": "e91dda33-e04e-4e99-a297-21a34aa35493", + "version": "5", + "dialect": "pg", + "tables": { + "featuredAdventures": { + "name": "featuredAdventures", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "location": { + "name": "location", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "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" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "sharedAdventures": { + "name": "sharedAdventures", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "data": { + "name": "data", + "type": "json", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hashed_password": { + "name": "hashed_password", + "type": "varchar", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": {}, + "schemas": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/migrations/meta/_journal.json b/migrations/meta/_journal.json index 5af8112..ff1ddfe 100644 --- a/migrations/meta/_journal.json +++ b/migrations/meta/_journal.json @@ -29,6 +29,27 @@ "when": 1712083977580, "tag": "0003_clammy_goblin_queen", "breakpoints": true + }, + { + "idx": 4, + "version": "5", + "when": 1712103855532, + "tag": "0004_smart_maelstrom", + "breakpoints": true + }, + { + "idx": 5, + "version": "5", + "when": 1712104331399, + "tag": "0005_glamorous_pixie", + "breakpoints": true + }, + { + "idx": 6, + "version": "5", + "when": 1712105206127, + "tag": "0006_melted_leech", + "breakpoints": true } ] } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e084878..caa4707 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,9 @@ "name": "adventurelog", "version": "0.0.1", "dependencies": { + "@lucia-auth/adapter-drizzle": "^1.0.7", "drizzle-orm": "^0.30.6", + "oslo": "^1.2.0", "postgres": "^3.4.4" }, "devDependencies": { @@ -18,11 +20,13 @@ "@sveltejs/kit": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0", "@tailwindcss/typography": "^0.5.12", + "@types/pg": "^8.11.4", "autoprefixer": "^10.4.19", "daisyui": "^4.9.0", "dotenv": "^16.4.5", "drizzle-kit": "^0.20.14", - "pg": "^8.11.4", + "lucia": "^3.1.1", + "pg": "^8.11.5", "postcss": "^8.4.38", "svelte": "^4.2.7", "svelte-check": "^3.6.0", @@ -66,6 +70,24 @@ "superjson": "^2.2.1" } }, + "node_modules/@emnapi/core": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-0.45.0.tgz", + "integrity": "sha512-DPWjcUDQkCeEM4VnljEOEcXdAD7pp8zSZsgOujk/LGIwCXWbXJngin+MO4zbH429lzeC3WbYLGjE2MaUOwzpyw==", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "0.45.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-0.45.0.tgz", + "integrity": "sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w==", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@esbuild-kit/core-utils": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz", @@ -908,6 +930,14 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@lucia-auth/adapter-drizzle": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@lucia-auth/adapter-drizzle/-/adapter-drizzle-1.0.7.tgz", + "integrity": "sha512-X/V7fLBca8EC/gPXCntwbQpb0+F9oEuRoHElvsi9rCrdnGhCMNxHgwAvgiQ6pes+rIYpyvx4n3hvjqo/fPo03A==", + "peerDependencies": { + "lucia": "3.x" + } + }, "node_modules/@mapbox/node-pre-gyp": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", @@ -943,6 +973,513 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.1.2.tgz", + "integrity": "sha512-8JuczewTFIZ/XIjHQ+YlQUydHvlKx2hkcxtuGwh+t/t5zWyZct6YG4+xjHcq8xyc/e7FmFwf42Zj2YgICwmlvA==", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.1.0", + "@emnapi/runtime": "^1.1.0", + "@tybys/wasm-util": "^0.8.1" + } + }, + "node_modules/@napi-rs/wasm-runtime/node_modules/@emnapi/core": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.1.1.tgz", + "integrity": "sha512-eu4KjHfXg3I+UUR7vSuwZXpRo4c8h4Rtb5Lu2F7Z4JqJFl/eidquONEBiRs6viXKpWBC3BaJBy68xGJ2j56idw==", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@napi-rs/wasm-runtime/node_modules/@emnapi/runtime": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.1.1.tgz", + "integrity": "sha512-3bfqkzuR1KLx57nZfjr2NLnFOobvyS0aTszaEGCGqmYMVDRaGvgIZbjGSV/MHSSmLgQ/b9JFHQ5xm5WRZYd+XQ==", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@node-rs/argon2": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2/-/argon2-1.7.0.tgz", + "integrity": "sha512-zfULc+/tmcWcxn+nHkbyY8vP3+MpEqKORbszt4UkpqZgBgDAAIYvuDN/zukfTgdmo6tmJKKVfzigZOPk4LlIog==", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@node-rs/argon2-android-arm-eabi": "1.7.0", + "@node-rs/argon2-android-arm64": "1.7.0", + "@node-rs/argon2-darwin-arm64": "1.7.0", + "@node-rs/argon2-darwin-x64": "1.7.0", + "@node-rs/argon2-freebsd-x64": "1.7.0", + "@node-rs/argon2-linux-arm-gnueabihf": "1.7.0", + "@node-rs/argon2-linux-arm64-gnu": "1.7.0", + "@node-rs/argon2-linux-arm64-musl": "1.7.0", + "@node-rs/argon2-linux-x64-gnu": "1.7.0", + "@node-rs/argon2-linux-x64-musl": "1.7.0", + "@node-rs/argon2-wasm32-wasi": "1.7.0", + "@node-rs/argon2-win32-arm64-msvc": "1.7.0", + "@node-rs/argon2-win32-ia32-msvc": "1.7.0", + "@node-rs/argon2-win32-x64-msvc": "1.7.0" + } + }, + "node_modules/@node-rs/argon2-android-arm-eabi": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm-eabi/-/argon2-android-arm-eabi-1.7.0.tgz", + "integrity": "sha512-udDqkr5P9E+wYX1SZwAVPdyfYvaF4ry9Tm+R9LkfSHbzWH0uhU6zjIwNRp7m+n4gx691rk+lqqDAIP8RLKwbhg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-android-arm64": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm64/-/argon2-android-arm64-1.7.0.tgz", + "integrity": "sha512-s9j/G30xKUx8WU50WIhF0fIl1EdhBGq0RQ06lEhZ0Gi0ap8lhqbE2Bn5h3/G2D1k0Dx+yjeVVNmt/xOQIRG38A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-darwin-arm64": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-darwin-arm64/-/argon2-darwin-arm64-1.7.0.tgz", + "integrity": "sha512-ZIz4L6HGOB9U1kW23g+m7anGNuTZ0RuTw0vNp3o+2DWpb8u8rODq6A8tH4JRL79S+Co/Nq608m9uackN2pe0Rw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-darwin-x64": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-darwin-x64/-/argon2-darwin-x64-1.7.0.tgz", + "integrity": "sha512-5oi/pxqVhODW/pj1+3zElMTn/YukQeywPHHYDbcAW3KsojFjKySfhcJMd1DjKTc+CHQI+4lOxZzSUzK7mI14Hw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-freebsd-x64": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-freebsd-x64/-/argon2-freebsd-x64-1.7.0.tgz", + "integrity": "sha512-Ify08683hA4QVXYoIm5SUWOY5DPIT/CMB0CQT+IdxQAg/F+qp342+lUkeAtD5bvStQuCx/dFO3bnnzoe2clMhA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-linux-arm-gnueabihf": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm-gnueabihf/-/argon2-linux-arm-gnueabihf-1.7.0.tgz", + "integrity": "sha512-7DjDZ1h5AUHAtRNjD19RnQatbhL+uuxBASuuXIBu4/w6Dx8n7YPxwTP4MXfsvuRgKuMWiOb/Ub/HJ3kXVCXRkg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-linux-arm64-gnu": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-gnu/-/argon2-linux-arm64-gnu-1.7.0.tgz", + "integrity": "sha512-nJDoMP4Y3YcqGswE4DvP080w6O24RmnFEDnL0emdI8Nou17kNYBzP2546Nasx9GCyLzRcYQwZOUjrtUuQ+od2g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-linux-arm64-musl": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-musl/-/argon2-linux-arm64-musl-1.7.0.tgz", + "integrity": "sha512-BKWS8iVconhE3jrb9mj6t1J9vwUqQPpzCbUKxfTGJfc+kNL58F1SXHBoe2cDYGnHrFEHTY0YochzXoAfm4Dm/A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-linux-x64-gnu": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-gnu/-/argon2-linux-x64-gnu-1.7.0.tgz", + "integrity": "sha512-EmgqZOlf4Jurk/szW1iTsVISx25bKksVC5uttJDUloTgsAgIGReCpUUO1R24pBhu9ESJa47iv8NSf3yAfGv6jQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-linux-x64-musl": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-musl/-/argon2-linux-x64-musl-1.7.0.tgz", + "integrity": "sha512-/o1efYCYIxjfuoRYyBTi2Iy+1iFfhqHCvvVsnjNSgO1xWiWrX0Rrt/xXW5Zsl7vS2Y+yu8PL8KFWRzZhaVxfKA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-wasm32-wasi": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-wasm32-wasi/-/argon2-wasm32-wasi-1.7.0.tgz", + "integrity": "sha512-Evmk9VcxqnuwQftfAfYEr6YZYSPLzmKUsbFIMep5nTt9PT4XYRFAERj7wNYp+rOcBenF3X4xoB+LhwcOMTNE5w==", + "cpu": [ + "wasm32" + ], + "optional": true, + "dependencies": { + "@emnapi/core": "^0.45.0", + "@emnapi/runtime": "^0.45.0", + "@tybys/wasm-util": "^0.8.1", + "memfs-browser": "^3.4.13000" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@node-rs/argon2-win32-arm64-msvc": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-arm64-msvc/-/argon2-win32-arm64-msvc-1.7.0.tgz", + "integrity": "sha512-qgsU7T004COWWpSA0tppDqDxbPLgg8FaU09krIJ7FBl71Sz8SFO40h7fDIjfbTT5w7u6mcaINMQ5bSHu75PCaA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-win32-ia32-msvc": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-ia32-msvc/-/argon2-win32-ia32-msvc-1.7.0.tgz", + "integrity": "sha512-JGafwWYQ/HpZ3XSwP4adQ6W41pRvhcdXvpzIWtKvX+17+xEXAe2nmGWM6s27pVkg1iV2ZtoYLRDkOUoGqZkCcg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/argon2-win32-x64-msvc": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-x64-msvc/-/argon2-win32-x64-msvc-1.7.0.tgz", + "integrity": "sha512-9oq4ShyFakw8AG3mRls0AoCpxBFcimYx7+jvXeAf2OqKNO+mSA6eZ9z7KQeVCi0+SOEUYxMGf5UiGiDb9R6+9Q==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt/-/bcrypt-1.9.0.tgz", + "integrity": "sha512-u2OlIxW264bFUfvbFqDz9HZKFjwe8FHFtn7T/U8mYjPZ7DWYpbUB+/dkW/QgYfMSfR0ejkyuWaBBe0coW7/7ig==", + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@node-rs/bcrypt-android-arm-eabi": "1.9.0", + "@node-rs/bcrypt-android-arm64": "1.9.0", + "@node-rs/bcrypt-darwin-arm64": "1.9.0", + "@node-rs/bcrypt-darwin-x64": "1.9.0", + "@node-rs/bcrypt-freebsd-x64": "1.9.0", + "@node-rs/bcrypt-linux-arm-gnueabihf": "1.9.0", + "@node-rs/bcrypt-linux-arm64-gnu": "1.9.0", + "@node-rs/bcrypt-linux-arm64-musl": "1.9.0", + "@node-rs/bcrypt-linux-x64-gnu": "1.9.0", + "@node-rs/bcrypt-linux-x64-musl": "1.9.0", + "@node-rs/bcrypt-wasm32-wasi": "1.9.0", + "@node-rs/bcrypt-win32-arm64-msvc": "1.9.0", + "@node-rs/bcrypt-win32-ia32-msvc": "1.9.0", + "@node-rs/bcrypt-win32-x64-msvc": "1.9.0" + } + }, + "node_modules/@node-rs/bcrypt-android-arm-eabi": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm-eabi/-/bcrypt-android-arm-eabi-1.9.0.tgz", + "integrity": "sha512-nOCFISGtnodGHNiLrG0WYLWr81qQzZKYfmwHc7muUeq+KY0sQXyHOwZk9OuNQAWv/lnntmtbwkwT0QNEmOyLvA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-android-arm64": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm64/-/bcrypt-android-arm64-1.9.0.tgz", + "integrity": "sha512-+ZrIAtigVmjYkqZQTThHVlz0+TG6D+GDHWhVKvR2DifjtqJ0i+mb9gjo++hN+fWEQdWNGxKCiBBjwgT4EcXd6A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-darwin-arm64": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-arm64/-/bcrypt-darwin-arm64-1.9.0.tgz", + "integrity": "sha512-CQiS+F9Pa0XozvkXR1g7uXE9QvBOPOplDg0iCCPRYTN9PqA5qYxhwe48G3o+v2UeQceNRrbnEtWuANm7JRqIhw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-darwin-x64": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-x64/-/bcrypt-darwin-x64-1.9.0.tgz", + "integrity": "sha512-4pTKGawYd7sNEjdJ7R/R67uwQH1VvwPZ0SSUMmeNHbxD5QlwAPXdDH11q22uzVXsvNFZ6nGQBg8No5OUGpx6Ug==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-freebsd-x64": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-freebsd-x64/-/bcrypt-freebsd-x64-1.9.0.tgz", + "integrity": "sha512-UmWzySX4BJhT/B8xmTru6iFif3h0Rpx3TqxRLCcbgmH43r7k5/9QuhpiyzpvKGpKHJCFNm4F3rC2wghvw5FCIg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-linux-arm-gnueabihf": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm-gnueabihf/-/bcrypt-linux-arm-gnueabihf-1.9.0.tgz", + "integrity": "sha512-8qoX4PgBND2cVwsbajoAWo3NwdfJPEXgpCsZQZURz42oMjbGyhhSYbovBCskGU3EBLoC8RA2B1jFWooeYVn5BA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-linux-arm64-gnu": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-gnu/-/bcrypt-linux-arm64-gnu-1.9.0.tgz", + "integrity": "sha512-TuAC6kx0SbcIA4mSEWPi+OCcDjTQUMl213v5gMNlttF+D4ieIZx6pPDGTaMO6M2PDHTeCG0CBzZl0Lu+9b0c7Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-linux-arm64-musl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-musl/-/bcrypt-linux-arm64-musl-1.9.0.tgz", + "integrity": "sha512-/sIvKDABOI8QOEnLD7hIj02BVaNOuCIWBKvxcJOt8+TuwJ6zmY1UI5kSv9d99WbiHjTp97wtAUbZQwauU4b9ew==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-linux-x64-gnu": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-gnu/-/bcrypt-linux-x64-gnu-1.9.0.tgz", + "integrity": "sha512-DyyhDHDsLBsCKz1tZ1hLvUZSc1DK0FU0v52jK6IBQxrj24WscSU9zZe7ie/V9kdmA4Ep57BfpWX8Dsa2JxGdgQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-linux-x64-musl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-musl/-/bcrypt-linux-x64-musl-1.9.0.tgz", + "integrity": "sha512-duIiuqQ+Lew8ASSAYm6ZRqcmfBGWwsi81XLUwz86a2HR7Qv6V4yc3ZAUQovAikhjCsIqe8C11JlAZSK6+PlXYg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-wasm32-wasi": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-wasm32-wasi/-/bcrypt-wasm32-wasi-1.9.0.tgz", + "integrity": "sha512-ylaGmn9Wjwv/D5lxtawttx3H6Uu2WTTR7lWlRHGT6Ga/MB1Vj4OjSGUW8G8zIVnKuXpGbZ92pgHlt4HUpSLctw==", + "cpu": [ + "wasm32" + ], + "optional": true, + "dependencies": { + "@emnapi/core": "^0.45.0", + "@emnapi/runtime": "^0.45.0", + "@tybys/wasm-util": "^0.8.1", + "memfs-browser": "^3.4.13000" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@node-rs/bcrypt-win32-arm64-msvc": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-arm64-msvc/-/bcrypt-win32-arm64-msvc-1.9.0.tgz", + "integrity": "sha512-2h86gF7QFyEzODuDFml/Dp1MSJoZjxJ4yyT2Erf4NkwsiA5MqowUhUsorRwZhX6+2CtlGa7orbwi13AKMsYndw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-win32-ia32-msvc": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-ia32-msvc/-/bcrypt-win32-ia32-msvc-1.9.0.tgz", + "integrity": "sha512-kqxalCvhs4FkN0+gWWfa4Bdy2NQAkfiqq/CEf6mNXC13RSV673Ev9V8sRlQyNpCHCNkeXfOT9pgoBdJmMs9muA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@node-rs/bcrypt-win32-x64-msvc": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-x64-msvc/-/bcrypt-win32-x64-msvc-1.9.0.tgz", + "integrity": "sha512-2y0Tuo6ZAT2Cz8V7DHulSlv1Bip3zbzeXyeur+uR25IRNYXKvI/P99Zl85Fbuu/zzYAZRLLlGTRe6/9IHofe/w==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1887,6 +2424,15 @@ "node": ">=4" } }, + "node_modules/@tybys/wasm-util": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.8.1.tgz", + "integrity": "sha512-GSsTwyBl4pIzsxAY5wroZdyQKyhXk0d8PCRZtrSZ2WEB1cBdrp2EgGBwHOGCZtIIPun/DL3+AykCv+J6fyRH4Q==", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", @@ -1899,6 +2445,83 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/node": { + "version": "20.12.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.3.tgz", + "integrity": "sha512-sD+ia2ubTeWrOu+YMF+MTAB7E+O7qsMqAbMfW7DG3K1URwhZ5hN1pLlRVGbf4wDFzSfikL05M17EyorS86jShw==", + "devOptional": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/pg": { + "version": "8.11.4", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.11.4.tgz", + "integrity": "sha512-yw3Bwbda6vO+NvI1Ue/YKOwtl31AYvvd/e73O3V4ZkNzuGpTDndLSyc0dQRB2xrQqDePd20pEGIfqSp/GH3pRw==", + "devOptional": true, + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^4.0.1" + } + }, + "node_modules/@types/pg/node_modules/pg-types": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-4.0.2.tgz", + "integrity": "sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==", + "devOptional": true, + "dependencies": { + "pg-int8": "1.0.1", + "pg-numeric": "1.0.2", + "postgres-array": "~3.0.1", + "postgres-bytea": "~3.0.0", + "postgres-date": "~2.1.0", + "postgres-interval": "^3.0.0", + "postgres-range": "^1.1.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/pg/node_modules/postgres-array": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.2.tgz", + "integrity": "sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==", + "devOptional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@types/pg/node_modules/postgres-bytea": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-3.0.0.tgz", + "integrity": "sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==", + "devOptional": true, + "dependencies": { + "obuf": "~1.1.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@types/pg/node_modules/postgres-date": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-2.1.0.tgz", + "integrity": "sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==", + "devOptional": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/@types/pg/node_modules/postgres-interval": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-3.0.0.tgz", + "integrity": "sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==", + "devOptional": true, + "engines": { + "node": ">=12" + } + }, "node_modules/@types/pug": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", @@ -3548,6 +4171,12 @@ "node": ">=8" } }, + "node_modules/fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", + "optional": true + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4028,6 +4657,495 @@ "es5-ext": "~0.10.2" } }, + "node_modules/lucia": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lucia/-/lucia-3.1.1.tgz", + "integrity": "sha512-Ygvgnqq7Ha7lYVaZATPwkPD2s2Qlsm71Z2o0byx/abNBfFldCRow5sNii6RqMsuMpK957RAI3Gw4/aWoagkc7A==", + "dependencies": { + "oslo": "1.0.1" + } + }, + "node_modules/lucia/node_modules/@node-rs/argon2": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2/-/argon2-1.7.2.tgz", + "integrity": "sha512-+H6pc3M1vIX9YnG59YW7prHhhpv19P8YyxlXHnnFzTimf2q+kKDF7mGWbhvN9STqIY+P70Patn0Q6qb6Ib5/4g==", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@node-rs/argon2-android-arm-eabi": "1.7.2", + "@node-rs/argon2-android-arm64": "1.7.2", + "@node-rs/argon2-darwin-arm64": "1.7.2", + "@node-rs/argon2-darwin-x64": "1.7.2", + "@node-rs/argon2-freebsd-x64": "1.7.2", + "@node-rs/argon2-linux-arm-gnueabihf": "1.7.2", + "@node-rs/argon2-linux-arm64-gnu": "1.7.2", + "@node-rs/argon2-linux-arm64-musl": "1.7.2", + "@node-rs/argon2-linux-x64-gnu": "1.7.2", + "@node-rs/argon2-linux-x64-musl": "1.7.2", + "@node-rs/argon2-wasm32-wasi": "1.7.2", + "@node-rs/argon2-win32-arm64-msvc": "1.7.2", + "@node-rs/argon2-win32-ia32-msvc": "1.7.2", + "@node-rs/argon2-win32-x64-msvc": "1.7.2" + } + }, + "node_modules/lucia/node_modules/@node-rs/argon2-android-arm-eabi": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm-eabi/-/argon2-android-arm-eabi-1.7.2.tgz", + "integrity": "sha512-WhW84XOzdR4AOGc4BJvIg5lCRVBL0pXp/PPCe8QCyWw493p7VdNCdYpr2xdtjS/0zImmY85HNB/6zpzjLRTT/A==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/argon2-android-arm64": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-android-arm64/-/argon2-android-arm64-1.7.2.tgz", + "integrity": "sha512-CdtayHSMIyDuVhSYFirwA757c4foQuyTjpysgFJLHweP9C7uDiBf9WBYij+UyabpaCadJ0wPyK6Vakinvlk4/g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/argon2-darwin-arm64": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-darwin-arm64/-/argon2-darwin-arm64-1.7.2.tgz", + "integrity": "sha512-hUOhtgYHTEyzX5sgMZVdXunONOus2HWpWydF5D/RYJ1mZ76FXRnFpQE40DqbzisdPIraKdn40m7JqkPP7wqdyg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/argon2-darwin-x64": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-darwin-x64/-/argon2-darwin-x64-1.7.2.tgz", + "integrity": "sha512-lfs5HX+t542yUfcv6Aa/NeGD1nUCwyQNgnPEGcik71Ow6V13hkR1bHgmT1u3CHN4fBts0gW+DQEDsq1xlVgkvw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/argon2-freebsd-x64": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-freebsd-x64/-/argon2-freebsd-x64-1.7.2.tgz", + "integrity": "sha512-ROoF+4VaCBJUjddrTN1hjuqSl89ppRcjVXJscSPJjWzTlbzFmGGovJvIzUBmCr/Oq3yM1zKHj6MP9oRD5cB+/g==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/argon2-linux-arm-gnueabihf": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm-gnueabihf/-/argon2-linux-arm-gnueabihf-1.7.2.tgz", + "integrity": "sha512-CBSB8KPI8LS74Bcz3dYaa2/khULutz4vSDvFWUERlSLX+mPdDhoZi6UPuUPPF9e01w8AbiK1YCqlLUTm3tIMfw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/argon2-linux-arm64-gnu": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-gnu/-/argon2-linux-arm64-gnu-1.7.2.tgz", + "integrity": "sha512-6LBTug6ZiWFakP3X3Nqs7ZTM03gmcSWX4YvEn20HhhQE5NDrsrw3zNqGj0cJiNzKKIMSDDuj7uGy+ITEfNo4CA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/argon2-linux-arm64-musl": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-arm64-musl/-/argon2-linux-arm64-musl-1.7.2.tgz", + "integrity": "sha512-KjhQ+ZPne29t9VRVeIif7JdKwQba+tM6CBNYBoJB1iON0CUKeqSQtZcHuTj9gkf2SNRG5bsU4ABcfxd0OKsKHg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/argon2-linux-x64-gnu": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-gnu/-/argon2-linux-x64-gnu-1.7.2.tgz", + "integrity": "sha512-BQvp+iLtKqomHz4q5t1aKoni9osgvUDU5sZtHAlFm5dRTlGHnympcQVATRE5GHyH9C6MIM9W7P1kqEeCLGPolQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/argon2-linux-x64-musl": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-linux-x64-musl/-/argon2-linux-x64-musl-1.7.2.tgz", + "integrity": "sha512-yXJudpBZQ98g+lWaHn9EzZ5KsAyqRdlpub/K+5NP7gHehb8wzBRIFAejIHAG0fvzQEEc86VOnV2koWIVZxWAvw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/argon2-wasm32-wasi": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-wasm32-wasi/-/argon2-wasm32-wasi-1.7.2.tgz", + "integrity": "sha512-diXlVjJZY2GIV8ZDwUqXPhacXsFR0klGSv5D9f+XidwWXK4udtzDhkM/7N/Mb7h1HAWaxZ6IN9spYFjvWH1wqg==", + "cpu": [ + "wasm32" + ], + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.1.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/lucia/node_modules/@node-rs/argon2-win32-arm64-msvc": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-arm64-msvc/-/argon2-win32-arm64-msvc-1.7.2.tgz", + "integrity": "sha512-dhIBrY04P9nbmwzBpgERQDmmSu4YBZyeEE32t4TikMz5rQ07iaVC+JpGmtCBZoDIsLDHGC8cikENd3YEqpqIcA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/argon2-win32-ia32-msvc": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-ia32-msvc/-/argon2-win32-ia32-msvc-1.7.2.tgz", + "integrity": "sha512-o1tfqr8gyALCzuxBoQfvhxkeYMaw/0H8Gmt7klTYyEIBvEFu7SD5qytXO9Px7t5420nZL/Wy5cflg3IB1s57Pg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/argon2-win32-x64-msvc": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@node-rs/argon2-win32-x64-msvc/-/argon2-win32-x64-msvc-1.7.2.tgz", + "integrity": "sha512-v0h53XUc7hNgWiWi0qcMcHvj9/kwuItI9NwLK4C+gtzT3UB0cedhfIL8HFMKThMXasy41ZdbpCF2Bi0kJoLNEg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/bcrypt": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt/-/bcrypt-1.9.2.tgz", + "integrity": "sha512-FKUo9iCSIti+ldwoOlY1ztyIFhZxEgT7jZ/UCt/9bg1rLmNdbQQD2JKIMImDCqmTWuLPY4ZF4Q5MyOMIfDCd8Q==", + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@node-rs/bcrypt-android-arm-eabi": "1.9.2", + "@node-rs/bcrypt-android-arm64": "1.9.2", + "@node-rs/bcrypt-darwin-arm64": "1.9.2", + "@node-rs/bcrypt-darwin-x64": "1.9.2", + "@node-rs/bcrypt-freebsd-x64": "1.9.2", + "@node-rs/bcrypt-linux-arm-gnueabihf": "1.9.2", + "@node-rs/bcrypt-linux-arm64-gnu": "1.9.2", + "@node-rs/bcrypt-linux-arm64-musl": "1.9.2", + "@node-rs/bcrypt-linux-x64-gnu": "1.9.2", + "@node-rs/bcrypt-linux-x64-musl": "1.9.2", + "@node-rs/bcrypt-wasm32-wasi": "1.9.2", + "@node-rs/bcrypt-win32-arm64-msvc": "1.9.2", + "@node-rs/bcrypt-win32-ia32-msvc": "1.9.2", + "@node-rs/bcrypt-win32-x64-msvc": "1.9.2" + } + }, + "node_modules/lucia/node_modules/@node-rs/bcrypt-android-arm-eabi": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm-eabi/-/bcrypt-android-arm-eabi-1.9.2.tgz", + "integrity": "sha512-er/Q2khwpan9pczvTTqY/DJE4UU65u31xd0NkZlHUTKyB7djRhWfzoGexGx2GN+k831/RR3U8kKE/8QUHeO3hQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/bcrypt-android-arm64": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-android-arm64/-/bcrypt-android-arm64-1.9.2.tgz", + "integrity": "sha512-OUYatOEG5vbLbF73q2TC8UqrDO81zUQxnaFD/OAB1hcm6J+ur0zJ8E53c35/DIqkTp7JarPMraC4rouJ2ugN4w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/bcrypt-darwin-arm64": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-arm64/-/bcrypt-darwin-arm64-1.9.2.tgz", + "integrity": "sha512-svJKsGbzMAxOB5oluOYneN4YkKUy26WSMgm3KOIhgoX30IeMilj+2jFN/5qrI0oDZ0Iczb3XyL5DuZFtEkdP8A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/bcrypt-darwin-x64": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-darwin-x64/-/bcrypt-darwin-x64-1.9.2.tgz", + "integrity": "sha512-9OrySjBi/rWix8NZWD/TrNbNcwMY0pAiMHdL09aJnJ07uPih83GGh1pq4UHCYFCMy7iTX8swOmDlGBUImkOZbg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/bcrypt-freebsd-x64": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-freebsd-x64/-/bcrypt-freebsd-x64-1.9.2.tgz", + "integrity": "sha512-/djXV71RO6g5L1mI2pVvmp3x3pH7G4uKI3ODG1JBIXoz334oOcCMh40sB0uq0ljP8WEadker01p4T1rJE98fpg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/bcrypt-linux-arm-gnueabihf": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm-gnueabihf/-/bcrypt-linux-arm-gnueabihf-1.9.2.tgz", + "integrity": "sha512-F7wP950OTAooxEleUN4I2hqryGZK7hi1cSgRF13Wvbc597RFux35KiSxIXUA3mNt2DE7lV2PeceEtCOScaThWQ==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/bcrypt-linux-arm64-gnu": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-gnu/-/bcrypt-linux-arm64-gnu-1.9.2.tgz", + "integrity": "sha512-MehG+yQ0TgKMgKR1rO4hdvHkVsTM91Cof8qI9EJlS5+7+QSwfFA5O0zGwCkISD7bsyauJ5uJgcByGjpEobAHOg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/bcrypt-linux-arm64-musl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-arm64-musl/-/bcrypt-linux-arm64-musl-1.9.2.tgz", + "integrity": "sha512-PRZTAJjOwKEGsIhmBvfNh81So+wGl4QyCFAt23j+KwBujLStjC0N3YaqtTlWVKG9tcriPtmMYiAQtXWIyIgg/w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/bcrypt-linux-x64-gnu": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-gnu/-/bcrypt-linux-x64-gnu-1.9.2.tgz", + "integrity": "sha512-5WfGO+O1m7nJ55WZ8XDq+ItA98Z4O7sNWsR+1nIj9YGT+Tx5zkQ2RBhpK6oCWZMluuZ0eKQ0FDmyP6K+2NDRIA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/bcrypt-linux-x64-musl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-linux-x64-musl/-/bcrypt-linux-x64-musl-1.9.2.tgz", + "integrity": "sha512-VjCn0388p6PMCVUYHgYmHZrKNc7WwNJRr2WLJsHbQRGDOKbpNL6YolCjQxUchcSPDhzwrq1cIdy4j0fpoXEsdw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/bcrypt-wasm32-wasi": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-wasm32-wasi/-/bcrypt-wasm32-wasi-1.9.2.tgz", + "integrity": "sha512-P06aHfMzm9makwU+nM7WA65yQnS1xuqJ8l/6I/LvXjnl+lfB3DtJ2B0CSLtjnUGpUgcHbWl5gEbNnTPxSAirjQ==", + "cpu": [ + "wasm32" + ], + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.1.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/lucia/node_modules/@node-rs/bcrypt-win32-arm64-msvc": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-arm64-msvc/-/bcrypt-win32-arm64-msvc-1.9.2.tgz", + "integrity": "sha512-Iyo/Q5/eNw27VRd3mLBgh1b9b5fnT3QHTVwxv3Siv/MRAIfJXH/cTOe18qSwYQzNh0ZioW4yemFPYCWSZi7szA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/bcrypt-win32-ia32-msvc": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-ia32-msvc/-/bcrypt-win32-ia32-msvc-1.9.2.tgz", + "integrity": "sha512-6LHWMaPylyyHoS5863YpxAACVB8DWCxro5W6pQ4h8WKSgHpJp8Um9jphTdN0A2w45HZjUnfcFuiFFC+TbftjCw==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/@node-rs/bcrypt-win32-x64-msvc": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@node-rs/bcrypt-win32-x64-msvc/-/bcrypt-win32-x64-msvc-1.9.2.tgz", + "integrity": "sha512-vZ9T1MOaYkLO9FTyl28YX0SYJneiYTKNFgM8PUv8nas8xrD+7OzokA0fEtlNp6413T7IKSD/iG9qi8nTWsiyGg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/lucia/node_modules/oslo": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/oslo/-/oslo-1.0.1.tgz", + "integrity": "sha512-esfzZry+HfGgK/GCYkg7BRlLd3RH5aHa08wgLJPYjENXybi0BvXxGk0LbUj+lXfz2TkjPDHe4rB/o6JxRLHxBg==", + "dependencies": { + "@node-rs/argon2": "1.7.2", + "@node-rs/bcrypt": "1.9.2" + } + }, "node_modules/magic-string": { "version": "0.30.8", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", @@ -4070,6 +5188,27 @@ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "dev": true }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "optional": true, + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/memfs-browser": { + "version": "3.5.10302", + "resolved": "https://registry.npmjs.org/memfs-browser/-/memfs-browser-3.5.10302.tgz", + "integrity": "sha512-JJTc/nh3ig05O0gBBGZjTCPOyydaTxNF0uHYBrcc1gHNnO+KIHIvo0Y1FKCJsaei6FCl8C6xfQomXqu+cuzkIw==", + "optional": true, + "dependencies": { + "memfs": "3.5.3" + } + }, "node_modules/memoizee": { "version": "0.4.15", "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", @@ -4343,6 +5482,12 @@ "node": ">= 6" } }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "devOptional": true + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -4352,6 +5497,15 @@ "wrappy": "1" } }, + "node_modules/oslo": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/oslo/-/oslo-1.2.0.tgz", + "integrity": "sha512-OoFX6rDsNcOQVAD2gQD/z03u4vEjWZLzJtwkmgfRF+KpQUXwdgEXErD7zNhyowmHwHefP+PM9Pw13pgpHMRlzw==", + "dependencies": { + "@node-rs/argon2": "1.7.0", + "@node-rs/bcrypt": "1.9.0" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -4416,12 +5570,12 @@ } }, "node_modules/pg": { - "version": "8.11.4", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.4.tgz", - "integrity": "sha512-pWb7JKPxGk1UFbtq7jQ0m3IfPpb7LLACCEyN8/u9DYEom+Q/BSKy+4TRl4+Hh003AOYhppB/z+QK87/hx/bk0w==", + "version": "8.11.5", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.5.tgz", + "integrity": "sha512-jqgNHSKL5cbDjFlHyYsCXmQDrfIX/3RsNwYqpd4N0Kt8niLuNoRNH+aazv6cOd43gPh9Y4DjQCtb+X0MH0Hvnw==", "devOptional": true, "dependencies": { - "pg-connection-string": "^2.6.3", + "pg-connection-string": "^2.6.4", "pg-pool": "^3.6.2", "pg-protocol": "^1.6.1", "pg-types": "^2.1.0", @@ -4450,9 +5604,9 @@ "optional": true }, "node_modules/pg-connection-string": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.3.tgz", - "integrity": "sha512-77FxhhKJQH+xJx6tDqkhhMa0nZvv3U1HYLDQgwZxZafVD583++O5LXn5oo5HaQZ0vXwYcZA1koYAJM3JvD6Gtw==", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz", + "integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==", "devOptional": true }, "node_modules/pg-int8": { @@ -4464,6 +5618,15 @@ "node": ">=4.0.0" } }, + "node_modules/pg-numeric": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pg-numeric/-/pg-numeric-1.0.2.tgz", + "integrity": "sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==", + "devOptional": true, + "engines": { + "node": ">=4" + } + }, "node_modules/pg-pool": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.2.tgz", @@ -4740,6 +5903,12 @@ "node": ">=0.10.0" } }, + "node_modules/postgres-range": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/postgres-range/-/postgres-range-1.1.4.tgz", + "integrity": "sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==", + "devOptional": true + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -5593,7 +6762,7 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "dev": true + "devOptional": true }, "node_modules/type": { "version": "2.7.2", @@ -5614,6 +6783,12 @@ "node": ">=14.17" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "devOptional": true + }, "node_modules/update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", diff --git a/package.json b/package.json index 9613ca6..6b54d1a 100644 --- a/package.json +++ b/package.json @@ -21,11 +21,13 @@ "@sveltejs/kit": "^2.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0", "@tailwindcss/typography": "^0.5.12", + "@types/pg": "^8.11.4", "autoprefixer": "^10.4.19", "daisyui": "^4.9.0", "dotenv": "^16.4.5", "drizzle-kit": "^0.20.14", - "pg": "^8.11.4", + "lucia": "^3.1.1", + "pg": "^8.11.5", "postcss": "^8.4.38", "svelte": "^4.2.7", "svelte-check": "^3.6.0", @@ -36,7 +38,9 @@ }, "type": "module", "dependencies": { + "@lucia-auth/adapter-drizzle": "^1.0.7", "drizzle-orm": "^0.30.6", + "oslo": "^1.2.0", "postgres": "^3.4.4" } } diff --git a/src/app.d.ts b/src/app.d.ts index ede601a..65be1f9 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -1,12 +1,9 @@ -// See https://kit.svelte.dev/docs/types#app -// for information about these interfaces declare global { namespace App { - // interface Error {} - // interface Locals {} - // interface PageData {} - // interface PageState {} - // interface Platform {} + interface Locals { + user: import("lucia").User | null; + session: import("lucia").Session | null; + } } } diff --git a/src/hooks.server.ts b/src/hooks.server.ts new file mode 100644 index 0000000..4b48cbc --- /dev/null +++ b/src/hooks.server.ts @@ -0,0 +1,32 @@ +import { lucia } from "$lib/server/auth"; +import type { Handle } from "@sveltejs/kit"; + +export const handle: Handle = async ({ event, resolve }) => { + const sessionId = event.cookies.get(lucia.sessionCookieName); + if (!sessionId) { + event.locals.user = null; + event.locals.session = null; + return resolve(event); + } + + const { session, user } = await lucia.validateSession(sessionId); + if (session && session.fresh) { + const sessionCookie = lucia.createSessionCookie(session.id); + // sveltekit types deviates from the de-facto standard + // you can use 'as any' too + event.cookies.set(sessionCookie.name, sessionCookie.value, { + path: ".", + ...sessionCookie.attributes, + }); + } + if (!session) { + const sessionCookie = lucia.createBlankSessionCookie(); + event.cookies.set(sessionCookie.name, sessionCookie.value, { + path: ".", + ...sessionCookie.attributes, + }); + } + event.locals.user = user; + event.locals.session = session; + return resolve(event); +}; diff --git a/src/lib/db/db.server.ts b/src/lib/db/db.server.ts index 9288f10..f4fbc86 100644 --- a/src/lib/db/db.server.ts +++ b/src/lib/db/db.server.ts @@ -1,8 +1,9 @@ import { drizzle } from "drizzle-orm/postgres-js"; import postgres from "postgres"; import dotenv from "dotenv"; +import * as schema from "$lib/db/schema"; dotenv.config(); const { DATABASE_URL } = process.env; -const client = postgres(DATABASE_URL); -export const db = drizzle(client, {}); +const client = postgres(DATABASE_URL || ""); // Pass DATABASE_URL as a string argument +export const db = drizzle(client, { schema }); diff --git a/src/lib/db/schema.ts b/src/lib/db/schema.ts index f289086..e5f1264 100644 --- a/src/lib/db/schema.ts +++ b/src/lib/db/schema.ts @@ -1,4 +1,11 @@ -import { pgTable, json, text, serial } from "drizzle-orm/pg-core"; +import { + pgTable, + text, + timestamp, + json, + serial, + varchar, +} from "drizzle-orm/pg-core"; export const featuredAdventures = pgTable("featuredAdventures", { id: serial("id").primaryKey(), @@ -10,3 +17,22 @@ export const sharedAdventures = pgTable("sharedAdventures", { id: text("id").primaryKey(), data: json("data").notNull(), }); + +export const userTable = pgTable("user", { + id: text("id").primaryKey(), + username: text("username").notNull(), + hashed_password: varchar("hashed_password").notNull(), +}); + +// export type SelectUser = typeof userTable.$inferSelect; + +export const sessionTable = pgTable("session", { + id: text("id").primaryKey(), + userId: text("user_id") + .notNull() + .references(() => userTable.id), + expiresAt: timestamp("expires_at", { + withTimezone: true, + mode: "date", + }).notNull(), +}); diff --git a/src/lib/server/auth.ts b/src/lib/server/auth.ts new file mode 100644 index 0000000..2907892 --- /dev/null +++ b/src/lib/server/auth.ts @@ -0,0 +1,38 @@ +import { DrizzlePostgreSQLAdapter } from "@lucia-auth/adapter-drizzle"; +import { Lucia } from "lucia"; +import { dev } from "$app/environment"; +import { userTable, sessionTable } from "$lib/db/schema"; +import { db } from "$lib/db/db.server"; +import { Argon2id } from "oslo/password"; + +const adapter = new DrizzlePostgreSQLAdapter(db, sessionTable, userTable); + +export const lucia = new Lucia(adapter, { + sessionCookie: { + attributes: { + secure: !dev, + }, + }, + getUserAttributes: (attributes) => { + return { + // attributes has the type of DatabaseUserAttributes + username: attributes.username, + }; + }, +}); + +declare module "lucia" { + interface Register { + Lucia: typeof lucia; + DatabaseUserAttributes: DatabaseUserAttributes; + } +} + +interface DatabaseUserAttributes { + username: string; +} +export interface DatabaseUser { + id: string; + username: string; + hashed_password: string; +} diff --git a/src/routes/login/+page.server.ts b/src/routes/login/+page.server.ts new file mode 100644 index 0000000..5f05494 --- /dev/null +++ b/src/routes/login/+page.server.ts @@ -0,0 +1,76 @@ +import { lucia } from "$lib/server/auth"; +import { fail, redirect } from "@sveltejs/kit"; +import { Argon2id } from "oslo/password"; +import { db } from "$lib/db/db.server"; + +import type { Actions, PageServerLoad } from "./$types"; +import type { DatabaseUser } from "$lib/server/auth"; +import { userTable } from "$lib/db/schema"; +import { eq } from "drizzle-orm"; + +export const load: PageServerLoad = async (event) => { + if (event.locals.user) { + return redirect(302, "/"); + } + return {}; +}; + +export const actions: Actions = { + default: async (event) => { + const formData = await event.request.formData(); + const username = formData.get("username"); + const password = formData.get("password"); + + if ( + typeof username !== "string" || + username.length < 3 || + username.length > 31 || + !/^[a-z0-9_-]+$/.test(username) + ) { + return fail(400, { + message: "Invalid username", + }); + } + if ( + typeof password !== "string" || + password.length < 6 || + password.length > 255 + ) { + return fail(400, { + message: "Invalid password", + }); + } + + const existingUser = await db + .select() + .from(userTable) + .where(eq(userTable.username, username)) + .limit(1) + .then((results) => results[0] as unknown as DatabaseUser | undefined); + + if (!existingUser) { + return fail(400, { + message: "Incorrect username or password", + }); + } + + const validPassword = await new Argon2id().verify( + existingUser.hashed_password, + password + ); + if (!validPassword) { + return fail(400, { + message: "Incorrect username or password", + }); + } + + const session = await lucia.createSession(existingUser.id, {}); + const sessionCookie = lucia.createSessionCookie(session.id); + event.cookies.set(sessionCookie.name, sessionCookie.value, { + path: ".", + ...sessionCookie.attributes, + }); + + return redirect(302, "/"); + }, +}; diff --git a/src/routes/login/+page.svelte b/src/routes/login/+page.svelte new file mode 100644 index 0000000..2d865c4 --- /dev/null +++ b/src/routes/login/+page.svelte @@ -0,0 +1,13 @@ + + + +

Sign in

+
+ +
+ +
+ +
diff --git a/src/routes/signup/+page.server.ts b/src/routes/signup/+page.server.ts new file mode 100644 index 0000000..b6a99f9 --- /dev/null +++ b/src/routes/signup/+page.server.ts @@ -0,0 +1,60 @@ +// routes/signup/+page.server.ts +import { lucia } from "$lib/server/auth"; +import { fail, redirect } from "@sveltejs/kit"; +import { generateId } from "lucia"; +import { Argon2id } from "oslo/password"; +import { db } from "$lib/db/db.server"; + +import type { Actions } from "./$types"; +import { userTable } from "$lib/db/schema"; + +export const actions: Actions = { + default: async (event) => { + const formData = await event.request.formData(); + const username = formData.get("username"); + const password = formData.get("password"); + // username must be between 4 ~ 31 characters, and only consists of lowercase letters, 0-9, -, and _ + // keep in mind some database (e.g. mysql) are case insensitive + if ( + typeof username !== "string" || + username.length < 3 || + username.length > 31 || + !/^[a-z0-9_-]+$/.test(username) + ) { + return fail(400, { + message: "Invalid username", + }); + } + if ( + typeof password !== "string" || + password.length < 6 || + password.length > 255 + ) { + return fail(400, { + message: "Invalid password", + }); + } + + const userId = generateId(15); + const hashedPassword = await new Argon2id().hash(password); + + // TODO: check if username is already used + await db + .insert(userTable) + .values({ + id: userId, + username: username, + hashed_password: hashedPassword, + }) + .execute(); + + const session = await lucia.createSession(userId, {}); + const sessionCookie = lucia.createSessionCookie(session.id); + event.cookies.set(sessionCookie.name, sessionCookie.value, { + path: ".", + ...sessionCookie.attributes, + }); + + redirect(302, "/"); + }, +}; diff --git a/src/routes/signup/+page.svelte b/src/routes/signup/+page.svelte new file mode 100644 index 0000000..a553a36 --- /dev/null +++ b/src/routes/signup/+page.svelte @@ -0,0 +1,13 @@ + + + +

Sign up

+
+ +
+ +
+ +