Skip to content
AuthErrors.tsx 2.92 KiB
Newer Older
import {
  Button,
  Link,
  Modal,
  ModalBody,
  ModalContent,
  ModalFooter,
  ModalHeader,
} from "@nextui-org/react";
import { useEffect, useState } from "react";

const Params = {
  TYPE: "auth_type",
  ERROR: "auth_error",
  ERROR_DESC: "auth_error_desc",
  CAN_RETRY: "auth_retry",
};

/**
 * Show popups that detail auth error messages
 * @returns
 */
export const AuthErrors = () => {
  const [params, setParams] = useState(
    new URLSearchParams(window.location.search)
  );

  const onClose = () => {
    const url = new URL(window.location.href);
    url.search = "";
    window.history.replaceState({}, "", url.toString());

    setParams(new URLSearchParams(window.location.search));
  };

  return (
    <>
      <OPError
        isOpen={params.get(Params.TYPE) === "op"}
        onClose={onClose}
        params={params}
      />
      <BannedError
        isOpen={params.get(Params.TYPE) === "banned"}
        onClose={onClose}
        params={params}
      />
const BannedError = ({
  isOpen,
  onClose,
  params,
}: {
  isOpen: boolean;
  onClose: () => void;
  params: URLSearchParams;
}) => {
  return (
    <Modal isOpen={isOpen} onClose={onClose} isDismissable={false}>
      <ModalContent>
Grant's avatar
Grant committed
        {(_onClose) => (
          <>
            <ModalHeader>Login Error</ModalHeader>
            <ModalBody>
              <b>Your instance is banned.</b> You cannot proceed.
              <br />
              <br />
              {params.has(Params.ERROR_DESC) ? (
                <>Reason: {params.get(Params.ERROR_DESC)}</>
              ) : (
                <>No reason provided</>
              )}
            </ModalBody>
          </>
        )}
      </ModalContent>
    </Modal>
  );
};

/**
 * This is for OP errors, these might not be retryable
 * @param param0
 * @returns
 */
const OPError = ({
  isOpen,
  onClose,
  params,
}: {
  isOpen: boolean;
  onClose: () => void;
  params: URLSearchParams;
}) => {
  const canRetry = params.has(Params.CAN_RETRY);
Grant's avatar
Grant committed
  const [error, _setError] = useState(params.get(Params.ERROR));
  const [errorDesc, setErrorDesc] = useState(params.get(Params.ERROR_DESC));

  useEffect(() => {
    switch (params.get(Params.ERROR)) {
      case "invalid_grant":
        setErrorDesc("Invalid token, try logging in again");
        break;
    }
  }, [params]);

  return (
    <Modal isOpen={isOpen} onClose={onClose} isDismissable={false}>
      <ModalContent>
Grant's avatar
Grant committed
        {(_onClose) => (
          <>
            <ModalHeader>Login Error</ModalHeader>
            <ModalBody>
              <b>Error:</b> {error}
              <br />
              <br />
              <b>Error Description:</b> {errorDesc}
            </ModalBody>
            <ModalFooter>
              {canRetry && (
                <Button color="primary" href="/api/login" as={Link}>
                  Login
                </Button>
              )}
            </ModalFooter>
          </>
        )}
      </ModalContent>
    </Modal>
  );
};