UNPKG

@ory/nextjs

Version:

This package contains the Next.js SDK for Ory. It provides a set of React components, server-side components, and hooks to interact with the Ory ecosystem. Supports both app and page routers.

1 lines 34.3 kB
{"version":3,"sources":["../../src/types.ts","../../src/utils/sdk.ts","../../src/app/client.ts","../../src/app/utils.ts","../../src/utils/rewrite.ts","../../src/utils/utils.ts","../../src/app/flow.ts","../../src/app/login.ts","../../src/app/registration.ts","../../src/app/recovery.ts","../../src/app/verification.ts","../../src/app/settings.ts","../../src/app/logout.ts","../../src/app/session.ts"],"names":["redirect","RedirectType","FlowType","headers"],"mappings":"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","file":"index.mjs","sourcesContent":["// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\n\nexport type QueryParams = { [key: string]: string | string[] | undefined }\n\nexport const initOverrides: RequestInit = {\n cache: \"no-cache\",\n}\n\nexport type FlowParams = {\n id: string\n cookie: string | undefined\n return_to: string\n}\n","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Gets environment variable, prioritizing the NEXT_PUBLIC_ prefixed version\n */\nfunction getEnv(name: string): string | undefined {\n return process.env[`NEXT_PUBLIC_${name}`] || process.env[name]\n}\n\nexport function orySdkUrl() {\n const baseUrl = getEnv(\"ORY_SDK_URL\")\n\n if (!baseUrl) {\n throw new Error(\n \"You need to set environment variable `NEXT_PUBLIC_ORY_SDK_URL` to your Ory Network SDK URL.\",\n )\n }\n\n return baseUrl.replace(/\\/$/, \"\")\n}\n\nexport function isProduction() {\n const env = getEnv(\"VERCEL_ENV\") || getEnv(\"NODE_ENV\") || \"\"\n return [\"production\", \"prod\"].indexOf(env) > -1\n}\n\nexport function guessPotentiallyProxiedOrySdkUrl(options?: {\n knownProxiedUrl?: string\n}) {\n if (getEnv(\"VERCEL_ENV\")) {\n // We are in vercel\n\n // The domain name of the generated deployment URL. Example: *.vercel.app\n // This is only available for preview deployments on Vercel.\n if (!isProduction() && getEnv(\"VERCEL_URL\")) {\n return `https://${getEnv(\"VERCEL_URL\")}`.replace(/\\/$/, \"\")\n }\n\n const productionUrl = getEnv(\"VERCEL_PROJECT_PRODUCTION_URL\") || \"\"\n if (isProduction() && productionUrl.indexOf(\"vercel.app\") > -1) {\n // This is a production deployment on Vercel without a custom domain, so we use the vercel app domain.\n return `https://${productionUrl}`.replace(/\\/$/, \"\")\n }\n\n // This is sometimes set by the render server.\n if (process.env[\"__NEXT_PRIVATE_ORIGIN\"]) {\n return process.env[\"__NEXT_PRIVATE_ORIGIN\"].replace(/\\/$/, \"\")\n }\n }\n\n if (isProduction()) {\n // In production, we use the production custom domain\n return orySdkUrl()\n }\n\n // Try to use window location\n if (typeof window !== \"undefined\") {\n return window.location.origin\n }\n\n if (options?.knownProxiedUrl) {\n return options.knownProxiedUrl\n }\n\n // We tried everything. Let's use the SDK URL.\n const final = orySdkUrl()\n console.warn(\n `Unable to determine a suitable SDK URL for setting up the Next.js integration of Ory Elements. Will proceed using default Ory SDK URL \"${final}\". This is likely not what you want for local development and your authentication and login may not work.`,\n )\n\n return final\n}\n","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Configuration, FrontendApi } from \"@ory/client-fetch\"\n\nimport { orySdkUrl } from \"../utils/sdk\"\n\nexport const serverSideFrontendClient = () =>\n new FrontendApi(\n new Configuration({\n headers: {\n Accept: \"application/json\",\n },\n basePath: orySdkUrl(),\n }),\n )\n","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\nimport { FlowType, OnRedirectHandler } from \"@ory/client-fetch\"\nimport { headers } from \"next/headers\"\nimport { redirect, RedirectType } from \"next/navigation\"\nimport { QueryParams } from \"../types\"\nimport { ParsedUrlQuery } from \"querystring\"\n\nexport async function getCookieHeader() {\n const h = await headers()\n return h.get(\"cookie\") ?? undefined\n}\n\nexport const onRedirect: OnRedirectHandler = (url) => {\n redirect(url)\n}\n\n/**\n * @internal\n */\nexport async function toGetFlowParameter(\n params: Promise<QueryParams> | QueryParams,\n) {\n return {\n id: (await params)[\"flow\"]?.toString() ?? \"\",\n cookie: await getCookieHeader(),\n }\n}\n\nexport async function getPublicUrl() {\n const h = await headers()\n const host = h.get(\"host\")\n const protocol = h.get(\"x-forwarded-proto\") || \"http\"\n return `${protocol}://${host}`\n}\n\n/**\n * A utility type that represents the query parameters of a request.\n *\n * This is needed because Next.js does not expose the query parameters as a tye.\n *\n * ```ts\n * import { OryPageParams } from \"@ory/nextjs/app\"\n *\n * export default async function LoginPage(props: OryPageParams) {\n * // props.searchParams is a Promise that resolves to an object with the query parameters\n * }\n * ```\n *\n * @public\n */\nexport interface OryPageParams {\n searchParams: Promise<{ [key: string]: string | string[] | undefined }>\n}\n\nexport function startNewFlow(\n params: QueryParams,\n flowType: FlowType,\n baseUrl: string,\n) {\n // Take advantage of the fact, that Ory handles the flow creation for us and redirects the user to the default\n // return to automatically if they're logged in already.\n return redirect(\n new URL(\n \"/self-service/\" +\n flowType.toString() +\n \"/browser?\" +\n urlQueryToSearchParams(params).toString(),\n baseUrl,\n ).toString(),\n RedirectType.replace,\n )\n}\n\n// Copied over from https://github.com/vercel/next.js/blob/dbd5e1b274d30f9107141475eba116a8118bc346/packages/next/src/shared/lib/router/utils/querystring.ts\n// to avoid relying on internal APIs\nfunction stringifyUrlQueryParam(param: unknown): string {\n if (typeof param === \"string\") {\n return param\n }\n\n if (\n (typeof param === \"number\" && !isNaN(param)) ||\n typeof param === \"boolean\"\n ) {\n return String(param)\n } else {\n return \"\"\n }\n}\n\nexport function urlQueryToSearchParams(query: ParsedUrlQuery): URLSearchParams {\n const searchParams = new URLSearchParams()\n for (const [key, value] of Object.entries(query)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n searchParams.append(key, stringifyUrlQueryParam(item))\n }\n } else {\n searchParams.set(key, stringifyUrlQueryParam(value))\n }\n }\n return searchParams\n}\n","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\n\nimport { OryMiddlewareOptions } from \"src/middleware/middleware\"\nimport { orySdkUrl } from \"./sdk\"\nimport { joinUrlPaths } from \"./utils\"\n\nexport function rewriteUrls(\n source: string,\n matchBaseUrl: string,\n selfUrl: string,\n config: OryMiddlewareOptions,\n) {\n for (const [_, [matchPath, replaceWith]] of [\n // TODO load these dynamically from the project config\n\n // Old AX routes\n [\"/ui/recovery\", config.project?.recovery_ui_url],\n [\"/ui/registration\", config.project?.registration_ui_url],\n [\"/ui/login\", config.project?.login_ui_url],\n [\"/ui/verification\", config.project?.verification_ui_url],\n [\"/ui/settings\", config.project?.settings_ui_url],\n [\"/ui/welcome\", config.project?.default_redirect_url],\n\n // New AX routes\n [\"/recovery\", config.project?.recovery_ui_url],\n [\"/registration\", config.project?.registration_ui_url],\n [\"/login\", config.project?.login_ui_url],\n [\"/verification\", config.project?.verification_ui_url],\n [\"/settings\", config.project?.settings_ui_url],\n ].entries()) {\n const match = joinUrlPaths(matchBaseUrl, matchPath || \"\")\n if (replaceWith && source.startsWith(match)) {\n source = source.replaceAll(\n match,\n new URL(replaceWith, selfUrl).toString(),\n )\n }\n }\n return source.replaceAll(\n matchBaseUrl.replace(/\\/$/, \"\"),\n new URL(selfUrl).toString().replace(/\\/$/, \"\"),\n )\n}\n\n/**\n * Rewrites Ory SDK URLs in JSON responses (objects, arrays, strings) with the provided proxy URL.\n *\n * If `proxyUrl` is provided, the SDK URL is replaced with the proxy URL.\n *\n * @param obj - The object to rewrite\n * @param proxyUrl - The proxy URL to replace the SDK URL with\n */\nexport function rewriteJsonResponse<T extends object>(\n obj: T,\n proxyUrl?: string,\n): T {\n return Object.fromEntries(\n Object.entries(obj)\n .filter(([_, value]) => value !== undefined)\n .map(([key, value]) => {\n if (Array.isArray(value)) {\n // Recursively process each item in the array\n return [\n key,\n value\n .map((item) => {\n if (typeof item === \"object\" && item !== null) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return rewriteJsonResponse(item, proxyUrl)\n } else if (typeof item === \"string\" && proxyUrl) {\n return item.replaceAll(orySdkUrl(), proxyUrl)\n }\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return item\n })\n .filter((item) => item !== undefined),\n ]\n } else if (typeof value === \"object\" && value !== null) {\n // Recursively remove undefined in nested objects\n return [key, rewriteJsonResponse(value, proxyUrl)]\n } else if (typeof value === \"string\" && proxyUrl) {\n // Replace SDK URL with the provided proxy URL\n return [key, value.replaceAll(orySdkUrl(), proxyUrl)]\n }\n return [key, value]\n }),\n ) as T\n}\n","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\nimport { serialize, SerializeOptions } from \"cookie\"\nimport { parse, splitCookiesString } from \"set-cookie-parser\"\n\nimport { ApiResponse } from \"@ory/client-fetch\"\nimport { OryMiddlewareOptions } from \"src/middleware/middleware\"\nimport { FlowParams, QueryParams } from \"../types\"\nimport { guessCookieDomain } from \"./cookie\"\nimport { defaultForwardedHeaders } from \"./headers\"\nimport { rewriteJsonResponse } from \"./rewrite\"\n\nexport function onValidationError<T>(value: T): T {\n return value\n}\n\nexport async function toFlowParams(\n params: QueryParams,\n getCookieHeader: () => Promise<string | undefined>,\n): Promise<FlowParams> {\n return {\n id: params[\"flow\"]?.toString() ?? \"\",\n cookie: await getCookieHeader(),\n return_to: params[\"return_to\"]?.toString() ?? \"\",\n }\n}\nexport function processSetCookieHeaders(\n protocol: string,\n fetchResponse: Response,\n options: OryMiddlewareOptions,\n requestHeaders: Headers,\n) {\n const isTls =\n protocol === \"https:\" || requestHeaders.get(\"x-forwarded-proto\") === \"https\"\n\n const forwarded = requestHeaders.get(\"x-forwarded-host\")\n const host = forwarded ? forwarded : requestHeaders.get(\"host\")\n const domain =\n host && !options.forceCookieDomain\n ? guessCookieDomain(host ?? \"\")\n : options.forceCookieDomain\n\n return parse(\n splitCookiesString(fetchResponse.headers.get(\"set-cookie\") || \"\"),\n )\n .map((cookie) => ({\n ...cookie,\n domain,\n secure: isTls,\n encode: (v: string) => v,\n }))\n .map(({ value, name, ...options }) =>\n serialize(name, value, options as SerializeOptions),\n )\n}\n\nexport function filterRequestHeaders(\n headers: Headers,\n forwardAdditionalHeaders?: string[],\n): Headers {\n const filteredHeaders = new Headers()\n\n headers.forEach((value, key) => {\n const isValid =\n defaultForwardedHeaders.includes(key) ||\n (forwardAdditionalHeaders ?? []).includes(key)\n if (isValid) filteredHeaders.set(key, value)\n })\n\n return filteredHeaders\n}\n\nexport function joinUrlPaths(baseUrl: string, relativeUrl: string): string {\n const base = new URL(baseUrl)\n const relative = new URL(relativeUrl, baseUrl)\n\n relative.pathname =\n base.pathname.replace(/\\/$/, \"\") +\n \"/\" +\n relative.pathname.replace(/^\\//, \"\")\n\n return new URL(relative.toString(), baseUrl).href\n}\n\nexport function toValue<T extends object>(res: ApiResponse<T>): Promise<T> {\n // Remove all undefined values from the response (array and object) using lodash:\n // Remove all (nested) undefined values from the response using lodash\n return res.value().then((v) => rewriteJsonResponse(v))\n}\n","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\n\nimport { redirect, RedirectType } from \"next/navigation\"\nimport { FlowType, handleFlowError, ApiResponse } from \"@ory/client-fetch\"\n\nimport { startNewFlow, onRedirect } from \"./utils\"\nimport { QueryParams } from \"../types\"\nimport { onValidationError } from \"../utils/utils\"\nimport { rewriteJsonResponse } from \"../utils/rewrite\"\n\n/**\n * A function that creates a flow fetcher. The flow fetcher can be used\n * to fetch a login, registration, recovery, settings, or verification flow\n * from the SDK.\n *\n * Unless you are building something very custom, you will not need this method. Use it with care and expect\n * potential breaking changes.\n *\n * @param params - The query parameters of the request.\n * @param fetchFlowRaw - A function that fetches the flow from the SDK.\n * @param flowType - The type of the flow.\n * @param baseUrl - The base URL of the application.\n * @param route - The route of the application.\n * @param options - Additional options.\n * @public\n */\nexport async function getFlowFactory<T extends object>(\n params: QueryParams,\n fetchFlowRaw: () => Promise<ApiResponse<T>>,\n flowType: FlowType,\n baseUrl: string,\n route: string,\n options: {\n disableRewrite?: boolean\n } = { disableRewrite: false },\n): Promise<T | null | void> {\n // Guess our own public url using Next.js helpers. We need the hostname, port, and protocol.\n const onRestartFlow = (useFlowId?: string) => {\n if (!useFlowId) {\n return startNewFlow(params, flowType, baseUrl)\n }\n\n const redirectTo = new URL(route, baseUrl)\n redirectTo.search = new URLSearchParams({\n ...params,\n flow: useFlowId,\n }).toString()\n return redirect(redirectTo.toString(), RedirectType.replace)\n }\n\n if (!params[\"flow\"]) {\n return onRestartFlow()\n }\n\n try {\n const rawResponse = await fetchFlowRaw()\n return await rawResponse\n .value()\n .then(\n (v: T): T =>\n options.disableRewrite ? v : rewriteJsonResponse(v, baseUrl),\n )\n } catch (error) {\n const errorHandler = handleFlowError({\n onValidationError,\n onRestartFlow,\n onRedirect: onRedirect,\n })\n\n return await errorHandler(error)\n }\n}\n","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\nimport { FlowType, LoginFlow } from \"@ory/client-fetch\"\n\nimport { initOverrides, QueryParams } from \"../types\"\nimport { guessPotentiallyProxiedOrySdkUrl } from \"../utils/sdk\"\nimport { serverSideFrontendClient } from \"./client\"\nimport { getFlowFactory } from \"./flow\"\nimport { getPublicUrl, toGetFlowParameter } from \"./utils\"\n\n/**\n * Use this method in an app router page to fetch an existing login flow or to create a new one. This method works with server-side rendering.\n *\n * @example\n * ```tsx\n * import { Login } from \"@ory/elements-react/theme\"\n * import { getLoginFlow, OryPageParams } from \"@ory/nextjs/app\"\n * import CardHeader from \"@/app/auth/login/card-header\"\n *\n * import config from \"@/ory.config\"\n *\n * export default async function LoginPage(props: OryPageParams) {\n * const flow = await getLoginFlow(config, props.searchParams)\n *\n * if (!flow) {\n * return null\n * }\n *\n * return (\n * <Login\n * flow={flow}\n * config={config}\n * components={{\n * Card: {\n * Header: CardHeader,\n * },\n * }}\n * />\n * )\n * }\n * ```\n *\n * @param config - The Ory configuration object.\n * @param params - The query parameters of the request.\n * @public\n */\nexport async function getLoginFlow(\n config: { project: { login_ui_url: string } },\n params: QueryParams | Promise<QueryParams>,\n): Promise<LoginFlow | null | void> {\n return getFlowFactory(\n await params,\n async () =>\n serverSideFrontendClient().getLoginFlowRaw(\n await toGetFlowParameter(params),\n initOverrides,\n ),\n FlowType.Login,\n guessPotentiallyProxiedOrySdkUrl({\n knownProxiedUrl: await getPublicUrl(),\n }),\n config.project.login_ui_url,\n )\n}\n","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\nimport { FlowType, RegistrationFlow } from \"@ory/client-fetch\"\n\nimport { initOverrides, QueryParams } from \"../types\"\nimport { guessPotentiallyProxiedOrySdkUrl } from \"../utils/sdk\"\nimport { serverSideFrontendClient } from \"./client\"\nimport { getFlowFactory } from \"./flow\"\nimport { getPublicUrl, toGetFlowParameter } from \"./utils\"\n\n/**\n * Use this method in an app router page to fetch an existing registration flow or to create a new one. This method works with server-side rendering.\n *\n * @example\n * ```tsx\n * import { Registration } from \"@ory/elements-react/theme\"\n * import { getRegistrationFlow, OryPageParams } from \"@ory/nextjs/app\"\n *\n * import config from \"@/ory.config\"\n * import CardHeader from \"@/app/auth/registration/card-header\"\n *\n * export default async function RegistrationPage(props: OryPageParams) {\n * const flow = await getRegistrationFlow(config, props.searchParams)\n *\n * if (!flow) {\n * return null\n * }\n *\n * return (\n * <Registration\n * flow={flow}\n * config={config}\n * components={{\n * Card: {\n * Header: CardHeader,\n * },\n * }}\n * />\n * )\n * }\n * ```\n *\n * @param config - The Ory configuration object.\n * @param params - The query parameters of the request.\n * @public\n */\nexport async function getRegistrationFlow(\n config: { project: { registration_ui_url: string } },\n params: QueryParams | Promise<QueryParams>,\n): Promise<RegistrationFlow | null | void> {\n return getFlowFactory(\n await params,\n async () =>\n serverSideFrontendClient().getRegistrationFlowRaw(\n await toGetFlowParameter(params),\n initOverrides,\n ),\n FlowType.Registration,\n guessPotentiallyProxiedOrySdkUrl({\n knownProxiedUrl: await getPublicUrl(),\n }),\n config.project.registration_ui_url,\n )\n}\n","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\nimport { FlowType, RecoveryFlow } from \"@ory/client-fetch\"\nimport { initOverrides, QueryParams } from \"../types\"\nimport { guessPotentiallyProxiedOrySdkUrl } from \"../utils/sdk\"\nimport { serverSideFrontendClient } from \"./client\"\nimport { getFlowFactory } from \"./flow\"\nimport { getPublicUrl, toGetFlowParameter } from \"./utils\"\n\n/**\n * Use this method in an app router page to fetch an existing recovery flow or to create a new one. This method works with server-side rendering.\n *\n * @example\n * ```tsx\n * import { Recovery } from \"@ory/elements-react/theme\"\n * import { getRecoveryFlow, OryPageParams } from \"@ory/nextjs/app\"\n * import config from \"@/ory.config\"\n * import CardHeader from \"@/app/auth/recovery/card-header\"\n *\n * export default async function RecoveryPage(props: OryPageParams) {\n * const flow = await getRecoveryFlow(config, props.searchParams)\n *\n * if (!flow) {\n * return null\n * }\n *\n * return (\n * <Recovery\n * flow={flow}\n * config={config}\n * components={{\n * Card: {\n * Header: CardHeader,\n * },\n * }}\n * />\n * )\n * }\n * ```\n *\n * @param config - The Ory configuration object.\n * @param params - The query parameters of the request.\n * @public\n */\nexport async function getRecoveryFlow(\n config: { project: { recovery_ui_url: string } },\n params: QueryParams | Promise<QueryParams>,\n): Promise<RecoveryFlow | null | void> {\n return getFlowFactory(\n await params,\n async () =>\n serverSideFrontendClient().getRecoveryFlowRaw(\n await toGetFlowParameter(params),\n initOverrides,\n ),\n FlowType.Recovery,\n guessPotentiallyProxiedOrySdkUrl({\n knownProxiedUrl: await getPublicUrl(),\n }),\n config.project.recovery_ui_url,\n )\n}\n","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\nimport { FlowType, VerificationFlow } from \"@ory/client-fetch\"\n\nimport { initOverrides, QueryParams } from \"../types\"\nimport { guessPotentiallyProxiedOrySdkUrl } from \"../utils/sdk\"\nimport { serverSideFrontendClient } from \"./client\"\nimport { getFlowFactory } from \"./flow\"\nimport { getPublicUrl, toGetFlowParameter } from \"./utils\"\n\n/**\n * Use this method in an app router page to fetch an existing verification flow or to create a new one. This method works with server-side rendering.\n *\n * @example\n * ```tsx\n * import { Verification } from \"@ory/elements-react/theme\"\n * import { getVerificationFlow, OryPageParams } from \"@ory/nextjs/app\"\n *\n * import config from \"@/ory.config\"\n * import CardHeader from \"@/app/auth/verification/card-header\"\n *\n * export default async function VerificationPage(props: OryPageParams) {\n * const flow = await getVerificationFlow(config, props.searchParams)\n *\n * if (!flow) {\n * return null\n * }\n *\n * return (\n * <Verification\n * flow={flow}\n * config={config}\n * components={{\n * Card: {\n * Header: CardHeader,\n * },\n * }}\n * />\n * )\n * }\n * ```\n *\n * @param config - The Ory configuration object.\n * @param params - The query parameters of the request.\n * @public\n */\nexport async function getVerificationFlow(\n config: { project: { verification_ui_url: string } },\n params: QueryParams | Promise<QueryParams>,\n): Promise<VerificationFlow | null | void> {\n return getFlowFactory(\n await params,\n async () =>\n serverSideFrontendClient().getVerificationFlowRaw(\n await toGetFlowParameter(params),\n initOverrides,\n ),\n FlowType.Verification,\n guessPotentiallyProxiedOrySdkUrl({\n knownProxiedUrl: await getPublicUrl(),\n }),\n config.project.verification_ui_url,\n )\n}\n","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\nimport { FlowType, SettingsFlow } from \"@ory/client-fetch\"\n\nimport { initOverrides, QueryParams } from \"../types\"\nimport { guessPotentiallyProxiedOrySdkUrl } from \"../utils/sdk\"\nimport { serverSideFrontendClient } from \"./client\"\nimport { getFlowFactory } from \"./flow\"\nimport { getPublicUrl, toGetFlowParameter } from \"./utils\"\n\n/**\n * Use this method in an app router page to fetch an existing login flow or to create a new one. This method works with server-side rendering.\n *\n * @example\n * ```tsx\n * import { Login } from \"@ory/elements-react/theme\"\n * import { getLoginFlow, OryPageParams } from \"@ory/nextjs/app\"\n *\n * import config from \"@/ory.config\"\n * import CardHeader from \"@/app/auth/login/card-header\"\n *\n * export default async function LoginPage(props: OryPageParams) {\n * const flow = await getLoginFlow(config, props.searchParams)\n *\n * if (!flow) {\n * return null\n * }\n *\n * return (\n * <Login\n * flow={flow}\n * config={config}\n * components={{\n * Card: {\n * Header: CardHeader,\n * },\n * }}\n * />\n * )\n * }\n * ```\n *\n * @param config - The Ory configuration object.\n * @param params - The query parameters of the request.\n * @public\n */\nexport async function getSettingsFlow(\n config: { project: { settings_ui_url: string } },\n params: QueryParams | Promise<QueryParams>,\n): Promise<SettingsFlow | null | void> {\n return getFlowFactory(\n await params,\n async () =>\n serverSideFrontendClient().getSettingsFlowRaw(\n await toGetFlowParameter(params),\n initOverrides,\n ),\n FlowType.Settings,\n guessPotentiallyProxiedOrySdkUrl({\n knownProxiedUrl: await getPublicUrl(),\n }),\n config.project.settings_ui_url,\n )\n}\n","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\nimport { LogoutFlow } from \"@ory/client-fetch\"\n\nimport { headers } from \"next/headers\"\nimport { rewriteJsonResponse } from \"../utils/rewrite\"\nimport { guessPotentiallyProxiedOrySdkUrl } from \"../utils/sdk\"\nimport { serverSideFrontendClient } from \"./client\"\nimport { getPublicUrl } from \"./utils\"\n\n/**\n * Use this method in an app router page to create a new logout flow. This method works with server-side rendering.\n *\n * @example\n * ```tsx\n * import { getLogoutFlow } from \"@ory/nextjs/app\"\n *\n * async function LogoutLink() {\n * const flow = await getLogoutFlow()\n *\n * return (\n * <a href={flow.logout_url}>\n * Logout\n * </a>\n * )\n * }\n *\n * ```\n *\n * @param params - The query parameters of the request.\n * @public\n */\nexport async function getLogoutFlow({\n returnTo,\n}: { returnTo?: string } = {}): Promise<LogoutFlow> {\n const h = await headers()\n\n const knownProxiedUrl = await getPublicUrl()\n const url = guessPotentiallyProxiedOrySdkUrl({\n knownProxiedUrl,\n })\n return serverSideFrontendClient()\n .createBrowserLogoutFlow({\n cookie: h.get(\"cookie\") ?? \"\",\n returnTo,\n })\n .then((v: LogoutFlow): LogoutFlow => rewriteJsonResponse(v, url))\n}\n","// Copyright © 2024 Ory Corp\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Session } from \"@ory/client-fetch\"\nimport { serverSideFrontendClient } from \"./client\"\nimport { getCookieHeader } from \"./utils\"\n\n/**\n * A helper to fetch the session on the server side. This method works with server-side rendering.\n *\n * @example\n * ```tsx\n * import { getServerSession } from \"@ory/nextjs/app\"\n *\n * async function MyComponent() {\n * const session = await getServerSession()\n *\n * if (!session) {\n * return <p>No session found</p>\n * }\n *\n * }\n * ```\n *\n * @returns The session object or null if no session is found.\n * @public\n */\nexport async function getServerSession(): Promise<Session | null> {\n const cookie = await getCookieHeader()\n return serverSideFrontendClient()\n .toSession({\n cookie,\n })\n .catch(() => null)\n}\n"]}