@auth/sveltekit
Advanced tools
Comparing version 0.11.1 to 0.12.0
{ | ||
"name": "@auth/sveltekit", | ||
"version": "0.11.1", | ||
"version": "0.12.0", | ||
"description": "Authentication for SvelteKit.", | ||
@@ -28,3 +28,3 @@ "keywords": [ | ||
"@sveltejs/kit": "^2.4.3", | ||
"@sveltejs/package": "^1.0.0", | ||
"@sveltejs/package": "^2.0.0", | ||
"@sveltejs/vite-plugin-svelte": "^3.0.0", | ||
@@ -38,3 +38,3 @@ "@types/set-cookie-parser": "^2.4.7", | ||
"set-cookie-parser": "^2.6.0", | ||
"@auth/core": "0.25.1" | ||
"@auth/core": "0.26.0" | ||
}, | ||
@@ -46,7 +46,5 @@ "peerDependencies": { | ||
"type": "module", | ||
"types": "./index.d.ts", | ||
"types": "./dist/index.d.ts", | ||
"files": [ | ||
"client.*", | ||
"index.*", | ||
"providers", | ||
"dist", | ||
"src" | ||
@@ -56,18 +54,22 @@ ], | ||
".": { | ||
"types": "./index.d.ts", | ||
"import": "./index.js" | ||
"types": "./dist/index.d.ts", | ||
"import": "./dist/index.js" | ||
}, | ||
"./client": { | ||
"types": "./client.d.ts", | ||
"import": "./client.js" | ||
"types": "./dist/client.d.ts", | ||
"import": "./dist/client.js" | ||
}, | ||
"./components": { | ||
"types": "./dist/components/index.d.ts", | ||
"svelte": "./dist/components/index.js" | ||
}, | ||
"./adapters": { | ||
"types": "./adapters.d.ts" | ||
"types": "./dist/adapters.d.ts" | ||
}, | ||
"./providers": { | ||
"types": "./providers/index.d.ts" | ||
"types": "./dist/providers/index.d.ts" | ||
}, | ||
"./providers/*": { | ||
"types": "./providers/*.d.ts", | ||
"import": "./providers/*.js" | ||
"types": "./dist/providers/*.d.ts", | ||
"import": "./dist/providers/*.js" | ||
}, | ||
@@ -77,7 +79,7 @@ "./package.json": "./package.json" | ||
"scripts": { | ||
"build": "pnpm clean && pnpm providers && pnpm check && svelte-package && node ./scripts/postbuild.js && rm -rf package", | ||
"build": "pnpm clean && pnpm providers && pnpm check && svelte-package", | ||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", | ||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", | ||
"clean": "rm -rf client.* index.* package src/lib/providers", | ||
"dev": "svelte-package -w", | ||
"dev": "pnpm providers && svelte-package -w", | ||
"preview": "vite preview", | ||
@@ -84,0 +86,0 @@ "providers": "node ../utils/scripts/providers.js --out src/lib", |
@@ -16,4 +16,5 @@ /** | ||
* ## Usage | ||
* | ||
* ```ts title="src/hooks.server.ts" | ||
* | ||
* ```ts title="src/auth.ts" | ||
* | ||
* import { SvelteKitAuth } from "@auth/sveltekit" | ||
@@ -23,10 +24,10 @@ * import GitHub from "@auth/sveltekit/providers/github" | ||
* | ||
* export const handle = SvelteKitAuth({ | ||
* export const { handle, signIn signOut } = SvelteKitAuth({ | ||
* providers: [GitHub({ clientId: GITHUB_ID, clientSecret: GITHUB_SECRET })], | ||
* }) | ||
* ``` | ||
* | ||
* | ||
* or to use SvelteKit platform environment variables for platforms like Cloudflare | ||
* | ||
* ```ts title="src/hooks.server.ts" | ||
* ```ts title="src/auth.ts" | ||
* import { SvelteKitAuth } from "@auth/sveltekit" | ||
@@ -36,3 +37,3 @@ * import GitHub from "@auth/sveltekit/providers/github" | ||
* | ||
* export const handle = SvelteKitAuth(async (event) => { | ||
* export const { handle, signIn, signOut } = SvelteKitAuth(async (event) => { | ||
* const authOptions = { | ||
@@ -47,2 +48,7 @@ * providers: [GitHub({ clientId: event.platform.env.GITHUB_ID, clientSecret: event.platform.env.GITHUB_SECRET })] | ||
* | ||
* Re-export the handle in `src/hooks.server.ts`: | ||
* ```ts title="src/hooks.server.ts" | ||
* export { handle } from "./auth" | ||
* ``` | ||
* | ||
* Remember to set the `AUTH_SECRET` [environment variable](https://kit.svelte.dev/docs/modules#$env-dynamic-private). This should be a minimum of 32 characters, random string. On UNIX systems you can use `openssl rand -hex 32` or check out `https://generate-secret.vercel.app/32`. | ||
@@ -64,3 +70,3 @@ * | ||
* <script> | ||
* import { signIn, signOut } from "@auth/sveltekit/client" | ||
* import { SignIn, SignOut } from "@auth/sveltekit/components" | ||
* import { page } from "$app/stores" | ||
@@ -82,9 +88,31 @@ * </script> | ||
* </span> | ||
* <button on:click={() => signOut()} class="button">Sign out</button> | ||
* <SignOut /> | ||
* {:else} | ||
* <span class="notSignedInText">You are not signed in</span> | ||
* <button on:click={() => signIn("github")}>Sign In with GitHub</button> | ||
* <SignIn provider="github"/> | ||
* <SignIn provider="google"/> | ||
* <SignIn provider="facebook"/> | ||
* {/if} | ||
* </p> | ||
* ``` | ||
* | ||
* `<SignIn />` and `<SignOut />` are components that `@auth/sveltekit` provides out of the box - they handle the sign-in/signout flow, and can be used as-is as a starting point or customized for your own components. | ||
* To set up the form actions, we need to define the files in `src/routes`: | ||
* ```ts title="src/routes/signin/+page.server.ts" | ||
* import { signIn } from "../../auth" | ||
* import type { Actions } from "./$types" | ||
* export const actions: Actions = { default: signIn } | ||
* ``` | ||
* ```ts title="src/routes/signin/+page.svelte" | ||
* <!-- empty file --> | ||
* ``` | ||
* ```ts title="src/routes/signout/+page.server.ts" | ||
* import { signOut } from "../../auth" | ||
* import type { Actions } from "./$types" | ||
* export const actions: Actions = { default: signOut } | ||
* ``` | ||
* ```ts title="src/routes/signout/+page.svelte" | ||
* <!-- empty file --> | ||
* ``` | ||
* | ||
* | ||
@@ -207,10 +235,9 @@ * ## Managing the session | ||
/// <reference types="@sveltejs/kit" /> | ||
import type { Handle, RequestEvent } from "@sveltejs/kit" | ||
import { parse } from "set-cookie-parser" | ||
import { dev, building } from "$app/environment" | ||
import { base } from "$app/paths" | ||
import type { Action, Handle, RequestEvent } from "@sveltejs/kit" | ||
import { env } from "$env/dynamic/private" | ||
import { Auth, setEnvDefaults as coreSetEnvDefaults } from "@auth/core" | ||
import type { AuthAction, AuthConfig, Session } from "@auth/core/types" | ||
import type { SvelteKitAuthConfig } from "./types" | ||
import { setEnvDefaults } from "./env" | ||
import { auth, signIn, signOut } from "./actions" | ||
import { Auth, isAuthAction } from "@auth/core" | ||
@@ -225,47 +252,4 @@ export type { | ||
async function auth( | ||
event: RequestEvent, | ||
config: SvelteKitAuthConfig | ||
): ReturnType<App.Locals["auth"]> { | ||
setEnvDefaults(config) | ||
config.trustHost ??= true | ||
const authorizationParamsPrefix = "authorizationParams-" | ||
const { request: req } = event | ||
const basePath = config.basePath ?? `${base}/auth` | ||
const url = new URL(basePath + "/session", req.url) | ||
const request = new Request(url, { | ||
headers: { cookie: req.headers.get("cookie") ?? "" }, | ||
}) | ||
const response = await Auth(request, config) | ||
const authCookies = parse(response.headers.getSetCookie()) | ||
for (const cookie of authCookies) { | ||
const { name, value, ...options } = cookie | ||
// @ts-expect-error - Review: SvelteKit and set-cookie-parser are mismatching | ||
event.cookies.set(name, value, { path: "/", ...options }) | ||
} | ||
const { status = 200 } = response | ||
const data = await response.json() | ||
if (!data || !Object.keys(data).length) return null | ||
if (status === 200) return data | ||
throw new Error(data.message) | ||
} | ||
/** Configure the {@link SvelteKitAuth} method. */ | ||
export interface SvelteKitAuthConfig extends Omit<AuthConfig, "raw"> {} | ||
const actions: AuthAction[] = [ | ||
"providers", | ||
"session", | ||
"csrf", | ||
"signin", | ||
"signout", | ||
"callback", | ||
"verify-request", | ||
"error", | ||
] | ||
/** | ||
@@ -279,59 +263,64 @@ * The main entry point to `@auth/sveltekit` | ||
| ((event: RequestEvent) => PromiseLike<SvelteKitAuthConfig>) | ||
): Handle { | ||
return async function ({ event, resolve }) { | ||
const _config = typeof config === "object" ? config : await config(event) | ||
setEnvDefaults(_config) | ||
): { | ||
handle: Handle | ||
signIn: Action | ||
signOut: Action | ||
} { | ||
return { | ||
signIn: async (event) => { | ||
const { request } = event | ||
const _config = typeof config === "object" ? config : await config(event) | ||
setEnvDefaults(env, _config) | ||
const formData = await request.formData() | ||
const { providerId: provider, ...options } = Object.fromEntries(formData) | ||
// get the authorization params from the options prefixed with `authorizationParams-` | ||
let authorizationParams: Parameters<typeof signIn>[2] = {} | ||
let _options: Parameters<typeof signIn>[1] = {} | ||
for (const key in options) { | ||
if (key.startsWith(authorizationParamsPrefix)) { | ||
authorizationParams[key.slice(authorizationParamsPrefix.length)] = | ||
options[key] as string | ||
} else { | ||
_options[key] = options[key] | ||
} | ||
} | ||
await signIn( | ||
provider as string, | ||
_options, | ||
authorizationParams, | ||
_config, | ||
event | ||
) | ||
}, | ||
signOut: async (event) => { | ||
const _config = typeof config === "object" ? config : await config(event) | ||
setEnvDefaults(env, _config) | ||
const options = Object.fromEntries(await event.request.formData()) | ||
await signOut(options, _config, event) | ||
}, | ||
async handle({ event, resolve }) { | ||
const _config = typeof config === "object" ? config : await config(event) | ||
setEnvDefaults(env, _config) | ||
const { url, request } = event | ||
const { url, request } = event | ||
event.locals.auth ??= () => auth(event, _config) | ||
event.locals.getSession ??= event.locals.auth | ||
event.locals.auth ??= () => auth(event, _config) | ||
event.locals.getSession ??= event.locals.auth | ||
const action = url.pathname | ||
.slice( | ||
// @ts-expect-error - basePath is defined in setEnvDefaults | ||
_config.basePath.length + 1 | ||
) | ||
.split("/")[0] | ||
const action = url.pathname | ||
.slice( | ||
// @ts-expect-error - basePath is defined in setEnvDefaults | ||
_config.basePath.length + 1 | ||
) | ||
.split("/")[0] | ||
if (isAction(action) && url.pathname.startsWith(_config.basePath + "/")) { | ||
return Auth(request, _config) | ||
} | ||
return resolve(event) | ||
if ( | ||
isAuthAction(action) && | ||
url.pathname.startsWith(_config.basePath + "/") | ||
) { | ||
return Auth(request, _config) | ||
} | ||
return resolve(event) | ||
}, | ||
} | ||
} | ||
// TODO: Get this function from @auth/core/util | ||
function isAction(action: string): action is AuthAction { | ||
return actions.includes(action as AuthAction) | ||
} | ||
declare global { | ||
// eslint-disable-next-line @typescript-eslint/no-namespace | ||
namespace App { | ||
interface Locals { | ||
auth(): Promise<Session | null> | ||
/** @deprecated Use `auth` instead. */ | ||
getSession(): Promise<Session | null> | ||
} | ||
interface PageData { | ||
session?: Session | null | ||
} | ||
} | ||
} | ||
declare module "$env/dynamic/private" { | ||
export const AUTH_SECRET: string | ||
export const AUTH_SECRET_1: string | ||
export const AUTH_SECRET_2: string | ||
export const AUTH_SECRET_3: string | ||
export const AUTH_TRUST_HOST: string | ||
export const VERCEL: string | ||
} | ||
function setEnvDefaults(config: SvelteKitAuthConfig) { | ||
if (building) return | ||
coreSetEnvDefaults(env, config) | ||
config.trustHost ??= dev | ||
config.basePath = `${base}/auth` | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
86955
194
1803
5
+ Added@auth/core@0.26.0(transitive)
- Removed@auth/core@0.25.1(transitive)
Updated@auth/core@0.26.0