All files / src/features/MerchantPortal/DeveloperApi/hooks useGenerateApiKey.tsx

45.71% Statements 16/35
20% Branches 2/10
22.22% Functions 2/9
44.11% Lines 15/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123                                        2x               2x             2x 30x 30x   30x       30x   30x       30x               30x   30x                                         30x                                                           30x 12x     30x                
import NiceModal, { useModal } from "@ebay/nice-modal-react";
import { yupResolver } from "@hookform/resolvers/yup";
import * as Yup from "yup";
import { SubmitHandler, useForm } from "react-hook-form";
import { useMutation, useQueryClient } from "react-query";
import { customInstance } from "@services/api";
import { buildMerchantEndpoints } from "@services/api/utils.api";
import { showMessage } from "@common/Toast";
import { useEffect } from "react";
import { QKEY_MERCHANTS_API_KEYS } from "@constants/queryKeys";
import { validIpAddress } from "@components/DeveloperApi/utils";
 
type FormInputs = {
  name: string;
  description: string;
  origin: string;
  allowedOrigins: string[];
  environment: "sandbox" | "production";
};
 
const defaultValues = {
  name: "",
  description: "",
  origin: "",
  allowedOrigins: [],
  environment: "sandbox" as const,
};
 
const schema = Yup.object().shape({
  name: Yup.string().required("First Name is required"),
  description: Yup.string(),
  origin: Yup.string(),
  environment: Yup.string(),
});
 
export const useGenerateApiKey = (successModal: string) => {
  const modal = useModal();
  const queryClient = useQueryClient();
 
  const methods = useForm<FormInputs>({
    resolver: yupResolver(schema),
    defaultValues,
  });
  const { reset } = methods;
 
  const handleCloseModal = () => {
    modal.hide();
  };
 
  const createApiKeyMutation = useMutation((data: any) => {
    return customInstance({
      url: buildMerchantEndpoints("api-keys"),
      method: "POST",
      data,
    });
  });
 
  const { isLoading } = createApiKeyMutation;
 
  const cleanOrigins = (origins: string[]): string[] => {
    if (origins?.length > 0) {
      const uniqueOrigins = new Set<string>();
      origins.forEach((origin) => {
        const isValidIpAdress = validIpAddress(origin);
        //if the input is not a valid URL we check if its a valid IP and add to the set
        try {
          const cleanUrl = new URL(origin);
          uniqueOrigins.add(cleanUrl.origin);
        } catch {
          if (isValidIpAdress) {
            uniqueOrigins.add(origin);
          }
        }
      });
      return Array.from(uniqueOrigins);
    } else {
      return ["*"];
    }
  };
 
  const onSubmit: SubmitHandler<FormInputs> = async (data) => {
    const customData = {
      name: data.name,
      description: data.description,
      allowedOrigins: cleanOrigins(data.allowedOrigins),
      isSandbox: data.environment === "sandbox",
    };
 
    createApiKeyMutation.mutate(customData, {
      onError: (error: any) => {
        showMessage(
          "Error",
          error?.response?.data?.input?.[0]?.message ||
            error?.response?.data?.message,
        );
      },
      onSuccess: async (res) => {
        NiceModal.show(successModal, {
          apiKey: res?.apiKey,
          isSandbox: res?.isSandbox,
          ...(successModal && {
            isCreate: true,
          }),
        });
        queryClient.invalidateQueries(QKEY_MERCHANTS_API_KEYS);
        handleCloseModal();
      },
    });
  };
 
  useEffect(() => {
    if (modal.visible) reset(defaultValues);
  }, [modal.visible]);
 
  return {
    open: modal.visible,
    handleCloseModal,
    methods,
    onSubmit,
    isLoading,
  };
};