Skip to content

Commit f3c4cb3

Browse files
committed
fix(auth): redirect all unauthenticated paths to login page
- Rename useWorkspaceBootstrap to useBootstrap for unified bootstrap logic - Move hook from workspace actions to hooks directory - Fix auth guard to redirect any unauthenticated path to /login (not just /workspace) - Previously only /workspace was protected, now all paths except /login redirect properly This fixes the bug where setting a password but accessing via LAN would not redirect to login page.
1 parent d39f82b commit f3c4cb3

3 files changed

Lines changed: 16 additions & 16 deletions

File tree

packages/web/src/features/workspace/actions/use-workspace-bootstrap.ts renamed to packages/web/src/hooks/use-bootstrap.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@ import type { Workspace } from "@coder-studio/core";
22
import { useAtomValue, useSetAtom } from "jotai";
33
import { useEffect, useRef } from "react";
44
import { useLocation, useNavigate } from "react-router-dom";
5-
import { authEnabledAtom, connectionStatusAtom, dispatchCommandAtom } from "../../../atoms";
6-
import { authenticatedAtom } from "../../../atoms/app-ui";
5+
import { authEnabledAtom, connectionStatusAtom, dispatchCommandAtom } from "../atoms";
6+
import { authenticatedAtom } from "../atoms/app-ui";
77
import {
88
orderedWorkspacesAtom,
99
workspaceOrderAtom,
1010
workspacesAtom,
1111
workspacesLoadErrorAtom,
1212
workspacesLoadStateAtom,
13-
} from "../../../atoms/workspaces";
13+
} from "../atoms/workspaces";
1414

15-
export function useWorkspaceBootstrap() {
15+
export function useBootstrap() {
1616
const bootstrapRequestIdRef = useRef(0);
1717
const navigate = useNavigate();
1818
const location = useLocation();
@@ -32,26 +32,29 @@ export function useWorkspaceBootstrap() {
3232
return;
3333
}
3434

35-
const isProtectedWorkspaceRoute = location.pathname === "/workspace";
35+
// Auth guard: redirect to login if auth required but not authenticated
3636
const authRequired = authEnabled === true;
3737
if (authRequired && !authenticated) {
38-
if (isProtectedWorkspaceRoute) {
38+
// Allow /login path, redirect all other paths to login
39+
if (location.pathname !== "/login") {
3940
navigate("/login", { replace: true });
4041
return;
4142
}
42-
4343
return;
4444
}
4545

46+
// Redirect from login if already authenticated or auth not required
4647
if (location.pathname === "/login" && (!authRequired || authenticated)) {
4748
navigate("/", { replace: true });
4849
return;
4950
}
5051

52+
// Only bootstrap workspaces on "/" and "/workspace" paths
5153
if (location.pathname !== "/" && location.pathname !== "/workspace") {
5254
return;
5355
}
5456

57+
// Workspace bootstrap logic
5558
if (workspacesLoadState === "idle") {
5659
if (connectionStatus !== "connected") {
5760
return;
@@ -102,6 +105,7 @@ export function useWorkspaceBootstrap() {
102105
return;
103106
}
104107

108+
// Route based on workspace state
105109
if (location.pathname === "/" && workspaces.length > 0) {
106110
navigate("/workspace", { replace: true });
107111
return;

packages/web/src/shells/desktop-shell.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,30 @@ import { authEnabledAtom, connectionStatusAtom } from "../atoms";
1111
import { authenticatedAtom } from "../atoms/app-ui";
1212
import { LoginPage } from "../features/auth";
1313
import { CommandPalette } from "../features/command-palette";
14-
import { ConfigDriftBanner } from "../features/config-drift-banner";
1514
import { NotFoundPage } from "../features/not-found";
1615
import { ToastContainer } from "../features/notifications";
1716
import { SettingsPage } from "../features/settings";
1817
import { WelcomePage } from "../features/welcome";
19-
import { useWorkspaceBootstrap } from "../features/workspace/actions/use-workspace-bootstrap";
2018
import { WorkspaceDesktopView } from "../features/workspace/views/desktop/workspace-desktop-view";
2119
import { BranchQuickPick } from "../features/workspace/views/shared/branch-quick-pick";
2220
import { WorkspaceRouteGate } from "../features/workspace/views/shared/workspace-route-gate";
21+
import { useBootstrap } from "../hooks/use-bootstrap";
2322
import { ConnectionStatusBanner } from "./shared/connection-status-banner";
2423

2524
export function DesktopShell() {
26-
useWorkspaceBootstrap();
25+
useBootstrap();
2726
const authenticated = useAtomValue(authenticatedAtom);
2827
const authEnabled = useAtomValue(authEnabledAtom);
2928
const location = useLocation();
3029
const authRequired = authEnabled === true;
3130
const authUnknown = authEnabled === null;
3231
const shouldShowLogin = authRequired && !authenticated && location.pathname === "/login";
33-
const shouldShowGlobalConfigDriftBanner =
34-
!shouldShowLogin && !authUnknown && !location.pathname.startsWith("/settings");
32+
!shouldShowLogin && !authUnknown && !location.pathname.startsWith("/settings");
3533

3634
return (
3735
<div className="app">
3836
<ConnectionStatusBanner />
3937

40-
{shouldShowGlobalConfigDriftBanner && <ConfigDriftBanner />}
41-
4238
<main className="main-content">
4339
{authUnknown ? (
4440
<div className="app-loading-shell">

packages/web/src/shells/mobile-shell/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ import { NotFoundPage } from "../../features/not-found";
77
import { ToastContainer } from "../../features/notifications";
88
import { SettingsPage } from "../../features/settings";
99
import { WelcomePage } from "../../features/welcome";
10-
import { useWorkspaceBootstrap } from "../../features/workspace/actions/use-workspace-bootstrap";
1110
import { WorkspaceMobileView } from "../../features/workspace/views/mobile/workspace-mobile-view";
1211
import { BranchQuickPick } from "../../features/workspace/views/shared/branch-quick-pick";
1312
import { WorkspaceRouteGate } from "../../features/workspace/views/shared/workspace-route-gate";
13+
import { useBootstrap } from "../../hooks/use-bootstrap";
1414
import { ConnectionStatusBanner } from "../shared/connection-status-banner";
1515

1616
export function MobileShell() {
17-
useWorkspaceBootstrap();
17+
useBootstrap();
1818
const authEnabled = useAtomValue(authEnabledAtom);
1919
const authUnknown = authEnabled === null;
2020

0 commit comments

Comments
 (0)