diff --git a/.env.example b/.env.example
index 69a4227..14d5bda 100644
--- a/.env.example
+++ b/.env.example
@@ -1 +1,3 @@
-MONGO_URL=""
\ No newline at end of file
+MONGO_URL=""
+PUBLIC_SUPABASE_URL=""
+PUBLIC_SUPABASE_ANON_KEY=""
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index c7ffd60..2061f05 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,8 @@
"name": "LivingDexTracker",
"version": "0.0.1",
"dependencies": {
+ "@supabase/ssr": "^0.1.0",
+ "@supabase/supabase-js": "^2.42.0",
"mongoose": "^8.0.3",
"nanoid": "^5.0.4"
},
@@ -855,6 +857,112 @@
"win32"
]
},
+ "node_modules/@supabase/auth-js": {
+ "version": "2.63.0",
+ "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.63.0.tgz",
+ "integrity": "sha512-yIgcHnlgv24GxHtVGUhwGqAFDyJkPIC/xjx7HostN08A8yCy8HIfl4JEkTKyBqD1v1L05jNEJOUke4Lf4O1+Qg==",
+ "dependencies": {
+ "@supabase/node-fetch": "^2.6.14"
+ }
+ },
+ "node_modules/@supabase/functions-js": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.2.2.tgz",
+ "integrity": "sha512-sJGq1nludmi7pY/fdtCpyY/pYonx7MfHdN408bqb736guWcVI1AChYVbI4kUM978EuOE4Ci6l7bUudfGg07QRw==",
+ "dependencies": {
+ "@supabase/node-fetch": "^2.6.14"
+ }
+ },
+ "node_modules/@supabase/node-fetch": {
+ "version": "2.6.15",
+ "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz",
+ "integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ }
+ },
+ "node_modules/@supabase/node-fetch/node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ },
+ "node_modules/@supabase/node-fetch/node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ },
+ "node_modules/@supabase/node-fetch/node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/@supabase/postgrest-js": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.15.0.tgz",
+ "integrity": "sha512-U4bwBOrhsXWqDjZiYNbVqMBtRGgIIYE0kE5ZNSwsIbeBWfr/UxOMrnkIQUBGIZRhpYW/tw1WnTdRl1AGNyaxcw==",
+ "dependencies": {
+ "@supabase/node-fetch": "^2.6.14"
+ }
+ },
+ "node_modules/@supabase/realtime-js": {
+ "version": "2.9.3",
+ "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.9.3.tgz",
+ "integrity": "sha512-lAp50s2n3FhGJFq+wTSXLNIDPw5Y0Wxrgt44eM5nLSA3jZNUUP3Oq2Ccd1CbZdVntPCWLZvJaU//pAd2NE+QnQ==",
+ "dependencies": {
+ "@supabase/node-fetch": "^2.6.14",
+ "@types/phoenix": "^1.5.4",
+ "@types/ws": "^8.5.10",
+ "ws": "^8.14.2"
+ }
+ },
+ "node_modules/@supabase/ssr": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@supabase/ssr/-/ssr-0.1.0.tgz",
+ "integrity": "sha512-bIVrkqjAK5G3KjkIMKYKtAOlCgRRplEWjrlyRyXSOYtgDieiOhk2ZyNAPsEOa1By9OZVxuX5eAW1fitdnuxayw==",
+ "dependencies": {
+ "cookie": "^0.5.0",
+ "ramda": "^0.29.0"
+ },
+ "peerDependencies": {
+ "@supabase/supabase-js": "^2.33.1"
+ }
+ },
+ "node_modules/@supabase/ssr/node_modules/cookie": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
+ "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/@supabase/storage-js": {
+ "version": "2.5.5",
+ "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.5.5.tgz",
+ "integrity": "sha512-OpLoDRjFwClwc2cjTJZG8XviTiQH4Ik8sCiMK5v7et0MDu2QlXjCAW3ljxJB5+z/KazdMOTnySi+hysxWUPu3w==",
+ "dependencies": {
+ "@supabase/node-fetch": "^2.6.14"
+ }
+ },
+ "node_modules/@supabase/supabase-js": {
+ "version": "2.42.0",
+ "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.42.0.tgz",
+ "integrity": "sha512-1PDqJiA4iG45w3AAu6xkccJ3wPqlGJUoz9CPhScRLLTStxhewYhz0mjryTpXz1kgtNHdUAsirALreezn8UZMjA==",
+ "dependencies": {
+ "@supabase/auth-js": "2.63.0",
+ "@supabase/functions-js": "2.2.2",
+ "@supabase/node-fetch": "2.6.15",
+ "@supabase/postgrest-js": "1.15.0",
+ "@supabase/realtime-js": "2.9.3",
+ "@supabase/storage-js": "2.5.5"
+ }
+ },
"node_modules/@sveltejs/adapter-auto": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-3.1.1.tgz",
@@ -980,6 +1088,19 @@
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true
},
+ "node_modules/@types/node": {
+ "version": "20.12.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.5.tgz",
+ "integrity": "sha512-BD+BjQ9LS/D8ST9p5uqBxghlN+S42iuNxjsUGjeZobe/ciXzk2qb1B6IXc6AnRLS+yFJRpN2IPEHMzwspfDJNw==",
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
+ },
+ "node_modules/@types/phoenix": {
+ "version": "1.6.4",
+ "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.4.tgz",
+ "integrity": "sha512-B34A7uot1Cv0XtaHRYDATltAdKx0BvVKNgYNqE4WjtPUa4VQJM7kxeXcVKaH+KS+kCmZ+6w+QaUdcljiheiBJA=="
+ },
"node_modules/@types/pug": {
"version": "2.0.10",
"resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz",
@@ -1005,6 +1126,14 @@
"@types/webidl-conversions": "*"
}
},
+ "node_modules/@types/ws": {
+ "version": "8.5.10",
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz",
+ "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.1.1.tgz",
@@ -2971,6 +3100,15 @@
}
]
},
+ "node_modules/ramda": {
+ "version": "0.29.1",
+ "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.1.tgz",
+ "integrity": "sha512-OfxIeWzd4xdUNxlWhgFazxsA/nl3mS4/jGZI5n00uWOoSSFRhC1b6gl6xvmzUamgmqELraWp0J/qqVlXYPDPyA==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/ramda"
+ }
+ },
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -3512,6 +3650,11 @@
"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=="
+ },
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -4027,6 +4170,26 @@
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
},
+ "node_modules/ws": {
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
+ "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
diff --git a/package.json b/package.json
index a768bb8..0c5c56e 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,8 @@
},
"type": "module",
"dependencies": {
+ "@supabase/ssr": "^0.1.0",
+ "@supabase/supabase-js": "^2.42.0",
"mongoose": "^8.0.3",
"nanoid": "^5.0.4"
},
diff --git a/src/hooks.server.ts b/src/hooks.server.ts
index ebf14ae..6d6e55e 100644
--- a/src/hooks.server.ts
+++ b/src/hooks.server.ts
@@ -1,9 +1,49 @@
+import { PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY } from '$env/static/public';
+import { createServerClient } from '@supabase/ssr';
import type { Handle } from '@sveltejs/kit';
-import { dbConnect } from '$lib/utils/db';
-
-await dbConnect();
export const handle: Handle = async ({ event, resolve }) => {
- const response = await resolve(event);
- return response;
+ event.locals.supabase = createServerClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
+ cookies: {
+ get: (key) => event.cookies.get(key),
+ /**
+ * Note: You have to add the `path` variable to the
+ * set and remove method due to sveltekit's cookie API
+ * requiring this to be set, setting the path to an empty string
+ * will replicate previous/standard behaviour (https://kit.svelte.dev/docs/types#public-types-cookies)
+ */
+ set: (key, value, options) => {
+ event.cookies.set(key, value, { ...options, path: '/' });
+ },
+ remove: (key, options) => {
+ event.cookies.delete(key, { ...options, path: '/' });
+ }
+ }
+ });
+
+ /**
+ * Unlike `supabase.auth.getSession`, which is unsafe on the server because it
+ * doesn't validate the JWT, this function validates the JWT by first calling
+ * `getUser` and aborts early if the JWT signature is invalid.
+ */
+ event.locals.safeGetSession = async () => {
+ const {
+ data: { user },
+ error
+ } = await event.locals.supabase.auth.getUser();
+ if (error) {
+ return { session: null, user: null };
+ }
+
+ const {
+ data: { session }
+ } = await event.locals.supabase.auth.getSession();
+ return { session, user };
+ };
+
+ return resolve(event, {
+ filterSerializedResponseHeaders(name) {
+ return name === 'content-range';
+ }
+ });
};
diff --git a/src/lib/components/SignIn.svelte b/src/lib/components/SignIn.svelte
new file mode 100644
index 0000000..d1e2d86
--- /dev/null
+++ b/src/lib/components/SignIn.svelte
@@ -0,0 +1,30 @@
+
+
+
+
+
diff --git a/src/lib/components/SignOut.svelte b/src/lib/components/SignOut.svelte
new file mode 100644
index 0000000..a4cc2bf
--- /dev/null
+++ b/src/lib/components/SignOut.svelte
@@ -0,0 +1,20 @@
+
+
+
diff --git a/src/lib/components/SignUp.svelte b/src/lib/components/SignUp.svelte
new file mode 100644
index 0000000..51ce3b3
--- /dev/null
+++ b/src/lib/components/SignUp.svelte
@@ -0,0 +1,33 @@
+
+
+
+
+
diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts
new file mode 100644
index 0000000..1d33583
--- /dev/null
+++ b/src/routes/+layout.server.ts
@@ -0,0 +1,10 @@
+import type { LayoutServerLoad } from './$types';
+
+export const load: LayoutServerLoad = async ({ locals: { safeGetSession } }) => {
+ const { session, user } = await safeGetSession();
+
+ return {
+ session,
+ user
+ };
+};
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
new file mode 100644
index 0000000..4c0a0db
--- /dev/null
+++ b/src/routes/+layout.svelte
@@ -0,0 +1,6 @@
+
+
+
Visit kit.svelte.dev to read the documentation
+ + +{#if userEmail} + Welcome back {userEmail} +