{"version":3,"file":"IDPLogout.mjs","sources":["../../../../../../../../../web/src/ui/components/organisms/IDPLogout.tsx"],"sourcesContent":["import { useLingui } from '@lingui/react/macro';\nimport { BootstrapData } from '@stytch/core';\nimport {\n  IDPOAuthFlowMissingParamError,\n  OAuthLogoutStartOptions,\n  OAuthLogoutStartResponse,\n  StytchAPIError,\n  StytchSDKUIError,\n} from '@stytch/core/public';\nimport React, { useCallback, useEffect, useReducer } from 'react';\n\nimport { OAuthLogoutParams } from '../../../utils/idpHelpers';\nimport Button from '../atoms/Button';\nimport Column from '../atoms/Column';\nimport Typography from '../atoms/Typography';\nimport ButtonColumn from '../molecules/ButtonColumn';\nimport { Confirmation } from '../molecules/Confirmation';\nimport { ErrorDisplay } from '../molecules/ErrorScreen';\nimport { LoadingScreen } from '../molecules/Loading';\n\ntype Action =\n  | { type: 'START_PREFLIGHT' }\n  | { type: 'PREFLIGHT_ERROR'; error: string }\n  | {\n      type: 'COMPLETE_PREFLIGHT';\n      consent_required: boolean;\n      redirect_uri: string;\n    }\n  | { type: 'CONSENT_DENIED' };\n\ntype LogoutState = {\n  // True if there is a request in progress\n  loading: boolean;\n  // True if we have kicked off the preflight request\n  preflight: boolean;\n  error: string | null;\n  // True if logout has been denied by the end user\n  denied: boolean;\n  // Preflight results: Do we need to ask for consent? Who is asking?\n  consent_required: boolean;\n  // Preflight results: Where do we go afterward?\n  redirect_uri: string;\n};\n\nconst initialState = (error: string | null): LogoutState => ({\n  loading: !error,\n  preflight: !!error,\n  error: error,\n  denied: false,\n  consent_required: false,\n  redirect_uri: '',\n});\n\nconst logoutStateReducer = (state: LogoutState, action: Action): LogoutState => {\n  switch (action.type) {\n    case 'START_PREFLIGHT':\n      return { ...state, preflight: true, loading: true };\n    case 'PREFLIGHT_ERROR':\n      return { ...state, preflight: true, loading: false, error: action.error };\n    case 'COMPLETE_PREFLIGHT':\n      return {\n        ...state,\n        loading: false,\n        consent_required: action.consent_required,\n        redirect_uri: action.redirect_uri,\n      };\n    case 'CONSENT_DENIED':\n      return { ...state, denied: true };\n    default:\n      return state;\n  }\n};\n\ninterface IDPLogoutState {\n  state: LogoutState;\n  submit({ consent_granted }: { consent_granted: boolean }): Promise<void>;\n}\n\nconst browserNavigate = (href: string) => {\n  window.location.href = href;\n};\n\nexport const useLogoutState = ({\n  initialError,\n  initialParams,\n  oauthLogoutStart,\n  revokeSession,\n  onError,\n  navigate = browserNavigate,\n}: {\n  initialError: string | null;\n  initialParams: OAuthLogoutParams;\n  oauthLogoutStart(data: OAuthLogoutStartOptions): Promise<OAuthLogoutStartResponse>;\n  revokeSession(): Promise<unknown>;\n  onError(error: StytchSDKUIError): void;\n  navigate?: (href: string) => void;\n}): IDPLogoutState => {\n  const [state, dispatch] = useReducer(logoutStateReducer, initialState(initialError));\n\n  useEffect(() => {\n    if (!initialError) return;\n    onError(new IDPOAuthFlowMissingParamError(initialError));\n  }, [initialError, onError]);\n\n  const submitInternal = useCallback(\n    async (redirectURI: string) => {\n      try {\n        await revokeSession();\n      } catch {\n        // Session may already be revoked--in any event, we still want to\n        // redirect the user\n      }\n      navigate(redirectURI);\n    },\n    [revokeSession, navigate],\n  );\n\n  const logoutPreflight = useCallback(async () => {\n    dispatch({ type: 'START_PREFLIGHT' });\n\n    let startResponse;\n    try {\n      startResponse = await oauthLogoutStart(initialParams);\n    } catch (e: unknown) {\n      const err = StytchAPIError.from(e);\n      const message = err.error_message;\n      dispatch({ type: 'PREFLIGHT_ERROR', error: message });\n      onError(err);\n      return;\n    }\n\n    if (startResponse.consent_required) {\n      dispatch({\n        type: 'COMPLETE_PREFLIGHT',\n        consent_required: startResponse.consent_required,\n        redirect_uri: startResponse.redirect_uri,\n      });\n      return;\n    } else {\n      submitInternal(startResponse.redirect_uri);\n    }\n  }, [initialParams, oauthLogoutStart, onError, submitInternal]);\n\n  useEffect(() => {\n    if (state.preflight) {\n      return;\n    }\n    logoutPreflight();\n  }, [logoutPreflight, state.preflight]);\n\n  const submit = useCallback(\n    async ({ consent_granted }: { consent_granted: boolean }) => {\n      if (consent_granted) {\n        return submitInternal(state.redirect_uri);\n      } else {\n        dispatch({ type: 'CONSENT_DENIED' });\n      }\n    },\n    [submitInternal, state],\n  );\n\n  return { state, submit };\n};\n\ntype Props = IDPLogoutState & {\n  bootstrap: BootstrapData;\n  bootstrapNotLoaded: boolean;\n};\nexport const IDPLogout = ({ state, submit, bootstrap, bootstrapNotLoaded }: Props) => {\n  const { t } = useLingui();\n  const { loading, error, denied } = state;\n  if (loading || bootstrapNotLoaded) {\n    return <LoadingScreen />;\n  }\n  if (error) {\n    return <ErrorDisplay text={error} />;\n  }\n  if (denied) {\n    return (\n      <Confirmation\n        text={t({\n          id: 'idpLogout.notLoggedOut',\n          message: 'You have not been logged out. You may close this page.',\n        })}\n      />\n    );\n  }\n\n  const projectName = bootstrap.projectName!;\n  return (\n    <Column gap={6}>\n      <Typography variant=\"header\" align=\"center\">\n        {t({\n          id: 'idpLogout.title',\n          message: 'Log out?',\n        })}\n      </Typography>\n      <Typography variant=\"body\">\n        {t({\n          id: 'idpLogout.confirmMessage',\n          message: `Are you sure you want to log out of your ${projectName} account?`,\n        })}\n      </Typography>\n\n      <ButtonColumn>\n        <Button variant=\"primary\" onClick={() => submit({ consent_granted: true })}>\n          {t({\n            id: 'idpLogout.yes',\n            message: 'Yes',\n          })}\n        </Button>\n        <Button onClick={() => submit({ consent_granted: false })} variant=\"ghost\">\n          {t({\n            id: 'idpLogout.no',\n            message: 'No',\n          })}\n        </Button>\n      </ButtonColumn>\n    </Column>\n  );\n};\n"],"names":["initialState","error","loading","preflight","denied","consent_required","redirect_uri","logoutStateReducer","state","action","type","browserNavigate","href","window","location","useLogoutState","initialError","initialParams","oauthLogoutStart","revokeSession","onError","navigate","dispatch","useReducer","useEffect","IDPOAuthFlowMissingParamError","submitInternal","useCallback","redirectURI","logoutPreflight","startResponse","e","err","StytchAPIError","from","message","error_message","submit","consent_granted","IDPLogout","bootstrap","bootstrapNotLoaded","useLingui","React","LoadingScreen","ErrorDisplay","text","Confirmation","projectName","Column","gap","Typography","variant","align","ButtonColumn","Button","onClick"],"mappings":"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"}