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:
parent
01c24c1622
commit
f79629129a
4 changed files with 92 additions and 14 deletions
20
src/auth/hooks/useAuthParameters.ts
Normal file
20
src/auth/hooks/useAuthParameters.ts
Normal 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,
|
||||
};
|
||||
};
|
60
src/auth/hooks/useAuthRedirection.ts
Normal file
60
src/auth/hooks/useAuthRedirection.ts
Normal 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,
|
||||
};
|
||||
};
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue