0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

refactor(console): align sign-in/out redirect uris (#4385)

This commit is contained in:
Gao Sun 2023-08-23 22:53:48 +08:00 committed by GitHub
parent 7b569a4de9
commit 53486f27ad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 37 additions and 26 deletions

View file

@ -1,8 +1,7 @@
import { useLogto } from '@logto/react';
import { useContext, useEffect } from 'react';
import { useEffect } from 'react';
import { getCallbackUrl } from '@/consts';
import { TenantsContext } from '@/contexts/TenantsProvider';
import useRedirectUri from '@/hooks/use-redirect-uri';
import { saveRedirect } from '@/utils/storage';
import AppLoading from '../AppLoading';
@ -10,14 +9,14 @@ import AppLoading from '../AppLoading';
/** This component shows a loading indicator and tries to sign in again. */
function SessionExpired() {
const { signIn, isLoading } = useLogto();
const { currentTenantId } = useContext(TenantsContext);
const redirectUri = useRedirectUri();
useEffect(() => {
if (!isLoading) {
saveRedirect();
void signIn(getCallbackUrl(currentTenantId).href);
void signIn(redirectUri.href);
}
}, [signIn, isLoading, currentTenantId]);
}, [signIn, isLoading, redirectUri]);
return <AppLoading />;
}

View file

@ -1,6 +1,3 @@
import { ossConsolePath } from '@logto/schemas';
import { conditionalArray } from '@silverhand/essentials';
import { adminEndpoint, isCloud } from './env';
const getAdminTenantEndpoint = () => {
@ -17,12 +14,3 @@ const getAdminTenantEndpoint = () => {
export const adminTenantEndpoint = getAdminTenantEndpoint();
export const mainTitle = isCloud ? 'Logto Cloud' : 'Logto Console';
export const getCallbackUrl = (tenantId?: string) =>
new URL(
// Only Cloud has tenantId in callback URL
'/' + conditionalArray(isCloud ? tenantId : 'console', 'callback').join('/'),
window.location.origin
);
export const getSignOutRedirectPathname = () => (isCloud ? '/' : ossConsolePath);

View file

@ -11,12 +11,12 @@ import Profile from '@/assets/icons/profile.svg';
import SignOut from '@/assets/icons/sign-out.svg';
import UserAvatar from '@/components/UserAvatar';
import UserInfoCard from '@/components/UserInfoCard';
import { getSignOutRedirectPathname } from '@/consts';
import Divider from '@/ds-components/Divider';
import Dropdown, { DropdownItem } from '@/ds-components/Dropdown';
import Spacer from '@/ds-components/Spacer';
import { Ring as Spinner } from '@/ds-components/Spinner';
import useCurrentUser from '@/hooks/use-current-user';
import useRedirectUri from '@/hooks/use-redirect-uri';
import useTenantPathname from '@/hooks/use-tenant-pathname';
import useUserPreferences from '@/hooks/use-user-preferences';
import { DynamicAppearanceMode } from '@/types/appearance-mode';
@ -33,6 +33,7 @@ function UserInfo() {
const { user, isLoading: isLoadingUser } = useCurrentUser();
const anchorRef = useRef<HTMLDivElement>(null);
const [showDropdown, setShowDropdown] = useState(false);
const postSignOutRedirectUri = useRedirectUri('signOut');
const [isLoading, setIsLoading] = useState(false);
const {
@ -128,7 +129,7 @@ function UserInfo() {
return;
}
setIsLoading(true);
void signOut(new URL(getSignOutRedirectPathname(), window.location.origin).toString());
void signOut(postSignOutRedirectUri.href);
}}
>
{t('menu.sign_out')}

View file

@ -5,8 +5,9 @@ import { Outlet, useSearchParams } from 'react-router-dom';
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
import AppLoading from '@/components/AppLoading';
import { searchKeys, getCallbackUrl } from '@/consts';
import { searchKeys } from '@/consts';
import { TenantsContext } from '@/contexts/TenantsProvider';
import useRedirectUri from '@/hooks/use-redirect-uri';
import { saveRedirect } from '@/utils/storage';
/**
@ -32,15 +33,16 @@ export default function ProtectedRoutes() {
const api = useCloudApi();
const [searchParameters] = useSearchParams();
const { isAuthenticated, isLoading, signIn } = useLogto();
const { currentTenantId, isInitComplete, resetTenants } = useContext(TenantsContext);
const { isInitComplete, resetTenants } = useContext(TenantsContext);
const redirectUri = useRedirectUri();
useEffect(() => {
if (!isLoading && !isAuthenticated) {
saveRedirect();
const isSignUpMode = yes(searchParameters.get(searchKeys.signUp));
void signIn(getCallbackUrl(currentTenantId).href, conditional(isSignUpMode && 'signUp'));
void signIn(redirectUri.href, conditional(isSignUpMode && 'signUp'));
}
}, [currentTenantId, isAuthenticated, isLoading, searchParameters, signIn]);
}, [redirectUri, isAuthenticated, isLoading, searchParameters, signIn]);
useEffect(() => {
if (isAuthenticated && !isInitComplete) {

View file

@ -0,0 +1,20 @@
import { ossConsolePath } from '@logto/schemas';
import { conditionalArray } from '@silverhand/essentials';
import { useHref } from 'react-router-dom';
import { isCloud } from '@/consts/env';
/**
* The hook that returns the absolute URL for the sign-in or sign-out callback.
* The path is not related to react-router, which means the path will also include
* the basename of react-router if it's set.
*/
const useRedirectUri = (flow: 'signIn' | 'signOut' = 'signIn') => {
const path = useHref(
conditionalArray(!isCloud && ossConsolePath, flow === 'signIn' && '/callback').join('')
);
return new URL(path, window.location.origin);
};
export default useRedirectUri;

View file

@ -4,8 +4,8 @@ import { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import Logo from '@/assets/images/logo.svg';
import { getCallbackUrl } from '@/consts';
import Button from '@/ds-components/Button';
import useRedirectUri from '@/hooks/use-redirect-uri';
import useTenantPathname from '@/hooks/use-tenant-pathname';
import useTheme from '@/hooks/use-theme';
@ -16,6 +16,7 @@ function Welcome() {
const { navigate } = useTenantPathname();
const { isAuthenticated, signIn } = useLogto();
const theme = useTheme();
const redirectUri = useRedirectUri();
useEffect(() => {
// If authenticated, navigate to the console root page directly
@ -40,7 +41,7 @@ function Welcome() {
type="branding"
title="welcome.create_account"
onClick={() => {
void signIn(getCallbackUrl().href);
void signIn(redirectUri.href);
}}
/>
</div>