summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorWill Norris <will@tailscale.com>2023-11-07 11:11:33 -0800
committerWill Norris <will@willnorris.com>2023-11-07 11:13:01 -0800
commit623f669239a3efd18914fefaaa488450df48fb06 (patch)
treeca48ac6037b20e6439015ac9ccc5577a08e3bebe
parent0753ad6cf8a060896e80195f6050af45221e4c64 (diff)
downloadtailscale-623f669239a3efd18914fefaaa488450df48fb06.tar.xz
tailscale-623f669239a3efd18914fefaaa488450df48fb06.zip
client/web: pass URL prefix to frontend
This allows wouter to route URLs properly when running in CGI mode. Updates tailscale/corp#14335 Signed-off-by: Will Norris <will@tailscale.com>
-rw-r--r--client/web/src/components/app.tsx52
-rw-r--r--client/web/src/hooks/node-data.ts1
-rw-r--r--client/web/web.go2
3 files changed, 30 insertions, 25 deletions
diff --git a/client/web/src/components/app.tsx b/client/web/src/components/app.tsx
index aefa81a7d..41f5e5c2e 100644
--- a/client/web/src/components/app.tsx
+++ b/client/web/src/components/app.tsx
@@ -8,7 +8,7 @@ import useAuth, { AuthResponse } from "src/hooks/auth"
import useNodeData, { NodeData, NodeUpdate } from "src/hooks/node-data"
import { ReactComponent as TailscaleIcon } from "src/icons/tailscale-icon.svg"
import ProfilePic from "src/ui/profile-pic"
-import { Link, Route, Switch, useLocation } from "wouter"
+import { Link, Route, Router, Switch, useLocation } from "wouter"
import DeviceDetailsView from "./views/device-details-view"
export default function App() {
@@ -46,30 +46,32 @@ function WebClient({
{/* TODO(sonia): get rid of the conditions here once full/readonly
* views live on same components */}
{data.DebugMode === "full" && auth?.ok && <Header node={data} />}
- <Switch>
- <Route path="/">
- <HomeView
- auth={auth}
- data={data}
- newSession={newSession}
- refreshData={refreshData}
- updateNode={updateNode}
- />
- </Route>
- {data.DebugMode !== "" && (
- <>
- <Route path="/details">
- <DeviceDetailsView node={data} />
- </Route>
- <Route path="/subnets">{/* TODO */}Subnet router</Route>
- <Route path="/ssh">{/* TODO */}Tailscale SSH server</Route>
- <Route path="/serve">{/* TODO */}Share local content</Route>
- </>
- )}
- <Route>
- <h2 className="mt-8">Page not found</h2>
- </Route>
- </Switch>
+ <Router base={data.URLPrefix}>
+ <Switch>
+ <Route path="/">
+ <HomeView
+ auth={auth}
+ data={data}
+ newSession={newSession}
+ refreshData={refreshData}
+ updateNode={updateNode}
+ />
+ </Route>
+ {data.DebugMode !== "" && (
+ <>
+ <Route path="/details">
+ <DeviceDetailsView node={data} />
+ </Route>
+ <Route path="/subnets">{/* TODO */}Subnet router</Route>
+ <Route path="/ssh">{/* TODO */}Tailscale SSH server</Route>
+ <Route path="/serve">{/* TODO */}Share local content</Route>
+ </>
+ )}
+ <Route>
+ <h2 className="mt-8">Page not found</h2>
+ </Route>
+ </Switch>
+ </Router>
</>
)
}
diff --git a/client/web/src/hooks/node-data.ts b/client/web/src/hooks/node-data.ts
index 613f72d39..73657a19f 100644
--- a/client/web/src/hooks/node-data.ts
+++ b/client/web/src/hooks/node-data.ts
@@ -15,6 +15,7 @@ export type NodeData = {
IsUnraid: boolean
UnraidToken: string
IPNVersion: string
+ URLPrefix: string
DebugMode: "" | "login" | "full" // empty when not running in any debug mode
}
diff --git a/client/web/web.go b/client/web/web.go
index f81282af2..271b648ea 100644
--- a/client/web/web.go
+++ b/client/web/web.go
@@ -504,6 +504,7 @@ type nodeData struct {
UnraidToken string
IPNVersion string
DebugMode string // empty when not running in any debug mode
+ URLPrefix string // if set, the URL prefix the client is served behind
}
func (s *Server) serveGetNodeData(w http.ResponseWriter, r *http.Request) {
@@ -537,6 +538,7 @@ func (s *Server) serveGetNodeData(w http.ResponseWriter, r *http.Request) {
IsUnraid: distro.Get() == distro.Unraid,
UnraidToken: os.Getenv("UNRAID_CSRF_TOKEN"),
IPNVersion: versionShort,
+ URLPrefix: strings.TrimSuffix(s.pathPrefix, "/"),
DebugMode: debugMode, // TODO(sonia,will): just pass back s.mode directly?
}
for _, r := range prefs.AdvertiseRoutes {