diff --git a/bun.lock b/bun.lock index bdc1475..7babb34 100644 --- a/bun.lock +++ b/bun.lock @@ -4,9 +4,7 @@ "": { "name": "sveltekit-bsky-handles", "dependencies": { - "@node-rs/argon2": "^2.0.2", - "@oslojs/crypto": "^1.0.1", - "@oslojs/encoding": "^1.1.0", + "drizzle-orm": "^0.41.0", }, "devDependencies": { "@eslint/compat": "^1.2.5", @@ -20,12 +18,12 @@ "@testing-library/svelte": "^5.2.4", "@types/node": "^22.14.0", "drizzle-kit": "^0.30.2", - "drizzle-orm": "^0.41.0", "eslint": "^9.18.0", "eslint-config-prettier": "^10.0.1", "eslint-plugin-svelte": "^3.0.0", "globals": "^16.0.0", "jsdom": "^26.0.0", + "lodash": "^4.17.21", "prettier": "^3.4.2", "prettier-plugin-svelte": "^3.3.3", "prettier-plugin-tailwindcss": "^0.6.11", @@ -52,8 +50,6 @@ "@babel/runtime": ["@babel/runtime@7.27.0", "", { "dependencies": { "regenerator-runtime": "^0.14.0" } }, "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw=="], - "@cloudflare/workers-types": ["@cloudflare/workers-types@4.20250406.0", "", {}, "sha512-E42GP9oZFNOoykucfN9H9qaG3IeID6VMHc2zGjVuDYT2G55uESe56tstuGFYYwjMm36QeNob+ZryyiE92idFYA=="], - "@csstools/color-helpers": ["@csstools/color-helpers@5.0.2", "", {}, "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA=="], "@csstools/css-calc": ["@csstools/css-calc@2.1.2", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3" } }, "sha512-TklMyb3uBB28b5uQdxjReG4L80NxAqgrECqLZFQbyLekwwlcDDS8r3f07DKqeo8C4926Br0gf/ZDe17Zv4wIuw=="], @@ -66,12 +62,6 @@ "@drizzle-team/brocli": ["@drizzle-team/brocli@0.10.2", "", {}, "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w=="], - "@emnapi/core": ["@emnapi/core@1.4.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.1", "tslib": "^2.4.0" } }, "sha512-H+N/FqT07NmLmt6OFFtDfwe8PNygprzBikrEMyQfgqSmT0vzE515Pz7R8izwB9q/zsH/MA64AKoul3sA6/CzVg=="], - - "@emnapi/runtime": ["@emnapi/runtime@1.4.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-64WYIf4UYcdLnbKn/umDlNjQDSS8AgZrI/R9+x5ilkUVFxXcA1Ebl+gQLc/6mERA4407Xof0R7wEyEuj091CVw=="], - - "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.0.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw=="], - "@esbuild-kit/core-utils": ["@esbuild-kit/core-utils@3.3.2", "", { "dependencies": { "esbuild": "~0.18.20", "source-map-support": "^0.5.21" } }, "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ=="], "@esbuild-kit/esm-loader": ["@esbuild-kit/esm-loader@2.6.5", "", { "dependencies": { "@esbuild-kit/core-utils": "^3.3.2", "get-tsconfig": "^4.7.0" } }, "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA=="], @@ -188,54 +178,14 @@ "@libsql/win32-x64-msvc": ["@libsql/win32-x64-msvc@0.5.4", "", { "os": "win32", "cpu": "x64" }, "sha512-xWQyAQEsX+odBrMSXTpm3WOFeoJIX7QncCkaZcsaqdEFueOdNDIdcKAQKMoNlwtj1rCxE72RK4byw/Bflf6Jgg=="], - "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.8", "", { "dependencies": { "@emnapi/core": "^1.4.0", "@emnapi/runtime": "^1.4.0", "@tybys/wasm-util": "^0.9.0" } }, "sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg=="], - "@neon-rs/load": ["@neon-rs/load@0.0.4", "", {}, "sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw=="], - "@node-rs/argon2": ["@node-rs/argon2@2.0.2", "", { "optionalDependencies": { "@node-rs/argon2-android-arm-eabi": "2.0.2", "@node-rs/argon2-android-arm64": "2.0.2", "@node-rs/argon2-darwin-arm64": "2.0.2", "@node-rs/argon2-darwin-x64": "2.0.2", "@node-rs/argon2-freebsd-x64": "2.0.2", "@node-rs/argon2-linux-arm-gnueabihf": "2.0.2", "@node-rs/argon2-linux-arm64-gnu": "2.0.2", "@node-rs/argon2-linux-arm64-musl": "2.0.2", "@node-rs/argon2-linux-x64-gnu": "2.0.2", "@node-rs/argon2-linux-x64-musl": "2.0.2", "@node-rs/argon2-wasm32-wasi": "2.0.2", "@node-rs/argon2-win32-arm64-msvc": "2.0.2", "@node-rs/argon2-win32-ia32-msvc": "2.0.2", "@node-rs/argon2-win32-x64-msvc": "2.0.2" } }, "sha512-t64wIsPEtNd4aUPuTAyeL2ubxATCBGmeluaKXEMAFk/8w6AJIVVkeLKMBpgLW6LU2t5cQxT+env/c6jxbtTQBg=="], - - "@node-rs/argon2-android-arm-eabi": ["@node-rs/argon2-android-arm-eabi@2.0.2", "", { "os": "android", "cpu": "arm" }, "sha512-DV/H8p/jt40lrao5z5g6nM9dPNPGEHL+aK6Iy/og+dbL503Uj0AHLqj1Hk9aVUSCNnsDdUEKp4TVMi0YakDYKw=="], - - "@node-rs/argon2-android-arm64": ["@node-rs/argon2-android-arm64@2.0.2", "", { "os": "android", "cpu": "arm64" }, "sha512-1LKwskau+8O1ktKx7TbK7jx1oMOMt4YEXZOdSNIar1TQKxm6isZ0cRXgHLibPHEcNHgYRsJWDE9zvDGBB17QDg=="], - - "@node-rs/argon2-darwin-arm64": ["@node-rs/argon2-darwin-arm64@2.0.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-3TTNL/7wbcpNju5YcqUrCgXnXUSbD7ogeAKatzBVHsbpjZQbNb1NDxDjqqrWoTt6XL3z9mJUMGwbAk7zQltHtA=="], - - "@node-rs/argon2-darwin-x64": ["@node-rs/argon2-darwin-x64@2.0.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-vNPfkLj5Ij5111UTiYuwgxMqE7DRbOS2y58O2DIySzSHbcnu+nipmRKg+P0doRq6eKIJStyBK8dQi5Ic8pFyDw=="], - - "@node-rs/argon2-freebsd-x64": ["@node-rs/argon2-freebsd-x64@2.0.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-M8vQZk01qojQfCqQU0/O1j1a4zPPrz93zc9fSINY7Q/6RhQRBCYwDw7ltDCZXg5JRGlSaeS8cUXWyhPGar3cGg=="], - - "@node-rs/argon2-linux-arm-gnueabihf": ["@node-rs/argon2-linux-arm-gnueabihf@2.0.2", "", { "os": "linux", "cpu": "arm" }, "sha512-7EmmEPHLzcu0G2GDh30L6G48CH38roFC2dqlQJmtRCxs6no3tTE/pvgBGatTp/o2n2oyOJcfmgndVFcUpwMnww=="], - - "@node-rs/argon2-linux-arm64-gnu": ["@node-rs/argon2-linux-arm64-gnu@2.0.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-6lsYh3Ftbk+HAIZ7wNuRF4SZDtxtFTfK+HYFAQQyW7Ig3LHqasqwfUKRXVSV5tJ+xTnxjqgKzvZSUJCAyIfHew=="], - - "@node-rs/argon2-linux-arm64-musl": ["@node-rs/argon2-linux-arm64-musl@2.0.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-p3YqVMNT/4DNR67tIHTYGbedYmXxW9QlFmF39SkXyEbGQwpgSf6pH457/fyXBIYznTU/smnG9EH+C1uzT5j4hA=="], - - "@node-rs/argon2-linux-x64-gnu": ["@node-rs/argon2-linux-x64-gnu@2.0.2", "", { "os": "linux", "cpu": "x64" }, "sha512-ZM3jrHuJ0dKOhvA80gKJqBpBRmTJTFSo2+xVZR+phQcbAKRlDMSZMFDiKbSTnctkfwNFtjgDdh5g1vaEV04AvA=="], - - "@node-rs/argon2-linux-x64-musl": ["@node-rs/argon2-linux-x64-musl@2.0.2", "", { "os": "linux", "cpu": "x64" }, "sha512-of5uPqk7oCRF/44a89YlWTEfjsftPywyTULwuFDKyD8QtVZoonrJR6ZWvfFE/6jBT68S0okAkAzzMEdBVWdxWw=="], - - "@node-rs/argon2-wasm32-wasi": ["@node-rs/argon2-wasm32-wasi@2.0.2", "", { "dependencies": { "@napi-rs/wasm-runtime": "^0.2.5" }, "cpu": "none" }, "sha512-U3PzLYKSQYzTERstgtHLd4ZTkOF9co57zTXT77r0cVUsleGZOrd6ut7rHzeWwoJSiHOVxxa0OhG1JVQeB7lLoQ=="], - - "@node-rs/argon2-win32-arm64-msvc": ["@node-rs/argon2-win32-arm64-msvc@2.0.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-Eisd7/NM0m23ijrGr6xI2iMocdOuyl6gO27gfMfya4C5BODbUSP7ljKJ7LrA0teqZMdYHesRDzx36Js++/vhiQ=="], - - "@node-rs/argon2-win32-ia32-msvc": ["@node-rs/argon2-win32-ia32-msvc@2.0.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-GsE2ezwAYwh72f9gIjbGTZOf4HxEksb5M2eCaj+Y5rGYVwAdt7C12Q2e9H5LRYxWcFvLH4m4jiSZpQQ4upnPAQ=="], - - "@node-rs/argon2-win32-x64-msvc": ["@node-rs/argon2-win32-x64-msvc@2.0.2", "", { "os": "win32", "cpu": "x64" }, "sha512-cJxWXanH4Ew9CfuZ4IAEiafpOBCe97bzoKowHCGk5lG/7kR4WF/eknnBlHW9m8q7t10mKq75kruPLtbSDqgRTw=="], - "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], - "@oslojs/asn1": ["@oslojs/asn1@1.0.0", "", { "dependencies": { "@oslojs/binary": "1.0.0" } }, "sha512-zw/wn0sj0j0QKbIXfIlnEcTviaCzYOY3V5rAyjR6YtOByFtJiT574+8p9Wlach0lZH9fddD4yb9laEAIl4vXQA=="], - - "@oslojs/binary": ["@oslojs/binary@1.0.0", "", {}, "sha512-9RCU6OwXU6p67H4NODbuxv2S3eenuQ4/WFLrsq+K/k682xrznH5EVWA7N4VFk9VYVcbFtKqur5YQQZc0ySGhsQ=="], - - "@oslojs/crypto": ["@oslojs/crypto@1.0.1", "", { "dependencies": { "@oslojs/asn1": "1.0.0", "@oslojs/binary": "1.0.0" } }, "sha512-7n08G8nWjAr/Yu3vu9zzrd0L9XnrJfpMioQcvCMxBIiF5orECHe5/3J0jmXRVvgfqMm/+4oxlQ+Sq39COYLcNQ=="], - - "@oslojs/encoding": ["@oslojs/encoding@1.1.0", "", {}, "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="], - "@petamoriken/float16": ["@petamoriken/float16@3.9.2", "", {}, "sha512-VgffxawQde93xKxT3qap3OH+meZf7VaSB5Sqd4Rqc+FP5alWbpOyan/7tRbOAvynjpG3GpdtAuGU/NdhQpmrog=="], "@polka/url": ["@polka/url@1.0.0-next.28", "", {}, "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw=="], @@ -332,8 +282,6 @@ "@testing-library/svelte": ["@testing-library/svelte@5.2.7", "", { "dependencies": { "@testing-library/dom": "^10.0.0" }, "peerDependencies": { "svelte": "^3 || ^4 || ^5 || ^5.0.0-next.0", "vite": "*", "vitest": "*" }, "optionalPeers": ["vite", "vitest"] }, "sha512-aGhUaFmEXEVost4QOsbHUUbHLwi7ZZRRxAHFDO2Cmr0BZD3/3+XvaYEPq70Rdw0NRNjdqZHdARBEcrCOkPuAqw=="], - "@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="], - "@types/aria-query": ["@types/aria-query@5.0.4", "", {}, "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw=="], "@types/cookie": ["@types/cookie@0.6.0", "", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="], @@ -858,8 +806,6 @@ "ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="], - "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], - "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], "typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="], diff --git a/package.json b/package.json index e8bc348..d8e67e2 100644 --- a/package.json +++ b/package.json @@ -13,12 +13,12 @@ "@testing-library/svelte": "^5.2.4", "@types/node": "^22.14.0", "drizzle-kit": "^0.30.2", - "drizzle-orm": "^0.41.0", "eslint": "^9.18.0", "eslint-config-prettier": "^10.0.1", "eslint-plugin-svelte": "^3.0.0", "globals": "^16.0.0", "jsdom": "^26.0.0", + "lodash": "^4.17.21", "prettier": "^3.4.2", "prettier-plugin-svelte": "^3.3.3", "prettier-plugin-tailwindcss": "^0.6.11", @@ -30,11 +30,6 @@ "vite": "^6.0.0", "vitest": "^3.0.0" }, - "pnpm": { - "onlyBuiltDependencies": [ - "esbuild" - ] - }, "private": true, "scripts": { "dev": "bunx vite dev", @@ -53,8 +48,6 @@ }, "type": "module", "dependencies": { - "@node-rs/argon2": "^2.0.2", - "@oslojs/crypto": "^1.0.1", - "@oslojs/encoding": "^1.1.0" + "drizzle-orm": "^0.41.0" } } diff --git a/src/app.css b/src/app.css index 06976b2..3a1ee76 100644 --- a/src/app.css +++ b/src/app.css @@ -7,7 +7,7 @@ body { @apply bg-white text-pretty text-black dark:bg-zinc-900 dark:text-white; - background-size: 40%; + background-size: 40%; } .emoji { diff --git a/src/app.d.ts b/src/app.d.ts index 8948d95..4d6f9e5 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -1,9 +1,6 @@ declare global { namespace App { - interface Locals { - user: import('$lib/server/auth').SessionValidationResult['user']; - session: import('$lib/server/auth').SessionValidationResult['session']; - } + //interface Locals {} } } diff --git a/src/hooks.server.ts b/src/hooks.server.ts deleted file mode 100644 index 27a4a46..0000000 --- a/src/hooks.server.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { Handle } from '@sveltejs/kit'; -import * as auth from '$lib/server/auth.js'; - -const handleAuth: Handle = async ({ event, resolve }) => { - const sessionToken = event.cookies.get(auth.sessionCookieName); - - if (!sessionToken) { - event.locals.user = null; - event.locals.session = null; - return resolve(event); - } - - const { session, user } = await auth.validateSessionToken(sessionToken); - - if (session) { - auth.setSessionTokenCookie(event, sessionToken, session.expiresAt); - } else { - auth.deleteSessionTokenCookie(event); - } - - event.locals.user = user; - event.locals.session = session; - return resolve(event); -}; - -export const handle: Handle = handleAuth; diff --git a/src/hooks.ts b/src/hooks.ts index 90345f4..ad9034b 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -1,10 +1,10 @@ import type { Reroute } from '@sveltejs/kit'; +import { PUBLIC_URL } from '$env/static/public'; export const reroute: Reroute = async ({ url }) => { + const split = url.hostname.split('.'); - const subdomain = url.hostname.split('.')[0] - - if (url.pathname === '/.well-known/atproto-did') { - return `/handles/${subdomain}/.well-known/atproto-did` + if (url.hostname !== PUBLIC_URL && split.length >= 2) { + return `/handles/${split[0]}/`; } -} \ No newline at end of file +}; diff --git a/src/lib/components/Footer.svelte b/src/lib/components/Footer.svelte index bc5820f..a9ba11a 100644 --- a/src/lib/components/Footer.svelte +++ b/src/lib/components/Footer.svelte @@ -14,9 +14,6 @@ diff --git a/src/lib/server/auth.ts b/src/lib/server/auth.ts deleted file mode 100644 index 38c9930..0000000 --- a/src/lib/server/auth.ts +++ /dev/null @@ -1,81 +0,0 @@ -import type { RequestEvent } from '@sveltejs/kit'; -import { eq } from 'drizzle-orm'; -import { sha256 } from '@oslojs/crypto/sha2'; -import { encodeBase64url, encodeHexLowerCase } from '@oslojs/encoding'; -import { db } from '$lib/server/db'; -import * as table from '$lib/server/db/schema'; - -const DAY_IN_MS = 1000 * 60 * 60 * 24; - -export const sessionCookieName = 'auth-session'; - -export function generateSessionToken() { - const bytes = crypto.getRandomValues(new Uint8Array(18)); - const token = encodeBase64url(bytes); - return token; -} - -export async function createSession(token: string, userId: string) { - const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token))); - const session: table.Session = { - id: sessionId, - userId, - expiresAt: new Date(Date.now() + DAY_IN_MS * 30) - }; - await db.insert(table.session).values(session); - return session; -} - -export async function validateSessionToken(token: string) { - const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token))); - const [result] = await db - .select({ - // Adjust user table here to tweak returned data - user: { id: table.user.id, username: table.user.username }, - session: table.session - }) - .from(table.session) - .innerJoin(table.user, eq(table.session.userId, table.user.id)) - .where(eq(table.session.id, sessionId)); - - if (!result) { - return { session: null, user: null }; - } - const { session, user } = result; - - const sessionExpired = Date.now() >= session.expiresAt.getTime(); - if (sessionExpired) { - await db.delete(table.session).where(eq(table.session.id, session.id)); - return { session: null, user: null }; - } - - const renewSession = Date.now() >= session.expiresAt.getTime() - DAY_IN_MS * 15; - if (renewSession) { - session.expiresAt = new Date(Date.now() + DAY_IN_MS * 30); - await db - .update(table.session) - .set({ expiresAt: session.expiresAt }) - .where(eq(table.session.id, session.id)); - } - - return { session, user }; -} - -export type SessionValidationResult = Awaited>; - -export async function invalidateSession(sessionId: string) { - await db.delete(table.session).where(eq(table.session.id, sessionId)); -} - -export function setSessionTokenCookie(event: RequestEvent, token: string, expiresAt: Date) { - event.cookies.set(sessionCookieName, token, { - expires: expiresAt, - path: '/' - }); -} - -export function deleteSessionTokenCookie(event: RequestEvent) { - event.cookies.delete(sessionCookieName, { - path: '/' - }); -} diff --git a/src/lib/server/db/schema.ts b/src/lib/server/db/schema.ts index 6f7bba6..36345f9 100644 --- a/src/lib/server/db/schema.ts +++ b/src/lib/server/db/schema.ts @@ -1,5 +1,5 @@ import { sql } from 'drizzle-orm'; -import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core'; +import { sqliteTable, text } from 'drizzle-orm/sqlite-core'; export const user = sqliteTable('user', { id: text('id').primaryKey(), @@ -10,19 +10,7 @@ export const user = sqliteTable('user', { .default(sql`CURRENT_TIMESTAMP`), updated_at: text('updated_at') .notNull() - .default(sql`CURRENT_TIMESTAMP`), - username: text('username').notNull().unique(), - passwordHash: text('password_hash').notNull() + .default(sql`CURRENT_TIMESTAMP`) }); -export const session = sqliteTable('session', { - id: text('id').primaryKey(), - userId: text('user_id') - .notNull() - .references(() => user.id), - expiresAt: integer('expires_at', { mode: 'timestamp' }).notNull() -}); - -export type Session = typeof session.$inferSelect; - -export type User = typeof user.$inferSelect; +//export type User = typeof user.$inferSelect; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 95627dd..c6dbe1d 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -8,25 +8,25 @@ let { children } = $props(); - let div: HTMLDivElement; + let main: HTMLElement; onMount(() => { - div.style.backgroundImage = `url("${logo}")`; + main.style.backgroundImage = `url("${logo}")`; }); -
+
{@render children()}
-
+ diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts new file mode 100644 index 0000000..98105c3 --- /dev/null +++ b/src/routes/+page.server.ts @@ -0,0 +1,11 @@ +import type { PageServerLoad } from './$types'; +import { db } from '$lib/server/db'; +import { user } from '$lib/server/db/schema'; + +export const load: PageServerLoad = async () => { + const count = await db.$count(user); + + return { + count + }; +}; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 1ba25dc..1701bb1 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,10 +1,16 @@ - -
-

Get your own {page.url.hostname}

+
+

Get your own {PUBLIC_URL} handle

+

+ Get your own {PUBLIC_URL} handle with {Math.max(0, data.count - 1)} other users +

- +
diff --git a/src/routes/.well-known/atproto-did/+page.svelte b/src/routes/.well-known/atproto-did/+page.svelte deleted file mode 100644 index e69de29..0000000 diff --git a/src/routes/demo/+page.svelte b/src/routes/demo/+page.svelte deleted file mode 100644 index e69de29..0000000 diff --git a/src/routes/demo/lucia/+page.server.ts b/src/routes/demo/lucia/+page.server.ts deleted file mode 100644 index c6b3d98..0000000 --- a/src/routes/demo/lucia/+page.server.ts +++ /dev/null @@ -1,22 +0,0 @@ -import * as auth from '$lib/server/auth'; -import { fail, redirect } from '@sveltejs/kit'; -import type { Actions, PageServerLoad } from './$types'; - -export const load: PageServerLoad = async (event) => { - if (!event.locals.user) { - return redirect(302, '/demo/lucia/login'); - } - return { user: event.locals.user }; -}; - -export const actions: Actions = { - logout: async (event) => { - if (!event.locals.session) { - return fail(401); - } - await auth.invalidateSession(event.locals.session.id); - auth.deleteSessionTokenCookie(event); - - return redirect(302, '/demo/lucia/login'); - } -}; diff --git a/src/routes/demo/lucia/+page.svelte b/src/routes/demo/lucia/+page.svelte deleted file mode 100644 index cefb2d1..0000000 --- a/src/routes/demo/lucia/+page.svelte +++ /dev/null @@ -1,12 +0,0 @@ - - -

Hi, {data.user.username}!

-

Your user ID is {data.user.id}.

-
- -
diff --git a/src/routes/demo/lucia/login/+page.server.ts b/src/routes/demo/lucia/login/+page.server.ts deleted file mode 100644 index f0844ab..0000000 --- a/src/routes/demo/lucia/login/+page.server.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { verify } from '@node-rs/argon2'; -import { encodeBase32LowerCase } from '@oslojs/encoding'; -import { fail, redirect } from '@sveltejs/kit'; -import { eq } from 'drizzle-orm'; -import * as auth from '$lib/server/auth'; -import { db } from '$lib/server/db'; -import * as table from '$lib/server/db/schema'; -import type { Actions, PageServerLoad } from './$types'; - -export const load: PageServerLoad = async (event) => { - if (event.locals.user) { - return redirect(302, '/demo/lucia'); - } - return {}; -}; - -export const actions: Actions = { - login: async (event) => { - const formData = await event.request.formData(); - const username = formData.get('username'); - const password = formData.get('password'); - - if (!validateUsername(username)) { - return fail(400, { - message: 'Invalid username (min 3, max 31 characters, alphanumeric only)' - }); - } - if (!validatePassword(password)) { - return fail(400, { message: 'Invalid password (min 6, max 255 characters)' }); - } - - const results = await db.select().from(table.user).where(eq(table.user.username, username)); - - const existingUser = results.at(0); - if (!existingUser) { - return fail(400, { message: 'Incorrect username or password' }); - } - - const validPassword = await verify(existingUser.passwordHash, password, { - memoryCost: 19456, - timeCost: 2, - outputLen: 32, - parallelism: 1 - }); - if (!validPassword) { - return fail(400, { message: 'Incorrect username or password' }); - } - - const sessionToken = auth.generateSessionToken(); - const session = await auth.createSession(sessionToken, existingUser.id); - auth.setSessionTokenCookie(event, sessionToken, session.expiresAt); - - return redirect(302, '/demo/lucia'); - } - /*register: async (event) => { - const formData = await event.request.formData(); - const username = formData.get('username'); - const password = formData.get('password'); - - if (!validateUsername(username)) { - return fail(400, { message: 'Invalid username' }); - } - if (!validatePassword(password)) { - return fail(400, { message: 'Invalid password' }); - } - - const userId = generateUserId(); - const passwordHash = await hash(password, { - // recommended minimum parameters - memoryCost: 19456, - timeCost: 2, - outputLen: 32, - parallelism: 1 - }); - - try { - await db.insert(table.user).values({ id: userId, username, passwordHash }); - - const sessionToken = auth.generateSessionToken(); - const session = await auth.createSession(sessionToken, userId); - auth.setSessionTokenCookie(event, sessionToken, session.expiresAt); - } catch (e) { - return fail(500, { message: 'An error has occurred' }); - } - return redirect(302, '/demo/lucia'); - }*/ -}; - -function generateUserId() { - // ID with 120 bits of entropy, or about the same as UUID v4. - const bytes = crypto.getRandomValues(new Uint8Array(15)); - const id = encodeBase32LowerCase(bytes); - return id; -} - -function validateUsername(username: unknown): username is string { - return ( - typeof username === 'string' && - username.length >= 3 && - username.length <= 31 && - /^[a-z0-9_-]+$/.test(username) - ); -} - -function validatePassword(password: unknown): password is string { - return typeof password === 'string' && password.length >= 6 && password.length <= 255; -} diff --git a/src/routes/demo/lucia/login/+page.svelte b/src/routes/demo/lucia/login/+page.svelte deleted file mode 100644 index a3138d7..0000000 --- a/src/routes/demo/lucia/login/+page.svelte +++ /dev/null @@ -1,21 +0,0 @@ - - -

Login/Register

-
- - - - -
-

{form?.message ?? ''}

diff --git a/src/routes/handles/[handle]/+page.server.ts b/src/routes/handles/[handle]/+page.server.ts new file mode 100644 index 0000000..1c3a6aa --- /dev/null +++ b/src/routes/handles/[handle]/+page.server.ts @@ -0,0 +1,10 @@ +import type { PageServerLoad } from './$types'; +import { db } from '$lib/server/db'; + +export const load: PageServerLoad = async ({ params: { handle } }) => { + return { + user: await db.query.user.findFirst({ + where: (user, { eq }) => eq(user.handle, handle) + }) + }; +}; diff --git a/src/routes/handles/[handle]/+page.svelte b/src/routes/handles/[handle]/+page.svelte new file mode 100644 index 0000000..7279da0 --- /dev/null +++ b/src/routes/handles/[handle]/+page.svelte @@ -0,0 +1,16 @@ + + +
+ {#if data.user} +

{data.user?.handle}{PUBLIC_URL}

+ {/if} +

User does not exist

+

+ Are you sure you typed the handle right, why not take the handle if you want to +

+
diff --git a/src/routes/handles/[handle]/.well-known/atproto-did/+page.svelte b/src/routes/handles/[handle]/.well-known/atproto-did/+page.svelte index 5b41857..c1b8bbe 100644 --- a/src/routes/handles/[handle]/.well-known/atproto-did/+page.svelte +++ b/src/routes/handles/[handle]/.well-known/atproto-did/+page.svelte @@ -1,3 +1,4 @@ -

- This worked -

\ No newline at end of file + + +

This worked

diff --git a/src/routes/login/+page.svelte b/src/routes/login/+page.svelte deleted file mode 100644 index 2fb9f09..0000000 --- a/src/routes/login/+page.svelte +++ /dev/null @@ -1 +0,0 @@ -

bruh