client/web: fix redirect logic when accessing login client over TS IP

Was previously failing to redirect to the manage client when accessing
the login client with the Tailscale IP.

Updates #10261
Fixes tailscale/corp#16348

Co-authored-by: Will Norris <will@tailscale.com>
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
pull/10583/head
Sonia Appasamy 12 months ago committed by Sonia Appasamy
parent 869b34ddeb
commit 4fb679d9cd

@ -125,7 +125,7 @@ function LoginPopoverContent({
useEffect(() => checkTSConnection(), []) useEffect(() => checkTSConnection(), [])
const handleSignInClick = useCallback(() => { const handleSignInClick = useCallback(() => {
if (auth.viewerIdentity) { if (auth.viewerIdentity && auth.serverMode === "manage") {
if (window.self !== window.top) { if (window.self !== window.top) {
// if we're inside an iframe, start session in new window // if we're inside an iframe, start session in new window
let url = new URL(window.location.href) let url = new URL(window.location.href)
@ -145,7 +145,7 @@ function LoginPopoverContent({
window.location.href = manageURL window.location.href = manageURL
} }
} }
}, [node.IPv4, auth.viewerIdentity, newSession]) }, [auth.viewerIdentity, auth.serverMode, newSession, node.IPv4])
return ( return (
<div onMouseEnter={!canConnectOverTS ? checkTSConnection : undefined}> <div onMouseEnter={!canConnectOverTS ? checkTSConnection : undefined}>

@ -12,6 +12,7 @@ export enum AuthType {
export type AuthResponse = { export type AuthResponse = {
authNeeded?: AuthType authNeeded?: AuthType
canManageNode: boolean canManageNode: boolean
serverMode: "login" | "manage"
viewerIdentity?: { viewerIdentity?: {
loginName: string loginName: string
nodeName: string nodeName: string

@ -396,6 +396,7 @@ type authResponse struct {
AuthNeeded authType `json:"authNeeded,omitempty"` // filled when user needs to complete a specific type of auth AuthNeeded authType `json:"authNeeded,omitempty"` // filled when user needs to complete a specific type of auth
CanManageNode bool `json:"canManageNode"` CanManageNode bool `json:"canManageNode"`
ViewerIdentity *viewerIdentity `json:"viewerIdentity,omitempty"` ViewerIdentity *viewerIdentity `json:"viewerIdentity,omitempty"`
ServerMode ServerMode `json:"serverMode"`
} }
// viewerIdentity is the Tailscale identity of the source node // viewerIdentity is the Tailscale identity of the source node
@ -411,6 +412,7 @@ type viewerIdentity struct {
// and returns an authResponse indicating the current auth state and any steps the user needs to take. // and returns an authResponse indicating the current auth state and any steps the user needs to take.
func (s *Server) serveAPIAuth(w http.ResponseWriter, r *http.Request) { func (s *Server) serveAPIAuth(w http.ResponseWriter, r *http.Request) {
var resp authResponse var resp authResponse
resp.ServerMode = s.mode
session, whois, status, sErr := s.getSession(r) session, whois, status, sErr := s.getSession(r)
if whois != nil { if whois != nil {

@ -523,7 +523,7 @@ func TestServeAuth(t *testing.T) {
name: "no-session", name: "no-session",
path: "/api/auth", path: "/api/auth",
wantStatus: http.StatusOK, wantStatus: http.StatusOK,
wantResp: &authResponse{AuthNeeded: tailscaleAuth, ViewerIdentity: vi}, wantResp: &authResponse{AuthNeeded: tailscaleAuth, ViewerIdentity: vi, ServerMode: ManageServerMode},
wantNewCookie: false, wantNewCookie: false,
wantSession: nil, wantSession: nil,
}, },
@ -548,7 +548,7 @@ func TestServeAuth(t *testing.T) {
path: "/api/auth", path: "/api/auth",
cookie: successCookie, cookie: successCookie,
wantStatus: http.StatusOK, wantStatus: http.StatusOK,
wantResp: &authResponse{AuthNeeded: tailscaleAuth, ViewerIdentity: vi}, wantResp: &authResponse{AuthNeeded: tailscaleAuth, ViewerIdentity: vi, ServerMode: ManageServerMode},
wantSession: &browserSession{ wantSession: &browserSession{
ID: successCookie, ID: successCookie,
SrcNode: remoteNode.Node.ID, SrcNode: remoteNode.Node.ID,
@ -596,7 +596,7 @@ func TestServeAuth(t *testing.T) {
path: "/api/auth", path: "/api/auth",
cookie: successCookie, cookie: successCookie,
wantStatus: http.StatusOK, wantStatus: http.StatusOK,
wantResp: &authResponse{CanManageNode: true, ViewerIdentity: vi}, wantResp: &authResponse{CanManageNode: true, ViewerIdentity: vi, ServerMode: ManageServerMode},
wantSession: &browserSession{ wantSession: &browserSession{
ID: successCookie, ID: successCookie,
SrcNode: remoteNode.Node.ID, SrcNode: remoteNode.Node.ID,

Loading…
Cancel
Save