All files / app/features/auth AuthProvider.tsx

96.87% Statements 31/32
66.66% Branches 2/3
85.71% Functions 6/7
96.55% Lines 28/29

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  68x 68x 68x 68x 68x 68x   68x 68x   68x     1518x 1517x     1517x     68x 429x 429x   429x   429x 365x   2x 1x 1x     1x 1x 1x       365x 365x       429x     1518x  
import { RpcError } from "grpc-web";
import { useTranslation } from "i18n";
import { AUTH } from "i18n/namespaces";
import React, { Context, ReactNode, useContext, useEffect } from "react";
import { jailRoute, loginRoute } from "routes";
import { setUnauthenticatedErrorHandler } from "service/client";
import useStablePush from "utils/useStablePush";
 
import { JAILED_ERROR_MESSAGE } from "./constants";
import useAuthStore, { AuthStoreType } from "./useAuthStore";
 
export const AuthContext = React.createContext<null | AuthStoreType>(null);
 
function useAppContext<T>(context: Context<T | null>) {
  const contextValue = useContext(context);
  Iif (contextValue === null) {
    throw Error("No context provided!");
  }
  return contextValue;
}
 
export default function AuthProvider({ children }: { children: ReactNode }) {
  const { t } = useTranslation(AUTH);
  const store = useAuthStore();
 
  const push = useStablePush();
 
  useEffect(() => {
    setUnauthenticatedErrorHandler(async (e: RpcError) => {
      // the backend will return "Permission denied" if you're just jailed, and "Unauthorized" otherwise
      if (e.message === JAILED_ERROR_MESSAGE) {
        await store.authActions.updateJailStatus();
        push(jailRoute);
      } else {
        // completely logged out
        await store.authActions.logout();
        store.authActions.authError(t("logged_out_message"));
        push(loginRoute);
      }
    });
 
    return () => {
      setUnauthenticatedErrorHandler(async () => {});
    };
  }, [store.authActions, push, t]);
 
  return <AuthContext.Provider value={store}>{children}</AuthContext.Provider>;
}
 
export const useAuthContext = () => useAppContext(AuthContext);