mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 19:44:52 +00:00
Fix case where user can get stuck in a deleted organization if they were prev logged into it
This commit is contained in:
@@ -24,10 +24,10 @@ import {
|
||||
User,
|
||||
UserEnc
|
||||
} from "./types";
|
||||
import { queryClient } from "@app/hooks/api/reactQuery";
|
||||
|
||||
export const fetchUserDetails = async () => {
|
||||
const { data } = await apiRequest.get<{ user: User & UserEnc }>("/api/v1/user");
|
||||
|
||||
return data.user;
|
||||
};
|
||||
|
||||
@@ -278,30 +278,33 @@ export const useRegisterUserAction = () => {
|
||||
});
|
||||
};
|
||||
|
||||
export const useLogoutUser = (keepQueryClient?: boolean) => {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: async () => {
|
||||
await apiRequest.post("/api/v1/auth/logout");
|
||||
},
|
||||
onSuccess: () => {
|
||||
setAuthToken("");
|
||||
// Delete the cookie by not setting a value; Alternatively clear the local storage
|
||||
localStorage.removeItem("protectedKey");
|
||||
localStorage.removeItem("protectedKeyIV");
|
||||
localStorage.removeItem("protectedKeyTag");
|
||||
localStorage.removeItem("publicKey");
|
||||
localStorage.removeItem("encryptedPrivateKey");
|
||||
localStorage.removeItem("iv");
|
||||
localStorage.removeItem("tag");
|
||||
localStorage.removeItem("PRIVATE_KEY");
|
||||
localStorage.removeItem("orgData.id");
|
||||
sessionStorage.removeItem(SessionStorageKeys.CLI_TERMINAL_TOKEN);
|
||||
export const logoutUser = async () => {
|
||||
await apiRequest.post("/api/v1/auth/logout");
|
||||
};
|
||||
|
||||
if (!keepQueryClient) {
|
||||
queryClient.clear();
|
||||
}
|
||||
}
|
||||
// Utility function to clear session storage and query cache
|
||||
export const clearSession = (keepQueryClient?: boolean) => {
|
||||
setAuthToken(""); // Clear authentication token
|
||||
localStorage.removeItem("protectedKey");
|
||||
localStorage.removeItem("protectedKeyIV");
|
||||
localStorage.removeItem("protectedKeyTag");
|
||||
localStorage.removeItem("publicKey");
|
||||
localStorage.removeItem("encryptedPrivateKey");
|
||||
localStorage.removeItem("iv");
|
||||
localStorage.removeItem("tag");
|
||||
localStorage.removeItem("PRIVATE_KEY");
|
||||
localStorage.removeItem("orgData.id");
|
||||
sessionStorage.removeItem(SessionStorageKeys.CLI_TERMINAL_TOKEN);
|
||||
|
||||
if (!keepQueryClient) {
|
||||
queryClient.clear(); // Clear React Query cache
|
||||
}
|
||||
};
|
||||
|
||||
export const useLogoutUser = (keepQueryClient?: boolean) => {
|
||||
return useMutation({
|
||||
mutationFn: logoutUser,
|
||||
onSuccess: () => clearSession(keepQueryClient)
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ export const LoginPage = () => {
|
||||
console.log("Error - Not logged in yet");
|
||||
}
|
||||
};
|
||||
|
||||
if (isLoggedIn()) {
|
||||
handleRedirects();
|
||||
}
|
||||
|
||||
@@ -250,20 +250,24 @@ export const SignupInvitePage = () => {
|
||||
setStep(2);
|
||||
} else {
|
||||
const redirectExistingUser = async () => {
|
||||
const { token: mfaToken, isMfaEnabled } = await selectOrganization({
|
||||
organizationId
|
||||
});
|
||||
try {
|
||||
const { token: mfaToken, isMfaEnabled } = await selectOrganization({
|
||||
organizationId
|
||||
});
|
||||
|
||||
if (isMfaEnabled) {
|
||||
SecurityClient.setMfaToken(mfaToken);
|
||||
toggleShowMfa.on();
|
||||
setMfaSuccessCallback(() => redirectExistingUser);
|
||||
return;
|
||||
if (isMfaEnabled) {
|
||||
SecurityClient.setMfaToken(mfaToken);
|
||||
toggleShowMfa.on();
|
||||
setMfaSuccessCallback(() => redirectExistingUser);
|
||||
return;
|
||||
}
|
||||
|
||||
// user will be redirected to dashboard
|
||||
// if not logged in gets kicked out to login
|
||||
await navigateUserToOrg(navigate, organizationId);
|
||||
} catch (err) {
|
||||
navigate({ to: "/login" });
|
||||
}
|
||||
|
||||
// user will be redirected to dashboard
|
||||
// if not logged in gets kicked out to login
|
||||
await navigateUserToOrg(navigate, organizationId);
|
||||
};
|
||||
|
||||
await redirectExistingUser();
|
||||
|
||||
@@ -5,12 +5,15 @@ import { ROUTE_PATHS } from "@app/const/routes";
|
||||
import { userKeys } from "@app/hooks/api";
|
||||
import { authKeys, fetchAuthToken } from "@app/hooks/api/auth/queries";
|
||||
import { fetchUserDetails } from "@app/hooks/api/users/queries";
|
||||
import { AxiosError } from "axios";
|
||||
import { clearSession, logoutUser } from "@app/hooks/api/users/queries";
|
||||
|
||||
export const Route = createFileRoute("/_authenticate")({
|
||||
beforeLoad: async ({ context, location }) => {
|
||||
if (!context.serverConfig.initialized) {
|
||||
throw redirect({ to: "/admin/signup" });
|
||||
}
|
||||
|
||||
const data = await context.queryClient
|
||||
.ensureQueryData({
|
||||
queryKey: authKeys.getAuthToken,
|
||||
@@ -27,14 +30,31 @@ export const Route = createFileRoute("/_authenticate")({
|
||||
});
|
||||
});
|
||||
|
||||
if (!data.organizationId && location.pathname !== ROUTE_PATHS.Auth.PasswordSetupPage.path && location.pathname !== "/organization/none") {
|
||||
if (
|
||||
!data.organizationId &&
|
||||
location.pathname !== ROUTE_PATHS.Auth.PasswordSetupPage.path &&
|
||||
location.pathname !== "/organization/none"
|
||||
) {
|
||||
throw redirect({ to: "/login/select-organization" });
|
||||
}
|
||||
|
||||
const user = await context.queryClient.ensureQueryData({
|
||||
queryKey: userKeys.getUser,
|
||||
queryFn: fetchUserDetails
|
||||
});
|
||||
const user = await context.queryClient
|
||||
.ensureQueryData({
|
||||
queryKey: userKeys.getUser,
|
||||
queryFn: fetchUserDetails
|
||||
})
|
||||
.catch(async (error) => {
|
||||
const err = error as AxiosError;
|
||||
if (err.response?.status === 403) {
|
||||
// (dangtony98): this edge-case can occur if the user's token corresponds to an organization
|
||||
// that has been deleted for which we must clear the refresh token in http-only cookie
|
||||
clearSession(true);
|
||||
await logoutUser();
|
||||
throw redirect({
|
||||
to: "/login"
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return { organizationId: data.organizationId as string, isAuthenticated: true, user };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user