diff --git a/.env.example b/.env.example
index e69de29..435b3ca 100644
--- a/.env.example
+++ b/.env.example
@@ -0,0 +1,9 @@
+AUTH_SECRET=
+
+MYSQL_HOST=
+MYSQL_USERNAME=
+MYSQL_PASSWORD=
+
+KEYCLOAK_CLIENT_ID=
+KEYCLOAK_CLIENT_SECRET=
+KEYCLOAK_CLIENT_ISSUER=
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 664bd14..3fdee6c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -31,5 +31,4 @@ COPY --from=build /usr/src/app/package.json .
COPY --from=build /usr/src/app/build/ .
EXPOSE 3000/tcp
-CMD [ "node", "index.js" ]
-
+CMD [ "node", "index.js" ]
\ No newline at end of file
diff --git a/README.md b/README.md
index 3ef1d2b..86416e7 100644
--- a/README.md
+++ b/README.md
@@ -5,3 +5,11 @@
[![forthebadge](https://forthebadge.com/images/badges/license-mit.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/designed-in-ms-paint.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/gluten-free.svg)](https://forthebadge.com) [![forthebadge](https://forthebadge.com/images/badges/powered-by-black-magic.svg)](https://forthebadge.com)
A file uploading website.
+
+## Developing
+
+You can start a development SQL server with Docker:
+
+```sh
+sudo docker run -e MYSQL_ROOT_PASSWORD=development -e MYSQL_DATABASE=fileuploader -d mysql:latest
+```
diff --git a/drizzle.config.js b/drizzle.config.js
new file mode 100644
index 0000000..ba983af
--- /dev/null
+++ b/drizzle.config.js
@@ -0,0 +1,11 @@
+/** @type { import("drizzle-kit").Config } */
+export default {
+ schema: 'src/lib/server/database/schema.js',
+ driver: 'mysql2',
+ dbCredentials: {
+ host: process.env.MYSQL_HOST,
+ user: process.env.MYSQL_USERNAME,
+ password: process.env.MYSQL_PASSWORD,
+ database: 'fileuploader'
+ }
+};
diff --git a/package.json b/package.json
index b35a293..497513c 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,9 @@
},
"type": "module",
"dependencies": {
+ "@auth/core": "^0.28.0",
+ "@auth/drizzle-adapter": "^0.8.0",
+ "@auth/sveltekit": "^0.14.0",
"drizzle-orm": "^0.30.2",
"lucide-svelte": "^0.358.0",
"mysql2": "^3.9.2",
diff --git a/src/hooks.server.js b/src/hooks.server.js
index 93f91a4..fbb46ba 100644
--- a/src/hooks.server.js
+++ b/src/hooks.server.js
@@ -1,12 +1,25 @@
+// import { redirect } from '@sveltejs/kit';
+import { sequence } from '@sveltejs/kit/hooks';
+import { handle as authenticationHandle } from '$lib/server/auth.js';
+
+async function authorizationHandle({ event, resolve }) {
+ // if (event.url.pathname.startsWith('/(app)')) {
+ // const session = await event.locals.auth();
+ // if (!session) {
+ // throw redirect(303, '/auth/signin');
+ // }
+ // }
+
+ return resolve(event);
+}
+
+export const handle = sequence(authenticationHandle, authorizationHandle);
+
/** @type {import('@sveltejs/kit').HandleServerError} */
export async function handleError({ error, event, status, message }) {
-
- console.log(error)
-
- const id = crypto.randomUUID();
+ console.log(error);
return {
- id,
status,
message
};
diff --git a/src/lib/components/LoggedOut.svelte b/src/lib/components/LoggedOut.svelte
new file mode 100644
index 0000000..4a9e398
--- /dev/null
+++ b/src/lib/components/LoggedOut.svelte
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
Currently hosting 0 files.
+
Elon musk found dead in a pool
+
+
+
+
+
+
+
+
+
diff --git a/src/lib/server/auth.js b/src/lib/server/auth.js
new file mode 100644
index 0000000..2ac5ac2
--- /dev/null
+++ b/src/lib/server/auth.js
@@ -0,0 +1,23 @@
+import { SvelteKitAuth } from '@auth/sveltekit';
+import Keycloak from '@auth/core/providers/keycloak';
+import { DrizzleAdapter } from '@auth/drizzle-adapter';
+import { db } from '$lib/server/database';
+import { env } from '$env/dynamic/private';
+
+export const { handle, signIn, signOut } = SvelteKitAuth({
+ adapter: DrizzleAdapter(db),
+ providers: [
+ Keycloak({
+ clientId: env.KEYCLOAK_CLIENT_ID,
+ clientSecret: env.KEYCLOAK_CLIENT_SECRET,
+ issuer: env.KEYCLOAK_ISSUER,
+ profile(profile) {
+ return {
+ id: profile.sub,
+ name: profile.preferred_username,
+ email: profile.email
+ };
+ }
+ })
+ ]
+});
diff --git a/src/lib/server/database/index.js b/src/lib/server/database/index.js
new file mode 100644
index 0000000..e9902bc
--- /dev/null
+++ b/src/lib/server/database/index.js
@@ -0,0 +1,13 @@
+import { drizzle } from 'drizzle-orm/mysql2';
+import mysql from 'mysql2/promise';
+import { env } from '$env/dynamic/private';
+import * as schema from './schema';
+
+const connection = await mysql.createConnection({
+ host: env.MYSQL_HOST,
+ user: env.MYSQL_USERNAME,
+ password: env.MYSQL_PASSWORD,
+ database: 'fileuploader'
+});
+
+export const db = drizzle(connection, { schema, mode: 'default' });
diff --git a/src/lib/server/database/schema.js b/src/lib/server/database/schema.js
new file mode 100644
index 0000000..614ee8e
--- /dev/null
+++ b/src/lib/server/database/schema.js
@@ -0,0 +1,53 @@
+import { int, timestamp, mysqlTable, primaryKey, varchar } from 'drizzle-orm/mysql-core';
+
+export const users = mysqlTable('user', {
+ id: varchar('id', { length: 255 }).notNull().primaryKey(),
+ name: varchar('name', { length: 255 }),
+ email: varchar('email', { length: 255 }).notNull(),
+ emailVerified: timestamp('emailVerified', { mode: 'date', fsp: 3 }).defaultNow(),
+ image: varchar('image', { length: 255 })
+});
+
+export const accounts = mysqlTable(
+ 'account',
+ {
+ userId: varchar('userId', { length: 255 })
+ .notNull()
+ .references(() => users.id, { onDelete: 'cascade' }),
+ type: varchar('type', { length: 255 }).notNull(),
+ provider: varchar('provider', { length: 255 }).notNull(),
+ providerAccountId: varchar('providerAccountId', { length: 255 }).notNull(),
+ refresh_token: varchar('refresh_token', { length: 2048 }),
+ access_token: varchar('access_token', { length: 2048 }),
+ expires_at: int('expires_at'),
+ token_type: varchar('token_type', { length: 255 }),
+ scope: varchar('scope', { length: 255 }),
+ id_token: varchar('id_token', { length: 2048 }),
+ session_state: varchar('session_state', { length: 255 })
+ },
+ (account) => ({
+ compoundKey: primaryKey({
+ columns: [account.provider, account.providerAccountId]
+ })
+ })
+);
+
+export const sessions = mysqlTable('session', {
+ sessionToken: varchar('sessionToken', { length: 255 }).notNull().primaryKey(),
+ userId: varchar('userId', { length: 255 })
+ .notNull()
+ .references(() => users.id, { onDelete: 'cascade' }),
+ expires: timestamp('expires', { mode: 'date' }).notNull()
+});
+
+export const verificationTokens = mysqlTable(
+ 'verificationToken',
+ {
+ identifier: varchar('identifier', { length: 255 }).notNull(),
+ token: varchar('token', { length: 255 }).notNull(),
+ expires: timestamp('expires', { mode: 'date' }).notNull()
+ },
+ (vt) => ({
+ compoundKey: primaryKey({ columns: [vt.identifier, vt.token] })
+ })
+);
diff --git a/src/lib/server/db/index.js b/src/lib/server/db/index.js
deleted file mode 100644
index e595849..0000000
--- a/src/lib/server/db/index.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import { drizzle } from 'drizzle-orm/mysql2';
-import mysql from 'mysql2/promise';
-
-const connection = await mysql.createConnection({
- host: process.env.DATABASE_HOST,
- user: process.env.DATABASE_USER,
- password: process.env.DATABASE_PASSWORD
-});
-
-export default drizzle(connection);
diff --git a/src/lib/server/db/schema.js b/src/lib/server/db/schema.js
deleted file mode 100644
index 7cb9355..0000000
--- a/src/lib/server/db/schema.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import { int, mysqlTable, text } from 'drizzle-orm/mysql-core';
-
-export const users = mysqlTable('users', {
- id: int('id').autoincrement().primaryKey(),
- username: text('username').unique().notNull(),
- password: text('password').notNull()
-});
diff --git a/src/routes/+layout.server.js b/src/routes/+layout.server.js
new file mode 100644
index 0000000..1722a47
--- /dev/null
+++ b/src/routes/+layout.server.js
@@ -0,0 +1,5 @@
+export const load = async ({ locals }) => {
+ return {
+ session: await locals.getSession()
+ };
+};
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index 14609cc..5348a3f 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -2,8 +2,10 @@
import '../app.css';
import { Toaster } from 'svelte-sonner';
+ import { page } from '$app/stores';
import { darkMode } from '$lib/stores.js';
+ import LoggedOut from '$lib/components/LoggedOut.svelte';
import ThemeHandler from '$lib/components/ThemeHandler.svelte';
import PageMeta from '$lib/components/PageMeta.svelte';
@@ -12,6 +14,10 @@
-
-
-
+{#if $page.data.session?.user}
+
+
+
+{:else}
+
+{/if}
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index a111283..76a4b2d 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -1,45 +1,16 @@
-
-
-
-
-
-
-
Currently hosting 0 files.
-
Elon musk found dead in a pool
-
+
+
+ {JSON.stringify($page.data?.session, null, 4)}
+
+
-
-
-
-
-
-
Login
-
-
-
-
-
Register
-
-
-
-
-
-
+
diff --git a/src/routes/login/+page.svelte b/src/routes/login/+page.svelte
deleted file mode 100644
index 38d75bc..0000000
--- a/src/routes/login/+page.svelte
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
diff --git a/src/routes/register/+page.svelte b/src/routes/register/+page.svelte
deleted file mode 100644
index 65d10c6..0000000
--- a/src/routes/register/+page.svelte
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
diff --git a/yarn.lock b/yarn.lock
index de20266..5d4b76b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -15,6 +15,34 @@
"@jridgewell/gen-mapping" "^0.3.5"
"@jridgewell/trace-mapping" "^0.3.24"
+"@auth/core@0.28.0", "@auth/core@^0.28.0":
+ version "0.28.0"
+ resolved "https://registry.yarnpkg.com/@auth/core/-/core-0.28.0.tgz#3e3aa723062e3f1daf28eb47688db622bf119396"
+ integrity sha512-/fh/tb/L4NMSYcyPoo4Imn8vN6MskcVfgESF8/ndgtI4fhD/7u7i5fTVzWgNRZ4ebIEGHNDbWFRxaTu1NtQgvA==
+ dependencies:
+ "@panva/hkdf" "^1.1.1"
+ "@types/cookie" "0.6.0"
+ cookie "0.6.0"
+ jose "^5.1.3"
+ oauth4webapi "^2.4.0"
+ preact "10.11.3"
+ preact-render-to-string "5.2.3"
+
+"@auth/drizzle-adapter@^0.8.0":
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/@auth/drizzle-adapter/-/drizzle-adapter-0.8.0.tgz#a2d5a84528d0398d7853a0dde6d661a58b40b2d5"
+ integrity sha512-cwLMOJHf+R8VeHYFzdA5DReKelidWSx8bz9kJ6hydPjUugHate2F7u9XHoCOu7zXIA5azSPb3b2WR9C0Fjq7eA==
+ dependencies:
+ "@auth/core" "0.28.0"
+
+"@auth/sveltekit@^0.14.0":
+ version "0.14.0"
+ resolved "https://registry.yarnpkg.com/@auth/sveltekit/-/sveltekit-0.14.0.tgz#4d410f67b53fe398a2e5df121c7438d2f8c13d89"
+ integrity sha512-I4ec4hcL4BTHgebJ1KvjX/8VclLuJAkcJdPwH0BOGt20qlu+wipI7EQjJy6EG2s4p0cAEWaIGGKFhMZIUfb+1Q==
+ dependencies:
+ "@auth/core" "0.28.0"
+ set-cookie-parser "^2.6.0"
+
"@drizzle-team/studio@^0.0.39":
version "0.0.39"
resolved "https://registry.yarnpkg.com/@drizzle-team/studio/-/studio-0.0.39.tgz#70e9155503f7343e8f1917d316f93e64c23760e1"
@@ -328,6 +356,11 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
+"@panva/hkdf@^1.1.1":
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.1.1.tgz#ab9cd8755d1976e72fc77a00f7655a64efe6cd5d"
+ integrity sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==
+
"@pkgjs/parseargs@^0.11.0":
version "0.11.0"
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
@@ -498,7 +531,7 @@
svelte-hmr "^0.15.3"
vitefu "^0.2.5"
-"@types/cookie@^0.6.0":
+"@types/cookie@0.6.0", "@types/cookie@^0.6.0":
version "0.6.0"
resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.6.0.tgz#eac397f28bf1d6ae0ae081363eca2f425bedf0d5"
integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==
@@ -712,7 +745,7 @@ commondir@^1.0.1:
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==
-cookie@^0.6.0:
+cookie@0.6.0, cookie@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
@@ -1257,6 +1290,11 @@ jiti@^1.19.1:
resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d"
integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==
+jose@^5.1.3:
+ version "5.2.3"
+ resolved "https://registry.yarnpkg.com/jose/-/jose-5.2.3.tgz#071c87f9fe720cff741a403c8080b69bfe13164a"
+ integrity sha512-KUXdbctm1uHVL8BYhnyHkgp3zDX5KW8ZhAKVFEfUbU2P8Alpzjb+48hHvjOdQIyPshoblhzsuqOwEEAbtHVirA==
+
json-diff@0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/json-diff/-/json-diff-0.9.0.tgz#e7c536798053cb409113d7403c774849e8a0d7ff"
@@ -1470,6 +1508,11 @@ normalize-range@^0.1.2:
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
+oauth4webapi@^2.4.0:
+ version "2.10.3"
+ resolved "https://registry.yarnpkg.com/oauth4webapi/-/oauth4webapi-2.10.3.tgz#8e6d5a8a984a297dd80276a6c52634359319d034"
+ integrity sha512-9FkXEXfzVKzH63GUOZz1zMr3wBaICSzk6DLXx+CGdrQ10ItNk2ePWzYYc1fdmKq1ayGFb2aX97sRCoZ2s0mkDw==
+
object-assign@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@@ -1587,6 +1630,18 @@ postcss@^8.4.23, postcss@^8.4.35:
picocolors "^1.0.0"
source-map-js "^1.0.2"
+preact-render-to-string@5.2.3:
+ version "5.2.3"
+ resolved "https://registry.yarnpkg.com/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz#23d17376182af720b1060d5a4099843c7fe92fe4"
+ integrity sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==
+ dependencies:
+ pretty-format "^3.8.0"
+
+preact@10.11.3:
+ version "10.11.3"
+ resolved "https://registry.yarnpkg.com/preact/-/preact-10.11.3.tgz#8a7e4ba19d3992c488b0785afcc0f8aa13c78d19"
+ integrity sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==
+
prettier-plugin-svelte@^3.1.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/prettier-plugin-svelte/-/prettier-plugin-svelte-3.2.2.tgz#df576c8a92088dc0aaec8e27fce8a7d9683de93c"
@@ -1597,6 +1652,11 @@ prettier@^3.1.1:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.2.5.tgz#e52bc3090586e824964a8813b09aba6233b28368"
integrity sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==
+pretty-format@^3.8.0:
+ version "3.8.0"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385"
+ integrity sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==
+
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"