import { SelfServiceSettingsFlow , SubmitSelfServiceSettingsFlowBody } from '@ory/kratos-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 { Flow , Methods , Messages , ActionCard , CenterLink } from '../pkg' ; import { handleFlowError } from '../pkg/errors' ; import ory from '../pkg/sdk' ; interface Props { flow ? : SelfServiceSettingsFlow ; only ? : Methods ; } function SettingsCard ( { flow , only , children } ) { if ( ! flow ) { return null ; } const nodes = only ? flow . ui . nodes . filter ( ( { group } ) => group === only ) : flow . ui . nodes ; if ( nodes . length === 0 ) { return null ; } return < ActionCard wide > { children } < /ActionCard>; } const Settings = ( ) => { const [ flow , setFlow ] = useState < SelfServiceSettingsFlow > ( ) ; const router = useRouter ( ) ; const { flow : flowId , return_to : returnTo } = router . query ; useEffect ( ( ) => { if ( ! router . isReady || flow ) { return ; } if ( flowId ) { ory . getSelfServiceSettingsFlow ( String ( flowId ) ) . then ( ( { data } ) => { setFlow ( data ) ; } ) . catch ( handleFlowError ( router , 'settings' , setFlow ) ) ; return ; } ory . initializeSelfServiceSettingsFlowForBrowsers ( returnTo ? String ( returnTo ) : undefined ) . then ( ( { data } ) => { setFlow ( data ) ; } ) . catch ( handleFlowError ( router , 'settings' , setFlow ) ) ; } , [ flowId , router , router . isReady , returnTo , flow ] ) ; const onSubmit = ( values ) => router . push ( `/settings?flow=${ flow ?. id }` , undefined , { shallow : true } ) . then ( ( ) => ory . submitSelfServiceSettingsFlow ( String ( flow ?. id ) , undefined , values ) . then ( ( { data } ) => { setFlow ( data ) ; } ) . catch ( handleFlowError ( router , 'settings' , setFlow ) ) . catch ( async ( err ) => { if ( err . response ?. status === 400 ) { setFlow ( err . response ?. data ) ; return ; } return Promise . reject ( err ) ; } ) ) ; return ( < > < Head > < title > Profile Management and Security Settings - Ory NextJS Integration Example < /title> < meta name = "description" content = "NextJS + React + Vercel + Ory" / > < /Head> < CardTitle style = { { marginTop : 80 } } > Profile Management and Security Settings < /CardTitle> < SettingsCard only = "profile" flow = { flow } > < H3 > Profile Settings < /H3> < Messages messages = { flow ?. ui . messages } / > < Flow hideGlobalMessages onSubmit = { onSubmit } only = "profile" flow = { flow } / > < /SettingsCard> < SettingsCard only = "password" flow = { flow } > < H3 > Change Password < /H3> < Messages messages = { flow ?. ui . messages } / > < Flow hideGlobalMessages onSubmit = { onSubmit } only = "password" flow = { flow } / > < /SettingsCard> < SettingsCard only = "oidc" flow = { flow } > < H3 > Manage Social Sign In < /H3> < Messages messages = { flow ?. ui . messages } / > < Flow hideGlobalMessages onSubmit = { onSubmit } only = "oidc" flow = { flow } / > < /SettingsCard> < SettingsCard only = "lookup_secret" flow = { flow } > < H3 > Manage 2 FA Backup Recovery Codes < /H3> < Messages messages = { flow ?. ui . messages } / > < P > Recovery codes can be used in panic situations where you have lost access to your 2 FA device . < /P> < Flow hideGlobalMessages onSubmit = { onSubmit } only = "lookup_secret" flow = { flow } / > < /SettingsCard> < SettingsCard only = "totp" flow = { flow } > < H3 > Manage 2 FA TOTP Authenticator App < /H3> < P > Add a TOTP Authenticator App to your account to improve your account security . Popular Authenticator Apps are { ' ' } < a href = "https://www.lastpass.com" rel = "noreferrer" target = "_blank" > LastPass < /a>{' '} and Google Authenticator ( < a href = "https://apps.apple.com/us/app/google-authenticator/id388497605" target = "_blank" rel = "noreferrer" > iOS < /a> , { ' ' } < a href = "https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en&gl=US" target = "_blank" rel = "noreferrer" > Android < /a> ) . < /P> < Messages messages = { flow ?. ui . messages } / > < Flow hideGlobalMessages onSubmit = { onSubmit } only = "totp" flow = { flow } / > < /SettingsCard> < SettingsCard only = "webauthn" flow = { flow } > < H3 > Manage Hardware Tokens and Biometrics < /H3> < Messages messages = { flow ?. ui . messages } / > < P > Use Hardware Tokens ( e . g . YubiKey ) or Biometrics ( e . g . FaceID , TouchID ) to enhance your account security . < /P> < Flow hideGlobalMessages onSubmit = { onSubmit } only = "webauthn" flow = { flow } / > < /SettingsCard> < ActionCard wide > < Link href = "/" passHref > < CenterLink > Go back < /CenterLink> < /Link> < /ActionCard> < />); } ; export default Settings ;