diff --git a/package-lock.json b/package-lock.json index 7d733c1..ae6e14c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,8 @@ "name": "livingdextracker", "version": "0.0.1", "dependencies": { - "@supabase/ssr": "^0.1.0", - "@supabase/supabase-js": "^2.42.0", + "@supabase/ssr": "^0.12.7", + "@supabase/supabase-js": "^2.116.0", "nanoid": "^5.0.4", "sharp": "^0.33.4" }, @@ -3728,103 +3728,120 @@ "license": "MIT" }, "node_modules/@supabase/auth-js": { - "version": "2.89.0", - "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.89.0.tgz", - "integrity": "sha512-wiWZdz8WMad8LQdJMWYDZ2SJtZP5MwMqzQq3ehtW2ngiI3UTgbKiFrvMUUS3KADiVlk4LiGfODB2mrYx7w2f8w==", + "version": "2.116.0", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.116.0.tgz", + "integrity": "sha512-Cmosty12gyKGK9N3bQb+lMmuAFev5nmUzaR1AsmZHqKOAGzqX1VQzmp49CNPwOx/pw0H9Qqk4rs9yhwTlKpfDg==", "license": "MIT", "dependencies": { "tslib": "2.8.1" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" } }, "node_modules/@supabase/functions-js": { - "version": "2.89.0", - "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.89.0.tgz", - "integrity": "sha512-XEueaC5gMe5NufNYfBh9kPwJlP5M2f+Ogr8rvhmRDAZNHgY6mI35RCkYDijd92pMcNM7g8pUUJov93UGUnqfyw==", + "version": "2.116.0", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.116.0.tgz", + "integrity": "sha512-E+VOc2QDcni/fySqkBFiZhnoB3SGydEdZgFI6/dEAGAHx6yEhB46TN9qb2wXs+E+RSzOBV0R6dasiSlw4xlZAA==", "license": "MIT", "dependencies": { "tslib": "2.8.1" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" } }, + "node_modules/@supabase/phoenix": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/@supabase/phoenix/-/phoenix-0.4.5.tgz", + "integrity": "sha512-aAn9H9ovVyeApKy11OWOrrOGq8DV68yWeH4ud2lN9fzn4aO8Zb5GLL9m1pUg9nLqIcT+ZDfAcsZe0E/nqdv2lw==", + "license": "MIT" + }, "node_modules/@supabase/postgrest-js": { - "version": "2.89.0", - "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.89.0.tgz", - "integrity": "sha512-/b0fKrxV9i7RNOEXMno/I1862RsYhuUo+Q6m6z3ar1f4ulTMXnDfv0y4YYxK2POcgrOXQOgKYQx1eArybyNvtg==", + "version": "2.116.0", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.116.0.tgz", + "integrity": "sha512-kGpVZTDHxFTJS3tu+rU0iTAZ+4U0bcLVjxwCk8f3gRhjw3qdCZjTBlgYvc4kGH2XccmAzbkKwXL/mrNHMGSc+A==", "license": "MIT", "dependencies": { "tslib": "2.8.1" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" } }, "node_modules/@supabase/realtime-js": { - "version": "2.89.0", - "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.89.0.tgz", - "integrity": "sha512-aMOvfDb2a52u6PX6jrrjvACHXGV3zsOlWRzZsTIOAJa0hOVvRp01AwC1+nLTGUzxzezejrYeCX+KnnM1xHdl+w==", + "version": "2.116.0", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.116.0.tgz", + "integrity": "sha512-MHAnlXxi2s6yiJsZsQMfs2B3RFxeVfQWxerqYhIMqcCQV/FuY3LIeouPEkXw/ah7wUWMLYwempF9MOCUScyddg==", "license": "MIT", "dependencies": { - "@types/phoenix": "^1.6.6", - "@types/ws": "^8.18.1", - "tslib": "2.8.1", - "ws": "^8.18.2" + "@supabase/phoenix": "0.4.5", + "tslib": "2.8.1" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" } }, "node_modules/@supabase/ssr": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@supabase/ssr/-/ssr-0.1.0.tgz", - "integrity": "sha512-bIVrkqjAK5G3KjkIMKYKtAOlCgRRplEWjrlyRyXSOYtgDieiOhk2ZyNAPsEOa1By9OZVxuX5eAW1fitdnuxayw==", + "version": "0.12.7", + "resolved": "https://registry.npmjs.org/@supabase/ssr/-/ssr-0.12.7.tgz", + "integrity": "sha512-wiBtEie1KkRJi9RrZWY3R2imRhX1JY7qMyUCH2z9AUk15gQebNEplM+urbCKamdxaTJLXUU6LlpkJsaxhojCEg==", + "license": "MIT", "dependencies": { - "cookie": "^0.5.0", - "ramda": "^0.29.0" + "cookie": "^1.0.2" }, "peerDependencies": { - "@supabase/supabase-js": "^2.33.1" + "@supabase/supabase-js": "^2.114.0" } }, "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==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/@supabase/storage-js": { - "version": "2.89.0", - "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.89.0.tgz", - "integrity": "sha512-6zKcXofk/M/4Eato7iqpRh+B+vnxeiTumCIP+Tz26xEqIiywzD9JxHq+udRrDuv6hXE+pmetvJd8n5wcf4MFRQ==", + "version": "2.116.0", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.116.0.tgz", + "integrity": "sha512-6/3hR6vccBP6oGM5B6RfbwZcTCKmQOodd/ZWQdsw8yJsU5zO/a//oBL6yLnmgxcjnHSrelW8rsO7hL5DPybyUQ==", "license": "MIT", "dependencies": { "iceberg-js": "^0.8.1", "tslib": "2.8.1" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" } }, "node_modules/@supabase/supabase-js": { - "version": "2.89.0", - "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.89.0.tgz", - "integrity": "sha512-KlaRwSfFA0fD73PYVMHj5/iXFtQGCcX7PSx0FdQwYEEw9b2wqM7GxadY+5YwcmuEhalmjFB/YvqaoNVF+sWUlg==", + "version": "2.116.0", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.116.0.tgz", + "integrity": "sha512-YyWmKXt2NspV9iO8FPnlswUFJIRnrLd3oTCb+3ZyYRuKZtBH0xCUDgnUqoyA0fGUxpM/UhfwDjYf/dht/9bp7g==", "license": "MIT", "dependencies": { - "@supabase/auth-js": "2.89.0", - "@supabase/functions-js": "2.89.0", - "@supabase/postgrest-js": "2.89.0", - "@supabase/realtime-js": "2.89.0", - "@supabase/storage-js": "2.89.0" + "@supabase/auth-js": "2.116.0", + "@supabase/functions-js": "2.116.0", + "@supabase/postgrest-js": "2.116.0", + "@supabase/realtime-js": "2.116.0", + "@supabase/storage-js": "2.116.0" }, "engines": { - "node": ">=20.0.0" + "node": ">=22.0.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + } } }, "node_modules/@surma/rollup-plugin-off-main-thread": { @@ -4016,16 +4033,12 @@ "version": "20.12.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.5.tgz", "integrity": "sha512-BD+BjQ9LS/D8ST9p5uqBxghlN+S42iuNxjsUGjeZobe/ciXzk2qb1B6IXc6AnRLS+yFJRpN2IPEHMzwspfDJNw==", + "dev": true, + "peer": true, "dependencies": { "undici-types": "~5.26.4" } }, - "node_modules/@types/phoenix": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.7.tgz", - "integrity": "sha512-oN9ive//QSBkf19rfDv45M7eZPi0eEXylht2OLEXicu5b4KoQ1OzXIw+xDSGWxSxe1JmepRR/ZH283vsu518/Q==", - "license": "MIT" - }, "node_modules/@types/pug": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", @@ -4062,15 +4075,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "license": "MIT", - "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", @@ -9020,15 +9024,6 @@ } ] }, - "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/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -10908,7 +10903,9 @@ "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==" + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true, + "peer": true }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", @@ -12268,27 +12265,6 @@ "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", - "license": "MIT", - "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/xmlbuilder": { "version": "15.1.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", diff --git a/package.json b/package.json index 850b3d9..eddd0ab 100644 --- a/package.json +++ b/package.json @@ -78,8 +78,8 @@ }, "type": "module", "dependencies": { - "@supabase/ssr": "^0.1.0", - "@supabase/supabase-js": "^2.42.0", + "@supabase/ssr": "^0.12.7", + "@supabase/supabase-js": "^2.116.0", "nanoid": "^5.0.4", "sharp": "^0.33.4" }, diff --git a/src/hooks.server.ts b/src/hooks.server.ts index 21cb307..d63bc14 100644 --- a/src/hooks.server.ts +++ b/src/hooks.server.ts @@ -1,23 +1,20 @@ import { PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY } from '$env/static/public'; import { createServerClient } from '@supabase/ssr'; import type { Handle } from '@sveltejs/kit'; -import type { CookieSerializeOptions } from 'cookie'; export const handle: Handle = async ({ event, resolve }) => { event.locals.supabase = createServerClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, { cookies: { - get: (key: string) => event.cookies.get(key), + getAll: () => event.cookies.getAll(), /** - * 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) + * Note: You have to add the `path` variable to the set method due to sveltekit's cookie + * API requiring this to be set, setting the path to '/' will replicate previous/standard + * behaviour (https://kit.svelte.dev/docs/types#public-types-cookies) */ - set: (key: string, value: string, options: CookieSerializeOptions) => { - event.cookies.set(key, value, { ...options, path: '/' }); - }, - remove: (key: string, options: CookieSerializeOptions) => { - event.cookies.delete(key, { ...options, path: '/' }); + setAll: (cookiesToSet) => { + cookiesToSet.forEach(({ name, value, options }) => { + event.cookies.set(name, value, { ...options, path: '/' }); + }); } } }); diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts index 1d33583..1dde243 100644 --- a/src/routes/+layout.server.ts +++ b/src/routes/+layout.server.ts @@ -1,10 +1,12 @@ import type { LayoutServerLoad } from './$types'; -export const load: LayoutServerLoad = async ({ locals: { safeGetSession } }) => { +export const load: LayoutServerLoad = async ({ locals: { safeGetSession }, cookies }) => { const { session, user } = await safeGetSession(); return { session, - user + user, + // The universal layout load rebuilds a server-side client from these during SSR. + cookies: cookies.getAll() }; }; diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts index d0910b3..72058fb 100644 --- a/src/routes/+layout.ts +++ b/src/routes/+layout.ts @@ -1,7 +1,6 @@ import { PUBLIC_SUPABASE_ANON_KEY, PUBLIC_SUPABASE_URL } from '$env/static/public'; import type { LayoutLoad } from './$types'; -import { createBrowserClient, isBrowser, parse, serialize } from '@supabase/ssr'; -import type { CookieSerializeOptions } from 'cookie'; +import { createBrowserClient, createServerClient, isBrowser } from '@supabase/ssr'; export const load: LayoutLoad = async ({ fetch, data, depends }) => { depends('supabase:auth'); @@ -31,29 +30,23 @@ export const load: LayoutLoad = async ({ fetch, data, depends }) => { return response; }; - const supabase = createBrowserClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, { - global: { - fetch: authFetch - }, - cookies: { - get(key: string) { - if (!isBrowser()) { - return JSON.stringify(data.session); + // The browser client manages document.cookie itself, including removing stale session chunks. + const supabase = isBrowser() + ? createBrowserClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, { + global: { + fetch: authFetch } - - const cookie = parse(document.cookie); - return cookie[key]; - }, - set(key: string, value: string, options: CookieSerializeOptions) { - if (isBrowser()) document.cookie = serialize(key, value, { ...options, path: '/' }); - }, - remove(key: string, options: CookieSerializeOptions) { - if (isBrowser()) { - document.cookie = serialize(key, '', { ...options, path: '/', maxAge: 0 }); + }) + : createServerClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, { + global: { + fetch + }, + cookies: { + getAll() { + return data.cookies; + } } - } - } - }); + }); /** * It's fine to use `getSession` here, because on the client, `getSession` is