import { SettingsFlow, UpdateSettingsFlowBody } from "@ory/client" import { CardTitle, H3, P } from "@ory/themes" import { AxiosError } from "axios" import type { NextPage } from "next" import Head from "next/head" import Link from "next/link" import { useRouter } from "next/router" import { ReactNode, useEffect, useState } from "react" import { ActionCard, CenterLink, Flow, Messages, Methods } from "../pkg" import { handleFlowError } from "../pkg/errors" import ory from "../pkg/sdk" interface Props { flow?: SettingsFlow only?: Methods } function SettingsCard({ flow, only, children, }: Props & { children: ReactNode }) { if (!flow) { return null } const nodes = only ? flow.ui.nodes.filter(({ group }) => group === only) : flow.ui.nodes if (nodes.length === 0) { return null } return {children} } const Settings: NextPage = () => { const [flow, setFlow] = useState() // Get ?flow=... from the URL const router = useRouter() const { flow: flowId, return_to: returnTo } = router.query useEffect(() => { // If the router is not ready yet, or we already have a flow, do nothing. if (!router.isReady || flow) { return } // If ?flow=.. was in the URL, we fetch it if (flowId) { ory .getSettingsFlow({ id: String(flowId) }) .then(({ data }) => { setFlow(data) }) .catch(handleFlowError(router, "settings", setFlow)) return } // Otherwise we initialize it ory .createBrowserSettingsFlow({ returnTo: String(returnTo || ""), }) .then(({ data }) => { setFlow(data) }) .catch(handleFlowError(router, "settings", setFlow)) }, [flowId, router, router.isReady, returnTo, flow]) const onSubmit = (values: UpdateSettingsFlowBody) => router // On submission, add the flow ID to the URL but do not navigate. This prevents the user loosing // his data when she/he reloads the page. .push(`/settings?flow=${flow?.id}`, undefined, { shallow: true }) .then(() => ory .updateSettingsFlow({ flow: String(flow?.id), updateSettingsFlowBody: values, }) .then(({ data }) => { // The settings have been saved and the flow was updated. Let's show it to the user! setFlow(data) // continue_with is a list of actions that the user might need to take before the settings update is complete. // It could, for example, contain a link to the verification form. if (data.continue_with) { for (const item of data.continue_with) { switch (item.action) { case "show_verification_ui": router.push("/verification?flow=" + item.flow.id) return } } } if (data.return_to) { window.location.href = data.return_to return } }) .catch(handleFlowError(router, "settings", setFlow)) .catch(async (err: AxiosError) => { // If the previous handler did not catch the error it's most likely a form validation error if (err.response?.status === 400) { // Yup, it is! setFlow(err.response?.data) return } return Promise.reject(err) }), ) return ( <> Profile Management and Security Settings - Ory NextJS Integration Example Profile Management and Security Settings

Profile Settings

Change Password

Manage Social Sign In

Manage 2FA Backup Recovery Codes

Recovery codes can be used in panic situations where you have lost access to your 2FA device.

Manage 2FA TOTP Authenticator App

Add a TOTP Authenticator App to your account to improve your account security. Popular Authenticator Apps are{" "} LastPass {" "} and Google Authenticator ( iOS ,{" "} Android ).

Manage Hardware Tokens and Biometrics

Use Hardware Tokens (e.g. YubiKey) or Biometrics (e.g. FaceID, TouchID) to enhance your account security.

Manage Passkeys

Go back ) } export default Settings