Trigger auth plugin by given query param (#3586)

* Trigger auth plugin by given query param

* Fix fallback patameters

* Move hook to the separated file

* Re-login case
This commit is contained in:
Patryk Andrzejewski 2023-05-09 17:11:20 +02:00 committed by GitHub
parent 01c24c1622
commit f79629129a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 92 additions and 14 deletions

View file

@ -0,0 +1,20 @@
import useLocalStorage from "@dashboard/hooks/useLocalStorage";
import { loginCallbackPath } from "../urls";
export const useAuthParameters = () => {
const [requestedExternalPluginId, setRequestedExternalPluginId] =
useLocalStorage("requestedExternalPluginId", null);
const [fallbackUri, setFallbackUri] = useLocalStorage(
"externalLoginFallbackUri",
null,
);
return {
requestedExternalPluginId,
fallbackUri: fallbackUri === "null" ? "/" : fallbackUri,
isCallbackPath: location.pathname.includes(loginCallbackPath),
setRequestedExternalPluginId,
setFallbackUri,
};
};

View file

@ -0,0 +1,60 @@
import { getAppMountUri } from "@dashboard/config";
import { getAppMountUriForRedirect } from "@dashboard/utils/urls";
import { useEffect } from "react";
import urlJoin from "url-join";
import useRouter from "use-react-router";
import { useUser } from "..";
import { loginCallbackPath } from "../urls";
import { useAuthParameters } from "./useAuthParameters";
const PLUGIN_ID_PARAM = "saleorPluginId";
export const useAuthRedirection = () => {
const router = useRouter();
const params = new URLSearchParams(router.location.search);
const shouldRedirect = params.has(PLUGIN_ID_PARAM);
const { authenticated, authenticating, requestLoginByExternalPlugin } =
useUser();
const { setRequestedExternalPluginId } = useAuthParameters();
const pluginId = params.get(PLUGIN_ID_PARAM);
const handleAuthentication = async () => {
setRequestedExternalPluginId(pluginId);
const redirectUri = urlJoin(
window.location.origin,
getAppMountUriForRedirect(),
loginCallbackPath,
);
const response = await requestLoginByExternalPlugin(pluginId, {
redirectUri,
});
const data = JSON.parse(response?.authenticationData || "");
if (data && !response?.errors?.length) {
window.location.href = data.authorizationUrl;
}
};
useEffect(() => {
if (!shouldRedirect) {
return;
}
if (authenticated || authenticating) {
window.location.href = getAppMountUri();
return;
}
if (!authenticated && !authenticating) {
handleAuthentication();
}
}, [shouldRedirect, authenticated, authenticating]);
return {
authenticated,
authenticating: authenticating || shouldRedirect,
};
};

View file

@ -1,5 +1,4 @@
import { useAvailableExternalAuthenticationsQuery } from "@dashboard/graphql";
import useLocalStorage from "@dashboard/hooks/useLocalStorage";
import useNavigator from "@dashboard/hooks/useNavigator";
import { getAppMountUriForRedirect } from "@dashboard/utils/urls";
import React, { useEffect } from "react";
@ -9,6 +8,7 @@ import useRouter from "use-react-router";
import { useUser } from "..";
import LoginPage from "../components/LoginPage";
import { LoginFormData } from "../components/LoginPage/types";
import { useAuthParameters } from "../hooks/useAuthParameters";
import { loginCallbackPath, LoginUrlQueryParams } from "../urls";
interface LoginViewProps {
@ -29,15 +29,14 @@ const LoginView: React.FC<LoginViewProps> = ({ params }) => {
data: externalAuthentications,
loading: externalAuthenticationsLoading,
} = useAvailableExternalAuthenticationsQuery();
const [
requestedExternalPluginId,
setRequestedExternalPluginId,
] = useLocalStorage("requestedExternalPluginId", null);
const [fallbackUri, setFallbackUri] = useLocalStorage(
"externalLoginFallbackUri",
null,
);
const {
fallbackUri,
requestedExternalPluginId,
isCallbackPath,
setFallbackUri,
setRequestedExternalPluginId,
} = useAuthParameters();
const handleSubmit = async (data: LoginFormData) => {
const result = await login(data.email, data.password);
@ -70,15 +69,13 @@ const LoginView: React.FC<LoginViewProps> = ({ params }) => {
});
setRequestedExternalPluginId(null);
if (result && !result?.errors?.length) {
navigate(fallbackUri ?? "/");
navigate(fallbackUri);
setFallbackUri(null);
}
};
useEffect(() => {
const { code, state } = params;
const isCallbackPath = location.pathname.includes(loginCallbackPath);
const externalAuthParamsExist = code && state && isCallbackPath;
const externalAuthNotPerformed = !authenticating && !errors.length;

View file

@ -20,10 +20,11 @@ import { ExternalAppProvider } from "./apps/components/ExternalAppContext";
import { AppSections } from "./apps/urls";
import AttributeSection from "./attributes";
import { attributeSection } from "./attributes/urls";
import Auth, { useUser } from "./auth";
import Auth from "./auth";
import AuthProvider from "./auth/AuthProvider";
import LoginLoading from "./auth/components/LoginLoading/LoginLoading";
import SectionRoute from "./auth/components/SectionRoute";
import { useAuthRedirection } from "./auth/hooks/useAuthRedirection";
import CategorySection from "./categories";
import ChannelsSection from "./channels";
import { channelsSection } from "./channels/urls";
@ -145,7 +146,7 @@ const App: React.FC = () => (
const Routes: React.FC = () => {
const intl = useIntl();
const [, dispatchAppState] = useAppState();
const { authenticated, authenticating } = useUser();
const { authenticated, authenticating } = useAuthRedirection();
const { channel } = useAppChannel(false);