client/web: call /api/auth before rendering any client views
For now this is effectively a noop, since only the ManagementClientView uses the auth data. That will change soon. Updates tailscale/corp#14335 Signed-off-by: Will Norris <will@tailscale.com>
This commit is contained in:
parent
970eb5e784
commit
237c6c44cd
|
@ -4,25 +4,29 @@ import LegacyClientView from "src/components/views/legacy-client-view"
|
||||||
import LoginClientView from "src/components/views/login-client-view"
|
import LoginClientView from "src/components/views/login-client-view"
|
||||||
import ReadonlyClientView from "src/components/views/readonly-client-view"
|
import ReadonlyClientView from "src/components/views/readonly-client-view"
|
||||||
import useAuth from "src/hooks/auth"
|
import useAuth from "src/hooks/auth"
|
||||||
import useNodeData, { NodeData } from "src/hooks/node-data"
|
import useNodeData from "src/hooks/node-data"
|
||||||
import ManagementClientView from "./views/management-client-view"
|
import ManagementClientView from "./views/management-client-view"
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const { data, refreshData, updateNode } = useNodeData()
|
const { data, refreshData, updateNode } = useNodeData()
|
||||||
|
const { data: auth, loading: loadingAuth, waitOnAuth } = useAuth()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center min-w-sm max-w-lg mx-auto py-14">
|
<div className="flex flex-col items-center min-w-sm max-w-lg mx-auto py-14">
|
||||||
{!data ? (
|
{!data || loadingAuth ? (
|
||||||
<div className="text-center">Loading...</div> // TODO(sonia): add a loading view
|
<div className="text-center py-14">Loading...</div> // TODO(sonia): add a loading view
|
||||||
) : data?.Status === "NeedsLogin" || data?.Status === "NoState" ? (
|
) : data?.Status === "NeedsLogin" || data?.Status === "NoState" ? (
|
||||||
// Client not on a tailnet, render login.
|
// Client not on a tailnet, render login.
|
||||||
<LoginClientView
|
<LoginClientView
|
||||||
data={data}
|
data={data}
|
||||||
onLoginClick={() => updateNode({ Reauthenticate: true })}
|
onLoginClick={() => updateNode({ Reauthenticate: true })}
|
||||||
/>
|
/>
|
||||||
|
) : data.DebugMode === "full" && auth?.ok ? (
|
||||||
|
// Render new client interface in management mode.
|
||||||
|
<ManagementClientView {...data} />
|
||||||
) : data.DebugMode === "login" || data.DebugMode === "full" ? (
|
) : data.DebugMode === "login" || data.DebugMode === "full" ? (
|
||||||
// Render new client interface.
|
// Render new client interface in readonly mode.
|
||||||
<WebClient {...data} />
|
<ReadonlyClientView data={data} auth={auth} waitOnAuth={waitOnAuth} />
|
||||||
) : (
|
) : (
|
||||||
// Render legacy client interface.
|
// Render legacy client interface.
|
||||||
<LegacyClientView
|
<LegacyClientView
|
||||||
|
@ -31,25 +35,11 @@ export default function App() {
|
||||||
updateNode={updateNode}
|
updateNode={updateNode}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{data && <Footer licensesURL={data.LicensesURL} />}
|
{data && !loadingAuth && <Footer licensesURL={data.LicensesURL} />}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function WebClient(props: NodeData) {
|
|
||||||
const { data: auth, loading: loadingAuth, waitOnAuth } = useAuth()
|
|
||||||
|
|
||||||
if (loadingAuth) {
|
|
||||||
return <div className="text-center py-14">Loading...</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
return props.DebugMode === "full" && auth?.ok ? (
|
|
||||||
<ManagementClientView {...props} />
|
|
||||||
) : (
|
|
||||||
<ReadonlyClientView data={props} auth={auth} waitOnAuth={waitOnAuth} />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function Footer(props: { licensesURL: string; className?: string }) {
|
export function Footer(props: { licensesURL: string; className?: string }) {
|
||||||
return (
|
return (
|
||||||
<footer
|
<footer
|
||||||
|
|
|
@ -252,6 +252,11 @@ func (s *Server) serveLoginAPI(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Error(w, "invalid endpoint", http.StatusNotFound)
|
http.Error(w, "invalid endpoint", http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if r.URL.Path != "/api/auth" {
|
||||||
|
// empty JSON response until we serve auth for the login client
|
||||||
|
fmt.Fprintf(w, "{}")
|
||||||
|
return
|
||||||
|
}
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case httpm.GET:
|
case httpm.GET:
|
||||||
// TODO(soniaappasamy): we may want a minimal node data response here
|
// TODO(soniaappasamy): we may want a minimal node data response here
|
||||||
|
@ -354,8 +359,11 @@ func (s *Server) serveAPI(w http.ResponseWriter, r *http.Request) {
|
||||||
case path == "/auth":
|
case path == "/auth":
|
||||||
if s.tsDebugMode == "full" { // behind debug flag
|
if s.tsDebugMode == "full" { // behind debug flag
|
||||||
s.serveTailscaleAuth(w, r)
|
s.serveTailscaleAuth(w, r)
|
||||||
return
|
} else {
|
||||||
|
// empty JSON response until we serve auth for other modes
|
||||||
|
fmt.Fprintf(w, "{}")
|
||||||
}
|
}
|
||||||
|
return
|
||||||
case path == "/data":
|
case path == "/data":
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case httpm.GET:
|
case httpm.GET:
|
||||||
|
|
Loading…
Reference in New Issue