From ac0dbae10a91f9648287e11fb3f34b5791799985 Mon Sep 17 00:00:00 2001 From: Thang Vu Date: Thu, 8 Dec 2022 11:17:52 +0700 Subject: [PATCH] fix AuthHandler, add getServerSession --- apps/playground-sveltekit/src/hooks.server.ts | 6 +- .../playground-sveltekit/src/lib/next-auth.ts | 147 ------------------ .../routes/api/auth/[...nextauth]/+server.ts | 14 +- package.json | 7 +- packages/frameworks/sveltekit/package.json | 2 - packages/frameworks/sveltekit/src/app.d.ts | 5 + .../frameworks/sveltekit/src/lib/index.ts | 60 ++++++- pnpm-lock.yaml | 100 ++---------- 8 files changed, 98 insertions(+), 243 deletions(-) delete mode 100644 apps/playground-sveltekit/src/lib/next-auth.ts diff --git a/apps/playground-sveltekit/src/hooks.server.ts b/apps/playground-sveltekit/src/hooks.server.ts index e2a7f75396..3c1bcb924f 100644 --- a/apps/playground-sveltekit/src/hooks.server.ts +++ b/apps/playground-sveltekit/src/hooks.server.ts @@ -1,12 +1,12 @@ import type { Handle } from "@sveltejs/kit" -// import { getServerSession, options as nextAuthOptions } from "$lib/next-auth" +import { authOptions } from "./routes/api/auth/[...nextauth]/+server" +import { getServerSession } from 'next-auth-sveltekit' export const handle: Handle = async function handle({ event, resolve, }): Promise { - // const session = await getServerSession(event.request, nextAuthOptions) - const session = {} + const session = await getServerSession(event.request, authOptions) if (session) { event.locals.session = session } diff --git a/apps/playground-sveltekit/src/lib/next-auth.ts b/apps/playground-sveltekit/src/lib/next-auth.ts deleted file mode 100644 index d14d96dde5..0000000000 --- a/apps/playground-sveltekit/src/lib/next-auth.ts +++ /dev/null @@ -1,147 +0,0 @@ -// import type { ServerLoadEvent } from "@sveltejs/kit" -// import type { RequestInternal } from "next-auth" -// import type { NextAuthAction, NextAuthOptions } from "next-auth/core/types" -// import type { OutgoingResponse as NextAuthResponse } from "next-auth/core" -// import { NextAuthHandler } from "next-auth/core" -// import GithubProvider from "next-auth/providers/github" -// import cookie from "cookie" -// import { -// GITHUB_CLIENT_ID, -// GITHUB_CLIENT_SECRET, -// NEXTAUTH_SECRET, -// } from "$env/static/private" -// import { PUBLIC_NEXTAUTH_URL } from "$env/static/public" - -// // @ts-expect-error import is exported on .default during SSR -// const github = GithubProvider?.default || GithubProvider - -// export const options: NextAuthOptions = { -// providers: [ -// github({ -// clientId: GITHUB_CLIENT_ID, -// clientSecret: GITHUB_CLIENT_SECRET, -// }), -// ], -// } - -// const toSvelteKitResponse = async < -// T extends string | any[] | Record -// >( -// request: Request, -// nextAuthResponse: NextAuthResponse -// ): Promise => { -// const { cookies, redirect } = nextAuthResponse - -// const headers = new Headers() -// for (const header of nextAuthResponse?.headers || []) { -// // pass headers along from next-auth -// headers.set(header.key, header.value) -// } - -// // set-cookie header -// if (cookies?.length) { -// headers.set( -// "set-cookie", -// cookies -// ?.map((item) => cookie.serialize(item.name, item.value, item.options)) -// .join(",") as string -// ) -// } - -// let body = undefined -// let status = nextAuthResponse.status || 200 - -// if (redirect) { -// let formData: FormData | null = null -// try { -// formData = await request.formData() -// } catch { -// // no formData passed -// } -// const { json } = Object.fromEntries(formData ?? []) -// if (json !== "true") { -// status = 302 -// headers.set("Location", redirect) -// } else { -// body = { url: redirect } -// } -// } else { -// body = nextAuthResponse.body -// } - -// // @ts-expect-error - body is a known HTML document or JSON object -// return new Response(body, { -// status, -// headers, -// }) -// } - -// const SKNextAuthHandler = async ( -// { request, url, params }: ServerLoadEvent, -// options: NextAuthOptions -// ): Promise => { -// const [action, provider] = params.nextauth!.split("/") -// let body: FormData | undefined -// try { -// body = await request.formData() -// } catch { -// // no formData passed -// } -// options.secret = NEXTAUTH_SECRET -// const req: RequestInternal = { -// host: PUBLIC_NEXTAUTH_URL, -// body: Object.fromEntries(body ?? []), -// query: Object.fromEntries(url.searchParams), -// headers: request.headers, -// method: request.method, -// cookies: cookie.parse(request.headers.get("cookie") || ""), -// action: action as NextAuthAction, -// providerId: provider, -// error: provider, -// } - -// const response = await NextAuthHandler({ -// req, -// options, -// }) - -// return toSvelteKitResponse(request, response) -// } - -// export const getServerSession = async ( -// request: Request, -// options: NextAuthOptions -// ): Promise => { -// options.secret = NEXTAUTH_SECRET - -// const session = await NextAuthHandler({ -// req: { -// host: PUBLIC_NEXTAUTH_URL, -// action: "session", -// method: "GET", -// cookies: cookie.parse(request.headers.get("cookie") || ""), -// headers: request.headers, -// }, -// options, -// }) - -// const { body } = session - -// if (body && Object.keys(body).length) { -// return body as App.Session -// } -// return null -// } - -// export const NextAuth = ( -// options: NextAuthOptions -// ): { -// GET: (event: ServerLoadEvent) => Promise -// POST: (event: ServerLoadEvent) => Promise -// } => ({ -// GET: (event) => SKNextAuthHandler(event, options), -// POST: (event) => SKNextAuthHandler(event, options), -// }) - - - diff --git a/apps/playground-sveltekit/src/routes/api/auth/[...nextauth]/+server.ts b/apps/playground-sveltekit/src/routes/api/auth/[...nextauth]/+server.ts index 5b9f4b5aa6..9e85763e7e 100644 --- a/apps/playground-sveltekit/src/routes/api/auth/[...nextauth]/+server.ts +++ b/apps/playground-sveltekit/src/routes/api/auth/[...nextauth]/+server.ts @@ -1,8 +1,14 @@ import SvelteKitAuth from "next-auth-sveltekit" -import GitHub from 'next-auth-core/dist/providers/github'; +import GitHub from 'next-auth-core/providers/github'; +import { + GITHUB_CLIENT_ID, + GITHUB_CLIENT_SECRET, +} from "$env/static/private" -export const { GET, POST } = SvelteKitAuth({ +export const authOptions = { providers: [ - GitHub({ clientId: process.env.GITHUB_ID!, clientSecret: process.env.GITHUB_SECRET! }), + GitHub({ clientId: GITHUB_CLIENT_ID, clientSecret: GITHUB_CLIENT_SECRET }), ] -}) \ No newline at end of file +} + +export const { GET, POST } = SvelteKitAuth(authOptions) \ No newline at end of file diff --git a/package.json b/package.json index 366d76ff15..aa9dd68b04 100644 --- a/package.json +++ b/package.json @@ -65,5 +65,10 @@ "type": "opencollective", "url": "https://opencollective.com/nextauth" } - ] + ], + "pnpm": { + "overrides": { + "undici": "5.11.0" + } + } } diff --git a/packages/frameworks/sveltekit/package.json b/packages/frameworks/sveltekit/package.json index 4b6803e193..b975f863f4 100644 --- a/packages/frameworks/sveltekit/package.json +++ b/packages/frameworks/sveltekit/package.json @@ -14,7 +14,6 @@ "@sveltejs/adapter-auto": "next", "@sveltejs/kit": "next", "@sveltejs/package": "next", - "@types/cookie": "^0.5.1", "@typescript-eslint/eslint-plugin": "^5.45.0", "@typescript-eslint/parser": "^5.45.0", "eslint": "^8.28.0", @@ -31,7 +30,6 @@ }, "type": "module", "dependencies": { - "cookie": "^0.5.0", "next-auth-core": "workspace:^0.0.1" } } diff --git a/packages/frameworks/sveltekit/src/app.d.ts b/packages/frameworks/sveltekit/src/app.d.ts index b12a60df82..a9ecaa927f 100644 --- a/packages/frameworks/sveltekit/src/app.d.ts +++ b/packages/frameworks/sveltekit/src/app.d.ts @@ -13,4 +13,9 @@ declare namespace App { declare module '$env/static/private' { export const AUTH_SECRET: string +} +declare module '$env/static/public' { + export const PUBLIC_NEXTAUTH_URL: string + export const VERCEL: string + export const AUTH_TRUST_HOST: string } \ No newline at end of file diff --git a/packages/frameworks/sveltekit/src/lib/index.ts b/packages/frameworks/sveltekit/src/lib/index.ts index a0393211f9..81bab621de 100644 --- a/packages/frameworks/sveltekit/src/lib/index.ts +++ b/packages/frameworks/sveltekit/src/lib/index.ts @@ -2,17 +2,70 @@ import type { ServerLoadEvent } from "@sveltejs/kit" import { AUTH_SECRET, } from "$env/static/private" +import { + AUTH_TRUST_HOST, + VERCEL, + PUBLIC_NEXTAUTH_URL, +} from "$env/static/public" import { AuthHandler, type AuthOptions } from "next-auth-core" +function getURL( + url: string | undefined | null, + trusted: boolean | undefined = !!( + AUTH_TRUST_HOST ?? VERCEL + ), + forwardedValue: string | string[] | undefined | null +): URL | Error { + try { + let host = PUBLIC_NEXTAUTH_URL + + if (trusted && forwardedValue) { + host = Array.isArray(forwardedValue) ? forwardedValue[0] : forwardedValue + } + + if (!host) throw new TypeError("Invalid host") + + return new URL(url ?? "", new URL(host)) + } catch (error) { + return error as Error + } +} +export const getServerSession = async ( + req: Request, + options: AuthOptions +): Promise => { + + options.secret ??= AUTH_SECRET + const urlOrError = getURL( + "/api/auth/session", + options.trustHost, + req.headers.get("x-forwarded-host") ?? req.headers.get('host') + ) + + if (urlOrError instanceof Error) throw urlOrError + const response = await AuthHandler( + new Request(urlOrError, { headers: req.headers }), + 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) +} const SKAuthHandler = async ( { request }: ServerLoadEvent, options: AuthOptions ): Promise => { - options.secret = AUTH_SECRET + options.secret ??= AUTH_SECRET - console.log("SKAuthHandler", request, options) - // TODO Glue handling of cookies and headers etc. return await AuthHandler(request, options) } @@ -31,3 +84,4 @@ function SvelteKitAuth( } export default SvelteKitAuth +// export * from './getServerSession.js' \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c320dfc6d3..1c39c0b7ec 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5 +1,8 @@ lockfileVersion: 5.4 +overrides: + undici: 5.11.0 + importers: .: @@ -495,7 +498,6 @@ importers: jose: 4.11.1 oauth4webapi: 2.0.4 postcss: 8.4.19 - postcss-cli: 10.1.0 postcss-nested: 6.0.0 preact: 10.11.3 preact-render-to-string: 5.2.3 @@ -516,7 +518,6 @@ importers: autoprefixer: 10.4.13_postcss@8.4.19 cssnano: 5.1.14_postcss@8.4.19 postcss: 8.4.19 - postcss-cli: 10.1.0_postcss@8.4.19 postcss-nested: 6.0.0_postcss@8.4.19 packages/frameworks/sveltekit: @@ -524,10 +525,8 @@ importers: '@sveltejs/adapter-auto': next '@sveltejs/kit': next '@sveltejs/package': next - '@types/cookie': ^0.5.1 '@typescript-eslint/eslint-plugin': ^5.45.0 '@typescript-eslint/parser': ^5.45.0 - cookie: ^0.5.0 eslint: ^8.28.0 eslint-config-prettier: ^8.5.0 eslint-plugin-svelte3: ^4.0.0 @@ -541,13 +540,11 @@ importers: typescript: ^4.9.3 vite: ^3.2.4 dependencies: - cookie: 0.5.0 next-auth-core: link:../../core devDependencies: '@sveltejs/adapter-auto': 1.0.0-next.90 '@sveltejs/kit': 1.0.0-next.572_svelte@3.54.0+vite@3.2.5 '@sveltejs/package': 1.0.0-next.1_gf4dcx76vtk2o62ixxeqx7chra - '@types/cookie': 0.5.1 '@typescript-eslint/eslint-plugin': 5.45.1_tdm6ms4ntwhlpozn7kjqrhum74 '@typescript-eslint/parser': 5.45.1_s5ps7njkmjlaqajutnox5ntcla eslint: 8.29.0 @@ -567,11 +564,14 @@ importers: '@sveltejs/adapter-auto': next '@sveltejs/kit': next '@sveltejs/package': next + '@types/cookie': ^0.5.1 '@typescript-eslint/eslint-plugin': ^5.45.0 '@typescript-eslint/parser': ^5.45.0 + cookie: ^0.5.0 eslint: ^8.28.0 eslint-config-prettier: ^8.5.0 eslint-plugin-svelte3: ^4.0.0 + next-auth-core: workspace:^0.0.1 prettier: ^2.8.0 prettier-plugin-svelte: ^2.8.1 svelte: ^3.53.1 @@ -580,10 +580,14 @@ importers: tslib: ^2.4.1 typescript: ^4.9.3 vite: ^3.2.4 + dependencies: + cookie: 0.5.0 + next-auth-core: link:../../../core devDependencies: '@sveltejs/adapter-auto': 1.0.0-next.90 '@sveltejs/kit': 1.0.0-next.572_svelte@3.54.0+vite@3.2.5 '@sveltejs/package': 1.0.0-next.1_gf4dcx76vtk2o62ixxeqx7chra + '@types/cookie': 0.5.1 '@typescript-eslint/eslint-plugin': 5.45.1_tdm6ms4ntwhlpozn7kjqrhum74 '@typescript-eslint/parser': 5.45.1_s5ps7njkmjlaqajutnox5ntcla eslint: 8.29.0 @@ -7467,7 +7471,7 @@ packages: engines: {node: '>=6.0.0'} dependencies: '@jridgewell/set-array': 1.1.1 - '@jridgewell/sourcemap-codec': 1.4.13 + '@jridgewell/sourcemap-codec': 1.4.14 dev: true /@jridgewell/gen-mapping/0.3.1: @@ -7475,7 +7479,7 @@ packages: engines: {node: '>=6.0.0'} dependencies: '@jridgewell/set-array': 1.1.1 - '@jridgewell/sourcemap-codec': 1.4.13 + '@jridgewell/sourcemap-codec': 1.4.14 '@jridgewell/trace-mapping': 0.3.17 /@jridgewell/gen-mapping/0.3.2: @@ -7509,6 +7513,7 @@ packages: /@jridgewell/sourcemap-codec/1.4.13: resolution: {integrity: sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==} + dev: true /@jridgewell/sourcemap-codec/1.4.14: resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} @@ -8208,7 +8213,7 @@ packages: sirv: 2.0.2 svelte: 3.54.0 tiny-glob: 0.2.9 - undici: 5.13.0 + undici: 5.11.0 vite: 3.2.5 transitivePeerDependencies: - supports-color @@ -8235,7 +8240,7 @@ packages: sirv: 2.0.2 svelte: 3.54.0 tiny-glob: 0.2.9 - undici: 5.13.0 + undici: 5.11.0 vite: 3.2.5 transitivePeerDependencies: - supports-color @@ -15236,15 +15241,6 @@ packages: universalify: 2.0.0 dev: true - /fs-extra/11.1.0: - resolution: {integrity: sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==} - engines: {node: '>=14.14'} - dependencies: - graceful-fs: 4.2.10 - jsonfile: 6.1.0 - universalify: 2.0.0 - dev: true - /fs-extra/8.1.0: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} @@ -20963,30 +20959,6 @@ packages: postcss-value-parser: 4.2.0 dev: true - /postcss-cli/10.1.0_postcss@8.4.19: - resolution: {integrity: sha512-Zu7PLORkE9YwNdvOeOVKPmWghprOtjFQU3srMUGbdz3pHJiFh7yZ4geiZFMkjMfB0mtTFR3h8RemR62rPkbOPA==} - engines: {node: '>=14'} - hasBin: true - peerDependencies: - postcss: ^8.0.0 - dependencies: - chokidar: 3.5.3 - dependency-graph: 0.11.0 - fs-extra: 11.1.0 - get-stdin: 9.0.0 - globby: 13.1.2 - picocolors: 1.0.0 - postcss: 8.4.19 - postcss-load-config: 4.0.1_postcss@8.4.19 - postcss-reporter: 7.0.5_postcss@8.4.19 - pretty-hrtime: 1.0.3 - read-cache: 1.0.0 - slash: 5.0.0 - yargs: 17.5.1 - transitivePeerDependencies: - - ts-node - dev: true - /postcss-cli/9.1.0_postcss@8.4.14: resolution: {integrity: sha512-zvDN2ADbWfza42sAnj+O2uUWyL0eRL1V+6giM2vi4SqTR3gTYy8XzcpfwccayF2szcUif0HMmXiEaDv9iEhcpw==} engines: {node: '>=12'} @@ -21158,23 +21130,6 @@ packages: yaml: 1.10.2 dev: true - /postcss-load-config/4.0.1_postcss@8.4.19: - resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} - engines: {node: '>= 14'} - peerDependencies: - postcss: '>=8.0.9' - ts-node: '>=9.0.0' - peerDependenciesMeta: - postcss: - optional: true - ts-node: - optional: true - dependencies: - lilconfig: 2.0.5 - postcss: 8.4.19 - yaml: 2.1.3 - dev: true - /postcss-loader/7.0.0_mepnsno3xmng6eyses4tepu7bu: resolution: {integrity: sha512-IDyttebFzTSY6DI24KuHUcBjbAev1i+RyICoPEWcAstZsj03r533uMXtDn506l6/wlsRYiS5XBdx7TpccCsyUg==} engines: {node: '>= 14.15.0'} @@ -21664,17 +21619,6 @@ packages: thenby: 1.3.4 dev: true - /postcss-reporter/7.0.5_postcss@8.4.19: - resolution: {integrity: sha512-glWg7VZBilooZGOFPhN9msJ3FQs19Hie7l5a/eE6WglzYqVeH3ong3ShFcp9kDWJT1g2Y/wd59cocf9XxBtkWA==} - engines: {node: '>=10'} - peerDependencies: - postcss: ^8.1.0 - dependencies: - picocolors: 1.0.0 - postcss: 8.4.19 - thenby: 1.3.4 - dev: true - /postcss-selector-parser/6.0.10: resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} engines: {node: '>=4'} @@ -23631,11 +23575,6 @@ packages: engines: {node: '>=12'} dev: true - /slash/5.0.0: - resolution: {integrity: sha512-n6KkmvKS0623igEVj3FF0OZs1gYYJ0o0Hj939yc1fyxl2xt+xYpLnzJB6xBSqOfV9ZFLEWodBBN/heZJahuIJQ==} - engines: {node: '>=14.16'} - dev: true - /slice-ansi/4.0.0: resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} engines: {node: '>=10'} @@ -25470,8 +25409,8 @@ packages: resolution: {integrity: sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ==} dev: true - /undici/5.13.0: - resolution: {integrity: sha512-UDZKtwb2k7KRsK4SdXWG7ErXiL7yTGgLWvk2AXO1JMjgjh404nFo6tWSCM2xMpJwMPx3J8i/vfqEh1zOqvj82Q==} + /undici/5.11.0: + resolution: {integrity: sha512-oWjWJHzFet0Ow4YZBkyiJwiK5vWqEYoH7BINzJAJOLedZ++JpAlCbUktW2GQ2DS2FpKmxD/JMtWUUWl1BtghGw==} engines: {node: '>=12.18'} dependencies: busboy: 1.6.0 @@ -26511,11 +26450,6 @@ packages: engines: {node: '>= 6'} dev: true - /yaml/2.1.3: - resolution: {integrity: sha512-AacA8nRULjKMX2DvWvOAdBZMOfQlypSFkjcOcu9FalllIDJ1kvlREzcdIZmidQUqqeMv7jorHjq2HlLv/+c2lg==} - engines: {node: '>= 14'} - dev: true - /yargs-parser/20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'}