mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 21:15:32 +09:00
fix(app): refetch oauth bot destinations after account switch (#3460)
This commit is contained in:
1 parent
c0f825ae2a
commit
3c8fe74660
9 files changed
+61
-39
No files matched your search
@@ -769,7 +769,7 @@ export async function fetchDesktopHandoffInfo({
|
|||||||
return response.body;
|
return response.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CompleteLoginOptions {
|
interface CompleteLoginOptions {
|
||||||
redirectPath?: string | null;
|
redirectPath?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ const LoginPage = observer(function LoginPage({onBackActionChange}: LoginPagePro
|
|||||||
title={null}
|
title={null}
|
||||||
onLoginComplete={runtimeTarget.reset}
|
onLoginComplete={runtimeTarget.reset}
|
||||||
onBackActionChange={onBackActionChange}
|
onBackActionChange={onBackActionChange}
|
||||||
completeLoginRedirectPath={null}
|
completeLoginRedirectPath={Routes.ME}
|
||||||
forceCredentials={false}
|
forceCredentials={false}
|
||||||
startWithAddAccount={false}
|
startWithAddAccount={false}
|
||||||
runtimeTarget={runtimeTarget}
|
runtimeTarget={runtimeTarget}
|
||||||
|
|||||||
+1
-1
@@ -150,7 +150,7 @@ export const OAuthCommunityStep: React.FC<OAuthCommunityStepProps> = ({
|
|||||||
{destinationsError}
|
{destinationsError}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{!destinationsLoading && destinationOptions.length === 0 && (
|
{!destinationsLoading && !destinationsError && destinationOptions.length === 0 && (
|
||||||
<div className={styles.emptyState} data-flx="auth.o-auth-authorize-page.community-step.empty-state">
|
<div className={styles.emptyState} data-flx="auth.o-auth-authorize-page.community-step.empty-state">
|
||||||
{guildSelectorEmptyState}
|
{guildSelectorEmptyState}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+29
-4
@@ -10,6 +10,8 @@ import {
|
|||||||
} from '@app/features/auth/components/pages/oauth_authorize_page/OAuthAuthorizePageShared';
|
} from '@app/features/auth/components/pages/oauth_authorize_page/OAuthAuthorizePageShared';
|
||||||
import Accounts from '@app/features/auth/state/Accounts';
|
import Accounts from '@app/features/auth/state/Accounts';
|
||||||
import {formatList} from '@app/features/i18n/utils/IntlCache';
|
import {formatList} from '@app/features/i18n/utils/IntlCache';
|
||||||
|
import {AccountScopedWork} from '@app/features/platform/state/AccountScopedWork';
|
||||||
|
import {isAccountTransitionAbortError} from '@app/features/platform/state/AccountTransitionAbort';
|
||||||
import {http} from '@app/features/platform/transport/RestTransport';
|
import {http} from '@app/features/platform/transport/RestTransport';
|
||||||
import {failureMessage} from '@app/features/platform/utils/ResponseInspection';
|
import {failureMessage} from '@app/features/platform/utils/ResponseInspection';
|
||||||
import * as AvatarUtils from '@app/features/user/utils/AvatarUtils';
|
import * as AvatarUtils from '@app/features/user/utils/AvatarUtils';
|
||||||
@@ -106,9 +108,14 @@ function getGroupDmLabel(channel: ChannelResponse, unknownGroupDmLabel: string,
|
|||||||
return unknownGroupDmLabel;
|
return unknownGroupDmLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useBotInviteDestinations(enabled: boolean, rawPermissions: string | null): BotInviteDestinationsResult {
|
export function useBotInviteDestinations(
|
||||||
|
enabled: boolean,
|
||||||
|
rawPermissions: string | null,
|
||||||
|
revalidate: boolean,
|
||||||
|
): BotInviteDestinationsResult {
|
||||||
const {i18n} = useLingui();
|
const {i18n} = useLingui();
|
||||||
const currentAccountKey = Accounts.currentAccountKey;
|
const currentAccountKey = Accounts.currentAccountKey;
|
||||||
|
const accountWorkAdmitted = !AccountScopedWork.isSuspended;
|
||||||
const requestedPermissions = useMemo(() => parseRequestedBotPermissions(rawPermissions, false), [rawPermissions]);
|
const requestedPermissions = useMemo(() => parseRequestedBotPermissions(rawPermissions, false), [rawPermissions]);
|
||||||
const i18nRef = useRef(i18n);
|
const i18nRef = useRef(i18n);
|
||||||
i18nRef.current = i18n;
|
i18nRef.current = i18n;
|
||||||
@@ -116,17 +123,32 @@ export function useBotInviteDestinations(enabled: boolean, rawPermissions: strin
|
|||||||
const [rawGuilds, setRawGuilds] = useState<ReadonlyArray<GuildSummary>>([]);
|
const [rawGuilds, setRawGuilds] = useState<ReadonlyArray<GuildSummary>>([]);
|
||||||
const [rawChannels, setRawChannels] = useState<ReadonlyArray<ChannelResponse>>([]);
|
const [rawChannels, setRawChannels] = useState<ReadonlyArray<ChannelResponse>>([]);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
const [revision, setRevision] = useState(0);
|
||||||
|
const loadedAccountKeyRef = useRef<string | null>(null);
|
||||||
|
useEffect(() => {
|
||||||
|
if (!revalidate) return;
|
||||||
|
const bumpRevision = () => setRevision((value) => value + 1);
|
||||||
|
bumpRevision();
|
||||||
|
window.addEventListener('focus', bumpRevision);
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('focus', bumpRevision);
|
||||||
|
};
|
||||||
|
}, [revalidate]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
|
loadedAccountKeyRef.current = null;
|
||||||
setStatus('idle');
|
setStatus('idle');
|
||||||
setRawGuilds([]);
|
setRawGuilds([]);
|
||||||
setRawChannels([]);
|
setRawChannels([]);
|
||||||
setError(null);
|
setError(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let cancelled = false;
|
if (loadedAccountKeyRef.current !== currentAccountKey) {
|
||||||
setStatus('loading');
|
setStatus('loading');
|
||||||
setError(null);
|
setError(null);
|
||||||
|
}
|
||||||
|
if (!accountWorkAdmitted) return;
|
||||||
|
let cancelled = false;
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const [guildsResp, channelsResp] = await Promise.all([
|
const [guildsResp, channelsResp] = await Promise.all([
|
||||||
@@ -136,10 +158,13 @@ export function useBotInviteDestinations(enabled: boolean, rawPermissions: strin
|
|||||||
if (cancelled) return;
|
if (cancelled) return;
|
||||||
setRawGuilds(guildsResp.body);
|
setRawGuilds(guildsResp.body);
|
||||||
setRawChannels(channelsResp.body.filter((channel) => channel.type === ChannelTypes.GROUP_DM));
|
setRawChannels(channelsResp.body.filter((channel) => channel.type === ChannelTypes.GROUP_DM));
|
||||||
|
loadedAccountKeyRef.current = currentAccountKey;
|
||||||
|
setError(null);
|
||||||
setStatus('ready');
|
setStatus('ready');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (cancelled) return;
|
if (cancelled || isAccountTransitionAbortError(err)) return;
|
||||||
logger.error('Failed to fetch bot invite destinations', err);
|
logger.error('Failed to fetch bot invite destinations', err);
|
||||||
|
loadedAccountKeyRef.current = null;
|
||||||
setError(failureMessage(err) ?? i18nRef.current._(FAILED_TO_LOAD_INVITE_DESTINATIONS_DESCRIPTOR));
|
setError(failureMessage(err) ?? i18nRef.current._(FAILED_TO_LOAD_INVITE_DESTINATIONS_DESCRIPTOR));
|
||||||
setRawGuilds([]);
|
setRawGuilds([]);
|
||||||
setRawChannels([]);
|
setRawChannels([]);
|
||||||
@@ -149,7 +174,7 @@ export function useBotInviteDestinations(enabled: boolean, rawPermissions: strin
|
|||||||
return () => {
|
return () => {
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
};
|
};
|
||||||
}, [enabled, currentAccountKey]);
|
}, [enabled, currentAccountKey, accountWorkAdmitted, revision]);
|
||||||
const guilds = useMemo<ReadonlyArray<GuildWithPermissions>>(
|
const guilds = useMemo<ReadonlyArray<GuildWithPermissions>>(
|
||||||
() => mapBotGuilds(rawGuilds, requestedPermissions, i18n._(UNKNOWN_COMMUNITY_DESCRIPTOR)),
|
() => mapBotGuilds(rawGuilds, requestedPermissions, i18n._(UNKNOWN_COMMUNITY_DESCRIPTOR)),
|
||||||
[rawGuilds, requestedPermissions, i18n.locale],
|
[rawGuilds, requestedPermissions, i18n.locale],
|
||||||
|
|||||||
+7
-3
@@ -8,6 +8,8 @@ import {
|
|||||||
} from '@app/features/auth/components/pages/oauth_authorize_page/OAuthAuthorizePageShared';
|
} from '@app/features/auth/components/pages/oauth_authorize_page/OAuthAuthorizePageShared';
|
||||||
import accountStorage from '@app/features/auth/state/AccountStorage';
|
import accountStorage from '@app/features/auth/state/AccountStorage';
|
||||||
import Accounts from '@app/features/auth/state/Accounts';
|
import Accounts from '@app/features/auth/state/Accounts';
|
||||||
|
import {AccountScopedWork} from '@app/features/platform/state/AccountScopedWork';
|
||||||
|
import {isAccountTransitionAbortError} from '@app/features/platform/state/AccountTransitionAbort';
|
||||||
import {http} from '@app/features/platform/transport/RestTransport';
|
import {http} from '@app/features/platform/transport/RestTransport';
|
||||||
import {HttpError} from '@app/features/platform/types/EndpointError';
|
import {HttpError} from '@app/features/platform/types/EndpointError';
|
||||||
import {useEffect, useState} from 'react';
|
import {useEffect, useState} from 'react';
|
||||||
@@ -23,6 +25,7 @@ export interface PublicAppState {
|
|||||||
export function useOAuthPublicApp(clientId: string | null): PublicAppState {
|
export function useOAuthPublicApp(clientId: string | null): PublicAppState {
|
||||||
const currentUserId = Accounts.currentUserId;
|
const currentUserId = Accounts.currentUserId;
|
||||||
const currentAccountKey = Accounts.currentAccountKey;
|
const currentAccountKey = Accounts.currentAccountKey;
|
||||||
|
const accountWorkAdmitted = !AccountScopedWork.isSuspended;
|
||||||
const [state, setState] = useState<PublicAppState>(() => ({
|
const [state, setState] = useState<PublicAppState>(() => ({
|
||||||
status: clientId ? 'loading' : 'idle',
|
status: clientId ? 'loading' : 'idle',
|
||||||
data: null,
|
data: null,
|
||||||
@@ -33,8 +36,9 @@ export function useOAuthPublicApp(clientId: string | null): PublicAppState {
|
|||||||
setState({status: 'idle', data: null, error: null});
|
setState({status: 'idle', data: null, error: null});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let cancelled = false;
|
|
||||||
setState({status: 'loading', data: null, error: null});
|
setState({status: 'loading', data: null, error: null});
|
||||||
|
if (!accountWorkAdmitted) return;
|
||||||
|
let cancelled = false;
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const resp = await http.get<PublicAppData>(Endpoints.OAUTH_PUBLIC_APPLICATION(clientId));
|
const resp = await http.get<PublicAppData>(Endpoints.OAUTH_PUBLIC_APPLICATION(clientId));
|
||||||
@@ -56,7 +60,7 @@ export function useOAuthPublicApp(clientId: string | null): PublicAppState {
|
|||||||
}
|
}
|
||||||
setState({status: 'ready', data: resp.body, error: null});
|
setState({status: 'ready', data: resp.body, error: null});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (cancelled) return;
|
if (cancelled || isAccountTransitionAbortError(err)) return;
|
||||||
if (err instanceof HttpError && err.status === 401) {
|
if (err instanceof HttpError && err.status === 401) {
|
||||||
logger.warn('OAuth public app fetch returned 401', err);
|
logger.warn('OAuth public app fetch returned 401', err);
|
||||||
setState({status: 'session_expired', data: null, error: err});
|
setState({status: 'session_expired', data: null, error: err});
|
||||||
@@ -69,6 +73,6 @@ export function useOAuthPublicApp(clientId: string | null): PublicAppState {
|
|||||||
return () => {
|
return () => {
|
||||||
cancelled = true;
|
cancelled = true;
|
||||||
};
|
};
|
||||||
}, [clientId, currentAccountKey, currentUserId]);
|
}, [clientId, currentAccountKey, currentUserId, accountWorkAdmitted]);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
+15
-14
@@ -185,7 +185,11 @@ export function useAuthorizeFlow(options: UseAuthorizeFlowOptions = {}): Authori
|
|||||||
const initialMissingClientId = !params;
|
const initialMissingClientId = !params;
|
||||||
const publicAppState = useOAuthPublicApp(params?.clientId ?? null);
|
const publicAppState = useOAuthPublicApp(params?.clientId ?? null);
|
||||||
const scopeSelection = useScopeSelection(scopes);
|
const scopeSelection = useScopeSelection(scopes);
|
||||||
const destinations = useBotInviteDestinations(hasBotScope, params?.permissions ?? null);
|
const destinations = useBotInviteDestinations(
|
||||||
|
hasBotScope,
|
||||||
|
params?.permissions ?? null,
|
||||||
|
phase.kind === 'review' && phase.step === 'community',
|
||||||
|
);
|
||||||
const selectedDestinationTarget = parseBotInviteDestinationKey(selectedDestinationKey);
|
const selectedDestinationTarget = parseBotInviteDestinationKey(selectedDestinationKey);
|
||||||
const selectedGuildId = selectedDestinationTarget?.kind === 'guild' ? selectedDestinationTarget.id : null;
|
const selectedGuildId = selectedDestinationTarget?.kind === 'guild' ? selectedDestinationTarget.id : null;
|
||||||
const permissionSelection = usePermissionSelection(
|
const permissionSelection = usePermissionSelection(
|
||||||
@@ -280,18 +284,15 @@ export function useAuthorizeFlow(options: UseAuthorizeFlowOptions = {}): Authori
|
|||||||
});
|
});
|
||||||
}, [phase.kind]);
|
}, [phase.kind]);
|
||||||
const currentAccountKey = Accounts.currentAccountKey;
|
const currentAccountKey = Accounts.currentAccountKey;
|
||||||
const destinationInitRef = useRef(false);
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
destinationInitRef.current = false;
|
|
||||||
setSelectedDestinationKey(null);
|
setSelectedDestinationKey(null);
|
||||||
}, [currentAccountKey]);
|
}, [currentAccountKey]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!hasBotScope) {
|
if (!hasBotScope) {
|
||||||
destinationInitRef.current = false;
|
|
||||||
setSelectedDestinationKey(null);
|
setSelectedDestinationKey(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (destinationInitRef.current) return;
|
if (destinations.options.some((option) => option.value === selectedDestinationKey)) return;
|
||||||
const requestedDestinationKey = params?.channelId
|
const requestedDestinationKey = params?.channelId
|
||||||
? createBotInviteDestinationKey('group_dm', params.channelId)
|
? createBotInviteDestinationKey('group_dm', params.channelId)
|
||||||
: params?.guildId
|
: params?.guildId
|
||||||
@@ -304,23 +305,23 @@ export function useAuthorizeFlow(options: UseAuthorizeFlowOptions = {}): Authori
|
|||||||
? requestedDestinationKey
|
? requestedDestinationKey
|
||||||
: null,
|
: null,
|
||||||
);
|
);
|
||||||
destinationInitRef.current = true;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (destinations.status !== 'ready') return;
|
if (destinations.status !== 'ready') return;
|
||||||
const preferredDestinationKey = preferredDestinationKeyRef.current;
|
const preferredDestinationKey = preferredDestinationKeyRef.current;
|
||||||
if (preferredDestinationKey && destinations.options.some((option) => option.value === preferredDestinationKey)) {
|
if (preferredDestinationKey && destinations.options.some((option) => option.value === preferredDestinationKey)) {
|
||||||
setSelectedDestinationKey(preferredDestinationKey);
|
setSelectedDestinationKey(preferredDestinationKey);
|
||||||
destinationInitRef.current = true;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (destinations.options.length > 0) {
|
setSelectedDestinationKey(destinations.options[0]?.value ?? null);
|
||||||
setSelectedDestinationKey(destinations.options[0].value);
|
}, [
|
||||||
destinationInitRef.current = true;
|
hasBotScope,
|
||||||
return;
|
params?.guildId,
|
||||||
}
|
params?.channelId,
|
||||||
destinationInitRef.current = true;
|
destinations.options,
|
||||||
}, [hasBotScope, params?.guildId, params?.channelId, destinations.options, destinations.status]);
|
destinations.status,
|
||||||
|
selectedDestinationKey,
|
||||||
|
]);
|
||||||
const selectedDestination = useMemo(
|
const selectedDestination = useMemo(
|
||||||
() => destinations.options.find((option) => option.value === selectedDestinationKey) ?? null,
|
() => destinations.options.find((option) => option.value === selectedDestinationKey) ?? null,
|
||||||
[destinations.options, selectedDestinationKey],
|
[destinations.options, selectedDestinationKey],
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ export interface AuthLoginLayoutProps {
|
|||||||
readonly registerLink: ReactElement<Record<string, unknown>>;
|
readonly registerLink: ReactElement<Record<string, unknown>>;
|
||||||
readonly onLoginComplete?: ((payload: LoginSuccessPayload) => Promise<void> | void) | null;
|
readonly onLoginComplete?: ((payload: LoginSuccessPayload) => Promise<void> | void) | null;
|
||||||
readonly onBackActionChange?: ((action: (() => void) | null) => void) | null;
|
readonly onBackActionChange?: ((action: (() => void) | null) => void) | null;
|
||||||
readonly completeLoginRedirectPath?: string | null;
|
readonly completeLoginRedirectPath: string | null;
|
||||||
readonly forceCredentials?: boolean;
|
readonly forceCredentials?: boolean;
|
||||||
readonly startWithAddAccount?: boolean;
|
readonly startWithAddAccount?: boolean;
|
||||||
readonly runtimeTarget: AuthRuntimeTarget;
|
readonly runtimeTarget: AuthRuntimeTarget;
|
||||||
@@ -343,15 +343,6 @@ function resolveMethodSsoAction({
|
|||||||
return {isStarting, label, onStart};
|
return {isStarting, label, onStart};
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveCompleteLoginOptions(
|
|
||||||
completeLoginRedirectPath: string | null,
|
|
||||||
): AuthenticationCommands.CompleteLoginOptions {
|
|
||||||
if (completeLoginRedirectPath == null) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return {redirectPath: completeLoginRedirectPath};
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveAuthBackAction({
|
function resolveAuthBackAction({
|
||||||
accountListBackAction,
|
accountListBackAction,
|
||||||
authLoginStep,
|
authLoginStep,
|
||||||
@@ -400,7 +391,7 @@ export const AuthLoginLayout = observer(function AuthLoginLayout({
|
|||||||
registerLink,
|
registerLink,
|
||||||
onLoginComplete = null,
|
onLoginComplete = null,
|
||||||
onBackActionChange = null,
|
onBackActionChange = null,
|
||||||
completeLoginRedirectPath = null,
|
completeLoginRedirectPath,
|
||||||
forceCredentials = false,
|
forceCredentials = false,
|
||||||
startWithAddAccount = false,
|
startWithAddAccount = false,
|
||||||
runtimeTarget,
|
runtimeTarget,
|
||||||
@@ -509,7 +500,7 @@ export const AuthLoginLayout = observer(function AuthLoginLayout({
|
|||||||
}
|
}
|
||||||
await AuthenticationCommands.completeLogin(
|
await AuthenticationCommands.completeLogin(
|
||||||
{...payload, runtimeSnapshot: requireAuthInstanceSnapshot(resolvedAuthRuntimeSnapshot)},
|
{...payload, runtimeSnapshot: requireAuthInstanceSnapshot(resolvedAuthRuntimeSnapshot)},
|
||||||
resolveCompleteLoginOptions(completeLoginRedirectPath),
|
{redirectPath: completeLoginRedirectPath},
|
||||||
);
|
);
|
||||||
if (onLoginComplete != null) {
|
if (onLoginComplete != null) {
|
||||||
await onLoginComplete(payload);
|
await onLoginComplete(payload);
|
||||||
@@ -572,7 +563,7 @@ export const AuthLoginLayout = observer(function AuthLoginLayout({
|
|||||||
);
|
);
|
||||||
const handleStoredAccountLogin = useCallback(
|
const handleStoredAccountLogin = useCallback(
|
||||||
async (payload: StoredAccountLoginPayload) => {
|
async (payload: StoredAccountLoginPayload) => {
|
||||||
await AuthenticationCommands.completeLogin(payload, resolveCompleteLoginOptions(completeLoginRedirectPath));
|
await AuthenticationCommands.completeLogin(payload, {redirectPath: completeLoginRedirectPath});
|
||||||
if (onLoginComplete != null) {
|
if (onLoginComplete != null) {
|
||||||
await onLoginComplete(payload);
|
await onLoginComplete(payload);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
|
||||||
|
import {Routes} from '@app/app/Routes';
|
||||||
import type {RuntimeConfigSnapshot} from '@app/features/app/state/InstanceSnapshotStore';
|
import type {RuntimeConfigSnapshot} from '@app/features/app/state/InstanceSnapshotStore';
|
||||||
import {usesUsernameSignIn} from '@app/features/app/utils/AccountIdentityFeatures';
|
import {usesUsernameSignIn} from '@app/features/app/utils/AccountIdentityFeatures';
|
||||||
import * as AuthenticationCommands from '@app/features/auth/commands/AuthenticationCommands';
|
import * as AuthenticationCommands from '@app/features/auth/commands/AuthenticationCommands';
|
||||||
@@ -141,7 +142,7 @@ const ResourceAuthContent = observer(function ResourceAuthContent<T>({
|
|||||||
showTitle={false}
|
showTitle={false}
|
||||||
title={null}
|
title={null}
|
||||||
onBackActionChange={null}
|
onBackActionChange={null}
|
||||||
completeLoginRedirectPath={null}
|
completeLoginRedirectPath={Routes.ME}
|
||||||
forceCredentials={false}
|
forceCredentials={false}
|
||||||
startWithAddAccount={false}
|
startWithAddAccount={false}
|
||||||
runtimeTarget={runtimeTarget}
|
runtimeTarget={runtimeTarget}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ const InviteLoginPage = observer(function InviteLoginPage({code, invite}: Invite
|
|||||||
title={null}
|
title={null}
|
||||||
onLoginComplete={runtimeTarget.reset}
|
onLoginComplete={runtimeTarget.reset}
|
||||||
onBackActionChange={null}
|
onBackActionChange={null}
|
||||||
completeLoginRedirectPath={null}
|
completeLoginRedirectPath={Routes.ME}
|
||||||
forceCredentials={false}
|
forceCredentials={false}
|
||||||
startWithAddAccount={false}
|
startWithAddAccount={false}
|
||||||
runtimeTarget={runtimeTarget}
|
runtimeTarget={runtimeTarget}
|
||||||
|
|||||||
Reference in new issue
Block a user