Skip to content

Commit 3ba682b

Browse files
committed
fix: Switching to user on another instance while in a server causes lastActivePath to get set to wrong value
- Fix non-reactivity warn on app routes - Improve error handling and display during login/auth flows Signed-off-by: Pecacheu <3608878+Pecacheu@users.noreply.github.com>
1 parent e04466f commit 3ba682b

4 files changed

Lines changed: 53 additions & 54 deletions

File tree

packages/client/components/auth/src/flows/FlowHome.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,10 @@ export default function FlowHome() {
9090
<Match when={isError()}>
9191
<Show
9292
when={lifecycle.permanentError === "InvalidSession"}
93-
fallback={"an unknown error occurred"}
93+
fallback={lifecycle.permanentError || "An unknown error occurred."}
9494
>
95-
<h1>
96-
<Trans>You were logged out!</Trans>
97-
</h1>
95+
<Trans>You were logged out!</Trans>
9896
</Show>
99-
10097
<Button
10198
variant="filled"
10299
onPress={() =>

packages/client/components/client/Controller.ts

Lines changed: 46 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -182,15 +182,13 @@ class Lifecycle {
182182

183183
switch (nextState) {
184184
case State.LoggingIn:
185-
this.client.api.get("/onboard/hello").then(({ onboarding }) => {
186-
if (onboarding) {
187-
this.transition({
188-
type: TransitionType.NoUser,
189-
});
190-
} else {
191-
this.client.connect();
192-
}
193-
});
185+
this.client.api
186+
.get("/onboard/hello")
187+
.then(({ onboarding }) => {
188+
if (onboarding) this.transition({ type: TransitionType.NoUser });
189+
else this.client.connect();
190+
})
191+
.catch((e) => this.showError(e));
194192
break;
195193
case State.Connecting:
196194
case State.Reconnecting:
@@ -242,9 +240,14 @@ class Lifecycle {
242240
transition(transition: Transition) {
243241
console.debug("Received transition", transition.type);
244242

245-
if (transition.type === TransitionType.DisposeOnly) {
246-
this.dispose();
247-
return;
243+
switch (transition.type) {
244+
case TransitionType.DisposeOnly:
245+
this.dispose();
246+
return;
247+
case TransitionType.PermanentFailure:
248+
this.#permanentError = transition.error;
249+
this.#enter(State.Error);
250+
return;
248251
}
249252

250253
const currentState = this.state();
@@ -281,11 +284,6 @@ class Lifecycle {
281284
case TransitionType.NoUser:
282285
this.#enter(State.Onboarding);
283286
break;
284-
case TransitionType.PermanentFailure:
285-
case TransitionType.TemporaryFailure:
286-
// TODO: relay error
287-
this.#enter(State.Error);
288-
break;
289287
}
290288
break;
291289
case State.Onboarding:
@@ -310,10 +308,6 @@ class Lifecycle {
310308
case TransitionType.TemporaryFailure:
311309
this.#enter(State.Disconnected);
312310
break;
313-
case TransitionType.PermanentFailure:
314-
this.#permanentError = transition.error;
315-
this.#enter(State.Error);
316-
break;
317311
case TransitionType.Logout:
318312
this.#enter(State.Dispose);
319313
break;
@@ -350,10 +344,6 @@ class Lifecycle {
350344
case TransitionType.TemporaryFailure:
351345
this.#enter(State.Disconnected);
352346
break;
353-
case TransitionType.PermanentFailure:
354-
// TODO: relay error
355-
this.#enter(State.Error);
356-
break;
357347
case TransitionType.Logout:
358348
this.#enter(State.Dispose);
359349
break;
@@ -405,21 +395,13 @@ class Lifecycle {
405395
case ConnectionState.Disconnected:
406396
if (this.client.events.lastError) {
407397
if (this.client.events.lastError.type === "revolt") {
408-
// if (this.client.events.lastError.data.type == 'InvalidSession') {
409-
410-
this.transition({
411-
type: TransitionType.PermanentFailure,
412-
error: this.client.events.lastError.data.type,
413-
});
414-
398+
this.showError(this.client.events.lastError.data.type);
415399
break;
416400
}
417401
}
418-
419402
this.transition({
420403
type: TransitionType.TemporaryFailure,
421404
});
422-
423405
break;
424406
}
425407
}
@@ -430,6 +412,14 @@ class Lifecycle {
430412
get permanentError() {
431413
return this.#permanentError!;
432414
}
415+
416+
/** Redirect to client error page */
417+
showError(e: string) {
418+
this.transition({
419+
type: TransitionType.PermanentFailure,
420+
error: e,
421+
});
422+
}
433423
}
434424

435425
/**
@@ -474,6 +464,7 @@ export default class ClientController {
474464
this.selectUsername = this.selectUsername.bind(this);
475465
this.isLoggedIn = this.isLoggedIn.bind(this);
476466
this.isError = this.isError.bind(this);
467+
this.isSwapping = this.isSwapping.bind(this);
477468

478469
this.loginCached(false, true);
479470
}
@@ -572,9 +563,7 @@ export default class ClientController {
572563
}
573564

574565
if (session.result === "Disabled") {
575-
// TODO
576-
alert("Account is disabled, run special logic here.");
577-
return;
566+
return this.lifecycle.showError("This account is disabled.");
578567
}
579568

580569
const createdSession = {
@@ -631,7 +620,7 @@ export default class ClientController {
631620
for (let i = sl.length - 1; i >= 0; --i)
632621
if ((sl[i].host || DefaultHost) === host) {
633622
console.log("SES SWAP TO BETTER FIT", sl[i]);
634-
this.state.auth.swapSession(sl[i].userId);
623+
this.#swapSession(sl[i].userId);
635624
this.lifecycle.transition({
636625
type: TransitionType.LoginCached,
637626
session: this.state.auth.getSession()!,
@@ -651,10 +640,27 @@ export default class ClientController {
651640
}
652641
}
653642

643+
#swapping = false;
644+
645+
/** True if the user session is about to be swapped */
646+
isSwapping() {
647+
return this.#swapping;
648+
}
649+
650+
#swapSession(userId: string) {
651+
try {
652+
this.#cacheUserInfo();
653+
this.#swapping = true;
654+
this.state.auth.swapSession(userId);
655+
} catch (e) {
656+
this.#swapping = false;
657+
throw e;
658+
}
659+
}
660+
654661
swapAccount(userId: string) {
655662
console.log("AUTH swapAccount", userId);
656-
this.#cacheUserInfo();
657-
this.state.auth.swapSession(userId);
663+
this.#swapSession(userId);
658664
if (this.#checkSwapInstance(false)) return;
659665
this.lifecycle.transition({
660666
type: TransitionType.Logout,

packages/client/src/Interface.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ const Interface = (props: { children: JSX.Element }) => {
2424
const state = useState();
2525
const client = useClient();
2626
const { openModal } = useModals();
27-
const { isLoggedIn, lifecycle } = useClientLifecycle();
27+
const { isLoggedIn, isSwapping, lifecycle } = useClientLifecycle();
2828
const { pathname } = useLocation();
2929

3030
useBeforeLeave((e) => {
31-
if (!e.defaultPrevented) {
31+
if (!e.defaultPrevented && !isSwapping()) {
3232
if (e.to === "/settings") {
3333
e.preventDefault();
3434
openModal({

packages/client/src/index.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,6 @@ function BotRedirect() {
111111

112112
function MountContext(props: { children?: JSX.Element }) {
113113
const state = useState();
114-
115-
/**
116-
* Tanstack Query client
117-
*/
118114
const client = new QueryClient();
119115

120116
return (
@@ -140,7 +136,7 @@ function MountContext(props: { children?: JSX.Element }) {
140136
);
141137
}
142138

143-
const routes = (
139+
const routes = () => (
144140
<>
145141
<Route component={StateContext}>
146142
<Route component={MountContext}>
@@ -181,10 +177,10 @@ render(
181177
<>
182178
<Router>
183179
<Route path="/i/:host" component={InstanceContext}>
184-
{routes}
180+
{routes()}
185181
</Route>
186182
<Route path="/" component={InstanceContext}>
187-
{routes}
183+
{routes()}
188184
</Route>
189185
</Router>
190186
{/* <ReportBug /> */}

0 commit comments

Comments
 (0)