From 0efa8a036ad1666a919133df5c342294d2f51917 Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Mon, 23 Mar 2026 16:50:07 +0100 Subject: [PATCH] docs: Update SvelteKit User management tutorial with correct auth methods (#44077) ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../tutorials/with-sveltekit.mdx | 6 +- .../package-lock.json | 381 ++++++++---------- .../sveltekit-user-management/package.json | 22 +- .../sveltekit-user-management/src/app.d.ts | 7 +- .../src/hooks.server.ts | 20 - .../src/routes/+layout.server.ts | 6 +- .../src/routes/+layout.svelte | 4 +- .../src/routes/+layout.ts | 15 +- .../src/routes/+page.server.ts | 6 +- .../src/routes/account/+page.server.ts | 31 +- .../src/routes/account/+page.svelte | 8 +- 11 files changed, 228 insertions(+), 278 deletions(-) diff --git a/apps/docs/content/guides/getting-started/tutorials/with-sveltekit.mdx b/apps/docs/content/guides/getting-started/tutorials/with-sveltekit.mdx index f83a941e777..08d723c8ce0 100644 --- a/apps/docs/content/guides/getting-started/tutorials/with-sveltekit.mdx +++ b/apps/docs/content/guides/getting-started/tutorials/with-sveltekit.mdx @@ -162,16 +162,16 @@ meta="name=src/routes/+page.server.ts" Change the email template to support a server-side authentication flow. -Before we proceed, let's change the email template to support sending a token hash: +Before proceeding, change the email template to support sending a token hash: - Go to the [**Auth** > **Emails**](/dashboard/project/_/auth/templates) page in the project dashboard. - Select the **Confirm signup** template. - Change `{{ .ConfirmationURL }}` to `{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=email`. - Repeat the previous step for **Magic link** template. - + -**Did you know?** You can also customize emails sent out to new users, including the email's looks, content, and query parameters. Check out the [settings of your project](/dashboard/project/_/auth/templates). +You can also customize emails sent out to new users, including the email's looks, content, and query parameters. Check out the [settings of your project](/dashboard/project/_/auth/templates). diff --git a/examples/user-management/sveltekit-user-management/package-lock.json b/examples/user-management/sveltekit-user-management/package-lock.json index 980f5b3d9bf..24aeeaa3d45 100644 --- a/examples/user-management/sveltekit-user-management/package-lock.json +++ b/examples/user-management/sveltekit-user-management/package-lock.json @@ -8,34 +8,18 @@ "name": "supabase-sveltekit", "version": "0.0.1", "dependencies": { - "@supabase/auth-ui-shared": "^0.1.8", - "@supabase/auth-ui-svelte": "^0.2.9", - "@supabase/ssr": "^0.6.1", - "@supabase/supabase-js": "^2.44.2" + "@supabase/ssr": "^0.9.0", + "@supabase/supabase-js": "^2.99.3" }, "devDependencies": { - "@sveltejs/adapter-auto": "^6.0.1", - "@sveltejs/kit": "^2.5.27", - "@sveltejs/vite-plugin-svelte": "^6.1.0", - "svelte": "^5.14.4", - "svelte-check": "^4.1.1", - "tslib": "^2.6.3", - "typescript": "^5.5.3", - "vite": "^7.0.5" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" + "@sveltejs/adapter-auto": "^7.0.1", + "@sveltejs/kit": "^2.55.0", + "@sveltejs/vite-plugin-svelte": "^6.0.0", + "svelte": "^5.54.1", + "svelte-check": "^4.4.5", + "tslib": "^2.8.1", + "typescript": "^5.9.3", + "vite": "^6.0.0" } }, "node_modules/@esbuild/aix-ppc64": { @@ -377,9 +361,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", - "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, "license": "MIT", "dependencies": { @@ -387,6 +371,17 @@ "@jridgewell/trace-mapping": "^0.3.24" } }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", @@ -622,128 +617,109 @@ "optional": true, "os": ["win32"] }, - "node_modules/@stitches/core": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@stitches/core/-/core-1.2.8.tgz", - "integrity": "sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg==", + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, "license": "MIT" }, "node_modules/@supabase/auth-js": { - "version": "2.71.1", - "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.71.1.tgz", - "integrity": "sha512-mMIQHBRc+SKpZFRB2qtupuzulaUhFYupNyxqDj5Jp/LyPvcWvjaJzZzObv6URtL/O6lPxkanASnotGtNpS3H2Q==", + "version": "2.100.0", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.100.0.tgz", + "integrity": "sha512-pdT3ye3UVRN1Cg0wom6BmyY+XTtp5DiJaYnPi6j8ht5i8Lq8kfqxJMJz9GI9YDKk3w1nhGOPnh6Qz5qpyYm+1w==", "license": "MIT", "dependencies": { - "@supabase/node-fetch": "^2.6.14" - } - }, - "node_modules/@supabase/auth-ui-shared": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/@supabase/auth-ui-shared/-/auth-ui-shared-0.1.8.tgz", - "integrity": "sha512-ouQ0DjKcEFg+0gZigFIEgu01V3e6riGZPzgVD0MJsCBNsMsiDT74+GgCEIElMUpTGkwSja3xLwdFRFgMNFKcjg==", - "license": "MIT", - "peerDependencies": { - "@supabase/supabase-js": "^2.21.0" - } - }, - "node_modules/@supabase/auth-ui-svelte": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@supabase/auth-ui-svelte/-/auth-ui-svelte-0.2.9.tgz", - "integrity": "sha512-oc+SRS7ykc5FCssoqT0IiK5KF/obwnWko5ePaaMTDwUEQOavv+O8/poAh2lRTKRJCqJMqOOpMS/lUE6pHcma3g==", - "dependencies": { - "@stitches/core": "^1.2.8", - "@supabase/auth-ui-shared": "0.1.8", - "svelte": "^3.55.1" + "tslib": "2.8.1" }, - "peerDependencies": { - "@supabase/supabase-js": "^2.21.0" - } - }, - "node_modules/@supabase/auth-ui-svelte/node_modules/svelte": { - "version": "3.59.2", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.2.tgz", - "integrity": "sha512-vzSyuGr3eEoAtT/A6bmajosJZIUWySzY2CzB3w2pgPvnkUjGqlDnsNnA0PMO+mMAhuyMul6C2uuZzY6ELSkzyA==", - "license": "MIT", "engines": { - "node": ">= 8" + "node": ">=20.0.0" } }, "node_modules/@supabase/functions-js": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.4.5.tgz", - "integrity": "sha512-v5GSqb9zbosquTo6gBwIiq7W9eQ7rE5QazsK/ezNiQXdCbY+bH8D9qEaBIkhVvX4ZRW5rP03gEfw5yw9tiq4EQ==", + "version": "2.100.0", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.100.0.tgz", + "integrity": "sha512-keLg79RPwP+uiwHuxFPTFgDRxPV46LM4j/swjyR2GKJgWniTVSsgiBHfbIBDcrQwehLepy09b/9QSHUywtKRWQ==", "license": "MIT", "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==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" + "tslib": "2.8.1" }, "engines": { - "node": "4.x || >=6.0.0" + "node": ">=20.0.0" } }, + "node_modules/@supabase/phoenix": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@supabase/phoenix/-/phoenix-0.4.0.tgz", + "integrity": "sha512-RHSx8bHS02xwfHdAbX5Lpbo6PXbgyf7lTaXTlwtFDPwOIw64NnVRwFAXGojHhjtVYI+PEPNSWwkL90f4agN3bw==", + "license": "MIT" + }, "node_modules/@supabase/postgrest-js": { - "version": "1.19.4", - "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.19.4.tgz", - "integrity": "sha512-O4soKqKtZIW3olqmbXXbKugUtByD2jPa8kL2m2c1oozAO11uCcGrRhkZL0kVxjBLrXHE0mdSkFsMj7jDSfyNpw==", + "version": "2.100.0", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.100.0.tgz", + "integrity": "sha512-xYNvNbBJaXOGcrZ44wxwp5830uo1okMHGS8h8dm3u4f0xcZ39yzbryUsubTJW41MG2gbL/6U57cA4Pi6YMZ9pA==", "license": "MIT", "dependencies": { - "@supabase/node-fetch": "^2.6.14" + "tslib": "2.8.1" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@supabase/realtime-js": { - "version": "2.11.15", - "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.11.15.tgz", - "integrity": "sha512-HQKRnwAqdVqJW/P9TjKVK+/ETpW4yQ8tyDPPtRMKOH4Uh3vQD74vmj353CYs8+YwVBKubeUOOEpI9CT8mT4obw==", + "version": "2.100.0", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.100.0.tgz", + "integrity": "sha512-2AZs00zzEF0HuCKY8grz5eCYlwEfVi5HONLZFoNR6aDfxQivl8zdQYNjyFoqN2MZiVhQHD7u6XV/xHwM8mCEHw==", "license": "MIT", "dependencies": { - "@supabase/node-fetch": "^2.6.13", - "@types/phoenix": "^1.6.6", + "@supabase/phoenix": "^0.4.0", "@types/ws": "^8.18.1", - "isows": "^1.0.7", + "tslib": "2.8.1", "ws": "^8.18.2" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@supabase/ssr": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@supabase/ssr/-/ssr-0.6.1.tgz", - "integrity": "sha512-QtQgEMvaDzr77Mk3vZ3jWg2/y+D8tExYF7vcJT+wQ8ysuvOeGGjYbZlvj5bHYsj/SpC0bihcisnwPrM4Gp5G4g==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@supabase/ssr/-/ssr-0.9.0.tgz", + "integrity": "sha512-UFY6otYV3yqCgV+AyHj80vNkTvbf1Gas2LW4dpbQ4ap6p6v3eB2oaDfcI99jsuJzwVBCFU4BJI+oDYyhNk1z0Q==", "license": "MIT", "dependencies": { - "cookie": "^1.0.1" + "cookie": "^1.0.2" }, "peerDependencies": { - "@supabase/supabase-js": "^2.43.4" + "@supabase/supabase-js": "^2.97.0" } }, "node_modules/@supabase/storage-js": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.7.1.tgz", - "integrity": "sha512-asYHcyDR1fKqrMpytAS1zjyEfvxuOIp1CIXX7ji4lHHcJKqyk+sLl/Vxgm4sN6u8zvuUtae9e4kDxQP2qrwWBA==", + "version": "2.100.0", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.100.0.tgz", + "integrity": "sha512-d4EeuK6RNIgYNA2MU9kj8lQrLm5AzZ+WwpWjGkii6SADQNIGTC/uiaTRu02XJ5AmFALQfo8fLl9xuCkO6Xw+iQ==", "license": "MIT", "dependencies": { - "@supabase/node-fetch": "^2.6.14" + "iceberg-js": "^0.8.1", + "tslib": "2.8.1" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@supabase/supabase-js": { - "version": "2.52.0", - "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.52.0.tgz", - "integrity": "sha512-jbs3CV1f2+ge7sgBeEduboT9v/uGjF22v0yWi/5/XFn5tbM8MfWRccsMtsDwAwu24XK8H6wt2LJDiNnZLtx/bg==", + "version": "2.100.0", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.100.0.tgz", + "integrity": "sha512-r0tlcukejJXJ1m/2eG/Ya5eYs4W8AC7oZfShpG3+SIo/eIU9uIt76ZeYI1SoUwUmcmzlAbgch+HDZDR/toVQPQ==", "license": "MIT", "dependencies": { - "@supabase/auth-js": "2.71.1", - "@supabase/functions-js": "2.4.5", - "@supabase/node-fetch": "2.6.15", - "@supabase/postgrest-js": "1.19.4", - "@supabase/realtime-js": "2.11.15", - "@supabase/storage-js": "2.7.1" + "@supabase/auth-js": "2.100.0", + "@supabase/functions-js": "2.100.0", + "@supabase/postgrest-js": "2.100.0", + "@supabase/realtime-js": "2.100.0", + "@supabase/storage-js": "2.100.0" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@sveltejs/acorn-typescript": { @@ -757,9 +733,9 @@ } }, "node_modules/@sveltejs/adapter-auto": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-6.0.1.tgz", - "integrity": "sha512-mcWud3pYGPWM2Pphdj8G9Qiq24nZ8L4LB7coCUckUEy5Y7wOWGJ/enaZ4AtJTcSm5dNK1rIkBRoqt+ae4zlxcQ==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-7.0.1.tgz", + "integrity": "sha512-dvuPm1E7M9NI/+canIQ6KKQDU2AkEefEZ2Dp7cY6uKoPq9Z/PhOXABe526UdW2mN986gjVkuSLkOYIBnS/M2LQ==", "dev": true, "license": "MIT", "peerDependencies": { @@ -767,23 +743,23 @@ } }, "node_modules/@sveltejs/kit": { - "version": "2.25.1", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.25.1.tgz", - "integrity": "sha512-8H+fxDEp7Xq6tLFdrGdS5fLu6ONDQQ9DgyjboXpChubuFdfH9QoFX09ypssBpyNkJNZFt9eW3yLmXIc9CesPCA==", + "version": "2.55.0", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.55.0.tgz", + "integrity": "sha512-MdFRjevVxmAknf2NbaUkDF16jSIzXMWd4Nfah0Qp8TtQVoSp3bV4jKt8mX7z7qTUTWvgSaxtR0EG5WJf53gcuA==", "dev": true, "license": "MIT", "dependencies": { + "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/cookie": "^0.6.0", "acorn": "^8.14.1", "cookie": "^0.6.0", - "devalue": "^5.1.0", + "devalue": "^5.6.4", "esm-env": "^1.2.2", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", - "sade": "^1.8.1", - "set-cookie-parser": "^2.6.0", + "set-cookie-parser": "^3.0.0", "sirv": "^3.0.0" }, "bin": { @@ -793,9 +769,19 @@ "node": ">=18.13" }, "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0", + "@opentelemetry/api": "^1.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 || ^7.0.0", "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0" + "typescript": "^5.3.3", + "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "typescript": { + "optional": true + } } }, "node_modules/@sveltejs/kit/node_modules/cookie": { @@ -871,10 +857,11 @@ "undici-types": "~7.8.0" } }, - "node_modules/@types/phoenix": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@types/phoenix/-/phoenix-1.6.6.tgz", - "integrity": "sha512-PIzZZlEppgrpoT2QgbnDU+MMzuR6BbCjllj0bM70lWoejMeNJAxCchxnv7J3XFkI8MpygtRpzXrIlmWUBclP5A==", + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "dev": true, "license": "MIT" }, "node_modules/@types/ws": { @@ -886,6 +873,20 @@ "@types/node": "*" } }, + "node_modules/@typescript-eslint/types": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz", + "integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", @@ -900,9 +901,9 @@ } }, "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", + "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", "dev": true, "license": "Apache-2.0", "engines": { @@ -983,9 +984,9 @@ } }, "node_modules/devalue": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz", - "integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==", + "version": "5.6.4", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.4.tgz", + "integrity": "sha512-Gp6rDldRsFh/7XuouDbxMH3Mx8GMCcgzIb1pDTvNyn8pZGQ22u+Wa+lGV9dQCltFQ7uVw0MhRyb8XDskNFOReA==", "dev": true, "license": "MIT" }, @@ -1039,13 +1040,14 @@ "license": "MIT" }, "node_modules/esrap": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.1.0.tgz", - "integrity": "sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.4.tgz", + "integrity": "sha512-suICpxAmZ9A8bzJjEl/+rLJiDKC0X4gYWUxT6URAWBLvlXmtbZd5ySMu/N2ZGEtMCAmflUDPSehrP9BQcsGcSg==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.4.15", + "@typescript-eslint/types": "^8.2.0" } }, "node_modules/fdir": { @@ -1076,6 +1078,15 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/iceberg-js": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/iceberg-js/-/iceberg-js-0.8.1.tgz", + "integrity": "sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/is-reference": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", @@ -1086,21 +1097,6 @@ "@types/estree": "^1.0.6" } }, - "node_modules/isows": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", - "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "peerDependencies": { - "ws": "*" - } - }, "node_modules/kleur": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", @@ -1291,9 +1287,9 @@ } }, "node_modules/set-cookie-parser": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.0.tgz", + "integrity": "sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==", "dev": true, "license": "MIT" }, @@ -1323,22 +1319,24 @@ } }, "node_modules/svelte": { - "version": "5.36.12", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.36.12.tgz", - "integrity": "sha512-c3mWT+b0yBLl3gPGSHiy4pdSQCsPNTjLC0tVoOhrGJ6PPfCzD/RQpAmAfJtQZ304CAae2ph+L3C4aqds3R3seQ==", + "version": "5.54.1", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.54.1.tgz", + "integrity": "sha512-ow8tncN097Ty8U1H+C3bM1xNlsCbnO2UZeN0lWBnv8f3jKho7QTTQ2LWbMXrPQDodLjH91n4kpNnLolyRhVE6A==", "dev": true, "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.3.0", + "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", + "@types/trusted-types": "^2.0.7", "acorn": "^8.12.1", - "aria-query": "^5.3.1", + "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", + "devalue": "^5.6.4", "esm-env": "^1.2.1", - "esrap": "^2.1.0", + "esrap": "^2.2.2", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", @@ -1349,9 +1347,9 @@ } }, "node_modules/svelte-check": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.3.0.tgz", - "integrity": "sha512-Iz8dFXzBNAM7XlEIsUjUGQhbEE+Pvv9odb9+0+ITTgFWZBGeJRRYqHUUglwe2EkLD5LIsQaAc4IUJyvtKuOO5w==", + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.4.5.tgz", + "integrity": "sha512-1bSwIRCvvmSHrlK52fOlZmVtUZgil43jNL/2H18pRpa+eQjzGt6e3zayxhp1S7GajPFKNM/2PMCG+DZFHlG9fw==", "dev": true, "license": "MIT", "dependencies": { @@ -1399,23 +1397,16 @@ "node": ">=6" } }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, "license": "0BSD" }, "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -1433,24 +1424,24 @@ "license": "MIT" }, "node_modules/vite": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.0.5.tgz", - "integrity": "sha512-1mncVwJxy2C9ThLwz0+2GKZyEXuC3MyWtAAlNftlZZXZDP3AJt5FmwcMit/IGGaNZ8ZOB2BNO/HFUB+CpN0NQw==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", + "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", - "fdir": "^6.4.6", + "fdir": "^6.4.4", "picomatch": "^4.0.2", - "postcss": "^8.5.6", - "rollup": "^4.40.0", - "tinyglobby": "^0.2.14" + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^20.19.0 || >=22.12.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -1459,14 +1450,14 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", - "less": "^4.0.0", + "less": "*", "lightningcss": "^1.21.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" @@ -1523,26 +1514,10 @@ } } }, - "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==", - "license": "BSD-2-Clause" - }, - "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==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", "license": "MIT", "engines": { "node": ">=10.0.0" diff --git a/examples/user-management/sveltekit-user-management/package.json b/examples/user-management/sveltekit-user-management/package.json index 2a651dad6cd..ede8632bc5b 100644 --- a/examples/user-management/sveltekit-user-management/package.json +++ b/examples/user-management/sveltekit-user-management/package.json @@ -10,20 +10,18 @@ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" }, "devDependencies": { - "@sveltejs/adapter-auto": "^6.0.1", - "@sveltejs/kit": "^2.5.27", - "@sveltejs/vite-plugin-svelte": "^6.1.0", - "svelte": "^5.14.4", - "svelte-check": "^4.1.1", - "tslib": "^2.6.3", - "typescript": "^5.5.3", - "vite": "^7.1.5" + "@sveltejs/adapter-auto": "^7.0.1", + "@sveltejs/kit": "^2.55.0", + "@sveltejs/vite-plugin-svelte": "^6.0.0", + "svelte": "^5.54.1", + "svelte-check": "^4.4.5", + "tslib": "^2.8.1", + "typescript": "^5.9.3", + "vite": "^6.0.0" }, "type": "module", "dependencies": { - "@supabase/auth-ui-shared": "^0.1.8", - "@supabase/auth-ui-svelte": "^0.2.9", - "@supabase/ssr": "^0.6.1", - "@supabase/supabase-js": "^2.44.2" + "@supabase/ssr": "^0.9.0", + "@supabase/supabase-js": "^2.99.3" } } diff --git a/examples/user-management/sveltekit-user-management/src/app.d.ts b/examples/user-management/sveltekit-user-management/src/app.d.ts index dc27c2fc971..617d908c9d6 100644 --- a/examples/user-management/sveltekit-user-management/src/app.d.ts +++ b/examples/user-management/sveltekit-user-management/src/app.d.ts @@ -1,4 +1,4 @@ -import { SupabaseClient, Session } from '@supabase/supabase-js' +import type { SupabaseClient } from '@supabase/supabase-js' // See https://kit.svelte.dev/docs/types#app // for information about these interfaces declare global { @@ -6,11 +6,6 @@ declare global { // interface Error {} interface Locals { supabase: SupabaseClient - safeGetSession(): Promise<{ session: Session | null; user?: Session['user'] | null }> - } - interface PageData { - session: Session | null - user?: Session['user'] | null } // interface PageState {} // interface Platform {} diff --git a/examples/user-management/sveltekit-user-management/src/hooks.server.ts b/examples/user-management/sveltekit-user-management/src/hooks.server.ts index 4da88ef59bf..c4fc1ed71a0 100644 --- a/examples/user-management/sveltekit-user-management/src/hooks.server.ts +++ b/examples/user-management/sveltekit-user-management/src/hooks.server.ts @@ -21,26 +21,6 @@ export const handle: Handle = async ({ event, resolve }) => { }, }) - /** - * 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: string) { return name === 'content-range' || name === 'x-supabase-api-version' diff --git a/examples/user-management/sveltekit-user-management/src/routes/+layout.server.ts b/examples/user-management/sveltekit-user-management/src/routes/+layout.server.ts index e48f6467f0c..a859d77e7a4 100644 --- a/examples/user-management/sveltekit-user-management/src/routes/+layout.server.ts +++ b/examples/user-management/sveltekit-user-management/src/routes/+layout.server.ts @@ -1,12 +1,8 @@ // src/routes/+layout.server.ts import type { LayoutServerLoad } from './$types' -export const load: LayoutServerLoad = async ({ locals: { safeGetSession }, cookies }) => { - const { session, user } = await safeGetSession() - +export const load: LayoutServerLoad = async ({ cookies }) => { return { - session, - user, cookies: cookies.getAll(), } } diff --git a/examples/user-management/sveltekit-user-management/src/routes/+layout.svelte b/examples/user-management/sveltekit-user-management/src/routes/+layout.svelte index 50611f57fd0..d2d87ba53d9 100644 --- a/examples/user-management/sveltekit-user-management/src/routes/+layout.svelte +++ b/examples/user-management/sveltekit-user-management/src/routes/+layout.svelte @@ -5,11 +5,11 @@ import { onMount } from 'svelte' let { data, children } = $props() - let { supabase, session } = $derived(data) + let { supabase, claims } = $derived(data) onMount(() => { const { data } = supabase.auth.onAuthStateChange((event, _session) => { - if (_session?.expires_at !== session?.expires_at) { + if (_session?.expires_at !== claims?.exp) { invalidate('supabase:auth') } }) diff --git a/examples/user-management/sveltekit-user-management/src/routes/+layout.ts b/examples/user-management/sveltekit-user-management/src/routes/+layout.ts index 5b23fe3779f..f8aa0f1c434 100644 --- a/examples/user-management/sveltekit-user-management/src/routes/+layout.ts +++ b/examples/user-management/sveltekit-user-management/src/routes/+layout.ts @@ -24,13 +24,14 @@ export const load: LayoutLoad = async ({ fetch, data, depends }) => { }) /** - * It's fine to use `getSession` here, because on the client, `getSession` is - * safe, and on the server, it reads `session` from the `LayoutData`, which - * safely checked the session using `safeGetSession`. + * `getClaims` validates the JWT signature locally (for asymmetric keys) once + * the relevant signing keys are available or cached, and returns the decoded + * claims. While an initial or periodic network request may be required to + * fetch or refresh keys, this is both faster and safer than `getSession`, + * which does not validate the JWT. */ - const { - data: { session }, - } = await supabase.auth.getSession() + const { data: claimsData, error } = await supabase.auth.getClaims() + const claims = error ? null : claimsData?.claims - return { supabase, session } + return { supabase, claims } } diff --git a/examples/user-management/sveltekit-user-management/src/routes/+page.server.ts b/examples/user-management/sveltekit-user-management/src/routes/+page.server.ts index 46c96683422..e614c35c551 100644 --- a/examples/user-management/sveltekit-user-management/src/routes/+page.server.ts +++ b/examples/user-management/sveltekit-user-management/src/routes/+page.server.ts @@ -2,11 +2,11 @@ import { fail, redirect } from '@sveltejs/kit' import type { Actions, PageServerLoad } from './$types' -export const load: PageServerLoad = async ({ url, locals: { safeGetSession } }) => { - const { session } = await safeGetSession() +export const load: PageServerLoad = async ({ url, locals: { supabase } }) => { + const { data, error } = await supabase.auth.getClaims() // if the user is already logged in return them to the account page - if (session) { + if (!error && data?.claims) { redirect(303, '/account') } diff --git a/examples/user-management/sveltekit-user-management/src/routes/account/+page.server.ts b/examples/user-management/sveltekit-user-management/src/routes/account/+page.server.ts index 5d571f7a5c8..81768839d2c 100644 --- a/examples/user-management/sveltekit-user-management/src/routes/account/+page.server.ts +++ b/examples/user-management/sveltekit-user-management/src/routes/account/+page.server.ts @@ -1,34 +1,40 @@ import { fail, redirect } from '@sveltejs/kit' import type { Actions, PageServerLoad } from './$types' -export const load: PageServerLoad = async ({ locals: { supabase, safeGetSession } }) => { - const { session } = await safeGetSession() +export const load: PageServerLoad = async ({ locals: { supabase } }) => { + const { data: claimsData, error } = await supabase.auth.getClaims() - if (!session) { + if (error || !claimsData?.claims) { redirect(303, '/') } + const { claims } = claimsData + const { data: profile } = await supabase .from('profiles') .select(`username, full_name, website, avatar_url`) - .eq('id', session.user.id) + .eq('id', claims.sub) .single() - return { session, profile } + return { claims, profile } } export const actions: Actions = { - update: async ({ request, locals: { supabase, safeGetSession } }) => { + update: async ({ request, locals: { supabase } }) => { const formData = await request.formData() const fullName = formData.get('fullName') as string const username = formData.get('username') as string const website = formData.get('website') as string const avatarUrl = formData.get('avatarUrl') as string - const { session } = await safeGetSession() + const { data: claimsData, error: claimsError } = await supabase.auth.getClaims() + + if (claimsError || !claimsData?.claims) { + return fail(401, { fullName, username, website, avatarUrl }) + } const { error } = await supabase.from('profiles').upsert({ - id: session?.user.id, + id: claimsData.claims.sub, full_name: fullName, username, website, @@ -52,11 +58,8 @@ export const actions: Actions = { avatarUrl, } }, - signout: async ({ locals: { supabase, safeGetSession } }) => { - const { session } = await safeGetSession() - if (session) { - await supabase.auth.signOut() - redirect(303, '/') - } + signout: async ({ locals: { supabase } }) => { + await supabase.auth.signOut() + redirect(303, '/') }, } diff --git a/examples/user-management/sveltekit-user-management/src/routes/account/+page.svelte b/examples/user-management/sveltekit-user-management/src/routes/account/+page.svelte index dde5b750462..a9e1e22fee9 100644 --- a/examples/user-management/sveltekit-user-management/src/routes/account/+page.svelte +++ b/examples/user-management/sveltekit-user-management/src/routes/account/+page.svelte @@ -4,7 +4,7 @@ import Avatar from './Avatar.svelte' let { data, form } = $props() - let { session, supabase, profile } = $derived(data) + let { claims, supabase, profile } = $derived(data) let profileForm: HTMLFormElement let loading = $state(false) let fullName: string = profile?.full_name ?? '' @@ -14,8 +14,9 @@ const handleSubmit: SubmitFunction = () => { loading = true - return async () => { + return async ({ update }) => { loading = false + update() } } @@ -44,9 +45,10 @@ profileForm.requestSubmit(); }} /> +
- +