Verified Commit 92082e8f authored by Marek Veselý's avatar Marek Veselý
Browse files

feat: add a handler for session expired errors

parent 1005de05
Loading
Loading
Loading
Loading
+0 −22
Original line number Diff line number Diff line
import { css } from '@emotion/css'
import { Container } from '@inject/shared'
import InjectLogo from '@inject/shared/svg/inject-logo--vertical-black.svg?react'
import { Login } from './LoginComp'

const page = css`
  height: 100%;
  display: flex;
  flex-direction: column;
`

const logo = css`
  width: 100%;
  height: 20rem;
`

export const LoginDialog = () => (
  <Container className={page}>
    <InjectLogo className={logo} />
    <Login />
  </Container>
)
+25 −3
Original line number Diff line number Diff line
import { Button, Colors, FormGroup, InputGroup } from '@blueprintjs/core'
import {
  Button,
  Callout,
  Colors,
  FormGroup,
  InputGroup,
} from '@blueprintjs/core'
import { css, cx } from '@emotion/css'
import { useHost } from '@inject/graphql'
import {
@@ -10,7 +16,7 @@ import {
  wiggleClass,
} from '@inject/shared'
import { useNavigate } from '@tanstack/react-router'
import type { FormEvent } from 'react'
import type { FC, FormEvent } from 'react'
import { useRef, useState } from 'react'
import { RegisterRoute } from '../../routes/register/route'

@@ -34,7 +40,11 @@ const loginForm = css`
  width: 100%;
`

export const Login = () => {
interface LoginFormProps {
  sessionExpired: boolean
}

export const LoginForm: FC<LoginFormProps> = ({ sessionExpired }) => {
  const host = useHost()
  const { beginWiggling, wiggling } = useWiggle()

@@ -111,6 +121,18 @@ export const Login = () => {
  return (
    <div>
      <form onSubmit={handleSubmit} className={loginForm}>
        {sessionExpired && (
          <Callout
            intent='warning'
            compact
            className={css`
              margin-bottom: 0.5rem;
            `}
          >
            Your session has expired. Please log in again.
          </Callout>
        )}

        <div className={fields}>
          <FormGroup
            label='Username'
+23 −17
Original line number Diff line number Diff line
import { useSessionId } from '@inject/shared'
import { useNavigate } from '@tanstack/react-router'
import { useEffect } from 'react'
import { LoginDialog } from './LoginDialog'
import { css } from '@emotion/css'
import { Container } from '@inject/shared'
import InjectLogo from '@inject/shared/svg/inject-logo--vertical-black.svg?react'
import type { FC } from 'react'
import { LoginForm } from './LoginForm'

export const LoginPage = () => {
  const sessionId = useSessionId()
  const navigate = useNavigate()
const page = css`
  height: 100%;
  display: flex;
  flex-direction: column;
`

  useEffect(() => {
    if (sessionId) {
      navigate({ to: '/' })
      return
    }
  }, [navigate, sessionId])
const logo = css`
  width: 100%;
  height: 20rem;
`

  if (sessionId) {
    return null
  }
  return <LoginDialog />
interface LoginPageProps {
  sessionExpired: boolean
}

export const LoginPage: FC<LoginPageProps> = ({ sessionExpired }) => (
  <Container className={page}>
    <InjectLogo className={logo} />
    <LoginForm sessionExpired={sessionExpired} />
  </Container>
)
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ const versionsCompatible = (backendVersion: string, frontendVersion: string) =>
export const URQLConnection: FC<PropsWithChildren> = ({ children }) => {
  const hostVar = useHost()
  const sessionId = useSessionId()
  // TODO: add loading vs error states
  const backendVersion = useBackendVersion()

  const [state, setState] = useState<ConnectionStatus>(
+0 −36
Original line number Diff line number Diff line
import { useAuthIdentity, useHost } from '@inject/graphql'
import {
  authenticatedFetch,
  clearNotify,
  logoutUrl,
  setSessionId,
} from '@inject/shared'
import { useNavigate } from '@tanstack/react-router'
import { LoginRoute } from '../../routes/login/route'

// TODO: deduplicate with ChangePassword

export const useHandleLogout = () => {
  const host = useHost()
  const nav = useNavigate()
  const { refetch } = useAuthIdentity()

  return async () => {
    await authenticatedFetch(logoutUrl(host), { method: 'POST' })
    localStorage.clear()
    sessionStorage.clear()
    // TODO: await and handle failures
    indexedDB.deleteDatabase('graphcache-v3')
    clearNotify()
    setSessionId('')
    refetch()
    window.dispatchEvent(new CustomEvent('killWs'))
    nav({
      to: LoginRoute.to,
      // Reload to fully reset state
      reloadDocument: true,
    })
  }
}

export default useHandleLogout
Loading