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 { useAvailableExternalAuthenticationsQuery } from "@dashboard/graphql";
|
||||||
import useLocalStorage from "@dashboard/hooks/useLocalStorage";
|
|
||||||
import useNavigator from "@dashboard/hooks/useNavigator";
|
import useNavigator from "@dashboard/hooks/useNavigator";
|
||||||
import { getAppMountUriForRedirect } from "@dashboard/utils/urls";
|
import { getAppMountUriForRedirect } from "@dashboard/utils/urls";
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
|
@ -9,6 +8,7 @@ import useRouter from "use-react-router";
|
||||||
import { useUser } from "..";
|
import { useUser } from "..";
|
||||||
import LoginPage from "../components/LoginPage";
|
import LoginPage from "../components/LoginPage";
|
||||||
import { LoginFormData } from "../components/LoginPage/types";
|
import { LoginFormData } from "../components/LoginPage/types";
|
||||||
|
import { useAuthParameters } from "../hooks/useAuthParameters";
|
||||||
import { loginCallbackPath, LoginUrlQueryParams } from "../urls";
|
import { loginCallbackPath, LoginUrlQueryParams } from "../urls";
|
||||||
|
|
||||||
interface LoginViewProps {
|
interface LoginViewProps {
|
||||||
|
@ -29,15 +29,14 @@ const LoginView: React.FC<LoginViewProps> = ({ params }) => {
|
||||||
data: externalAuthentications,
|
data: externalAuthentications,
|
||||||
loading: externalAuthenticationsLoading,
|
loading: externalAuthenticationsLoading,
|
||||||
} = useAvailableExternalAuthenticationsQuery();
|
} = useAvailableExternalAuthenticationsQuery();
|
||||||
const [
|
|
||||||
requestedExternalPluginId,
|
|
||||||
setRequestedExternalPluginId,
|
|
||||||
] = useLocalStorage("requestedExternalPluginId", null);
|
|
||||||
|
|
||||||
const [fallbackUri, setFallbackUri] = useLocalStorage(
|
const {
|
||||||
"externalLoginFallbackUri",
|
fallbackUri,
|
||||||
null,
|
requestedExternalPluginId,
|
||||||
);
|
isCallbackPath,
|
||||||
|
setFallbackUri,
|
||||||
|
setRequestedExternalPluginId,
|
||||||
|
} = useAuthParameters();
|
||||||
|
|
||||||
const handleSubmit = async (data: LoginFormData) => {
|
const handleSubmit = async (data: LoginFormData) => {
|
||||||
const result = await login(data.email, data.password);
|
const result = await login(data.email, data.password);
|
||||||
|
@ -70,15 +69,13 @@ const LoginView: React.FC<LoginViewProps> = ({ params }) => {
|
||||||
});
|
});
|
||||||
setRequestedExternalPluginId(null);
|
setRequestedExternalPluginId(null);
|
||||||
if (result && !result?.errors?.length) {
|
if (result && !result?.errors?.length) {
|
||||||
navigate(fallbackUri ?? "/");
|
navigate(fallbackUri);
|
||||||
setFallbackUri(null);
|
setFallbackUri(null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const { code, state } = params;
|
const { code, state } = params;
|
||||||
const isCallbackPath = location.pathname.includes(loginCallbackPath);
|
|
||||||
|
|
||||||
const externalAuthParamsExist = code && state && isCallbackPath;
|
const externalAuthParamsExist = code && state && isCallbackPath;
|
||||||
const externalAuthNotPerformed = !authenticating && !errors.length;
|
const externalAuthNotPerformed = !authenticating && !errors.length;
|
||||||
|
|
||||||
|
|
|
@ -20,10 +20,11 @@ import { ExternalAppProvider } from "./apps/components/ExternalAppContext";
|
||||||
import { AppSections } from "./apps/urls";
|
import { AppSections } from "./apps/urls";
|
||||||
import AttributeSection from "./attributes";
|
import AttributeSection from "./attributes";
|
||||||
import { attributeSection } from "./attributes/urls";
|
import { attributeSection } from "./attributes/urls";
|
||||||
import Auth, { useUser } from "./auth";
|
import Auth from "./auth";
|
||||||
import AuthProvider from "./auth/AuthProvider";
|
import AuthProvider from "./auth/AuthProvider";
|
||||||
import LoginLoading from "./auth/components/LoginLoading/LoginLoading";
|
import LoginLoading from "./auth/components/LoginLoading/LoginLoading";
|
||||||
import SectionRoute from "./auth/components/SectionRoute";
|
import SectionRoute from "./auth/components/SectionRoute";
|
||||||
|
import { useAuthRedirection } from "./auth/hooks/useAuthRedirection";
|
||||||
import CategorySection from "./categories";
|
import CategorySection from "./categories";
|
||||||
import ChannelsSection from "./channels";
|
import ChannelsSection from "./channels";
|
||||||
import { channelsSection } from "./channels/urls";
|
import { channelsSection } from "./channels/urls";
|
||||||
|
@ -145,7 +146,7 @@ const App: React.FC = () => (
|
||||||
const Routes: React.FC = () => {
|
const Routes: React.FC = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const [, dispatchAppState] = useAppState();
|
const [, dispatchAppState] = useAppState();
|
||||||
const { authenticated, authenticating } = useUser();
|
const { authenticated, authenticating } = useAuthRedirection();
|
||||||
|
|
||||||
const { channel } = useAppChannel(false);
|
const { channel } = useAppChannel(false);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue