Commit Graph

89 Commits

Author SHA1 Message Date
Will Norris
d2fbdb005d client/web: use CSP hash for inline javascript
Calculate and set the hash of the one inline script we have in
index.html. That script is unlikely to change, so hardcoding the hash
seems fine for now.

Updates #10261
Updates tailscale/corp#16266

Signed-off-by: Will Norris <will@tailscale.com>
2023-12-11 20:22:56 -08:00
Sonia Appasamy
bc9b9e8f69 client/web: restrict using an exit node on a couple more platforms
Completed testing of the new UI on the existing platforms that use
it. From testing, QNAP, Unraid, and Home Assistant (in addition to
Synology) all do not play well with using an exit node. For now,
we're disabling this setting from the UI. CLI should be updated to
also disallow selection of an exit node from these platforms.
All platforms still allow for advertising as an exit node.

Co-authored-by: Will Norris <will@tailscale.com>

Updates #10261

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-12-11 20:14:39 -05:00
Mario Minardi
4e012794fc
client/web: add metric logging when viewing local / remote node (#10555)
Add metric logging for the case where a user is viewing a local or remote
node.

Updates https://github.com/tailscale/tailscale/issues/10261

Signed-off-by: Mario Minardi <mario@tailscale.com>
2023-12-11 13:50:15 -07:00
Mario Minardi
763b9daa84
client/web: add visual indication for exit node pending approval (#10532)
Add visual indication when running as an exit node prior to receiving
admin approval.

Updates https://github.com/tailscale/tailscale/issues/10261

Signed-off-by: Mario Minardi <mario@tailscale.com>
Co-authored-by: Sonia Appasamy <sonia@tailscale.com>
2023-12-11 13:40:29 -07:00
Will Norris
970dc2a976 client/web: remove 'unsafe-inline' from CSP
I seem to recall I needed this for things to work properly with the vite
dev server, but that doesn't seem to be the case anymore?  Everything
seems to work fine without it.  If we still have issues, we'll need to
look into using a nonce or integrity attribute.

Updates #10261
Fixes tailscale/corp#16266

Signed-off-by: Will Norris <will@tailscale.com>
2023-12-11 10:25:41 -08:00
Mario Minardi
109929d110
client/web: add endpoint for logging device detail click metric (#10505)
Add an endpoint for logging the device detail click metric to allow for
this metric to be logged without having a valid session which is the
case when in readonly mode.

Updates https://github.com/tailscale/tailscale/issues/10261

Signed-off-by: Mario Minardi <mario@tailscale.com>
2023-12-11 10:50:06 -07:00
Will Norris
5a2e6a6f7d client/web: use Home Assistant's X-Ingress-Path header
When running on Home Assistant, use the X-Ingress-Path header to set the
URLPrefix that is passed to the frontend.

Also fix handling of errNotUsingTailscale in the auth handler
(previously it falling through to a later case and returning a 500).
Instead, it's just a terminal state with no auth needed.

Also disable SSH on Home Assistant, since it causes problems on startup
and doesn't make much sense anyway for that platform.

Updates #10261

Signed-off-by: Will Norris <will@tailscale.com>
2023-12-08 16:36:21 -08:00
Will Norris
69b56462fc client/web: check content-type on PATCH requests
Updates #10261
Fixes tailscale/corp#16267

Signed-off-by: Will Norris <will@tailscale.com>
2023-12-08 16:18:18 -08:00
Will Norris
c615fe2296 client/web: add security attributes on session cookie
Limit cookies to HTTP requests (not accessible from javascript).
Set SameSite to "Lax", which is similar to "Strict" but allows for
cookies to be included in requests that come from offsite links.  This
will be necessary when we link to the web client from the admin console.

Updates #10261
Fixes tailscale/corp#16265

Signed-off-by: Will Norris <will@tailscale.com>
2023-12-08 16:18:05 -08:00
Sonia Appasamy
261b6f1e9f client/web: limit updates ui to unstable builds
The updates view still needs a final design pass, limit to unstable
track for now.

Updates #10261

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-12-08 17:57:47 -05:00
Will Norris
33de922d57 client/web: only enforce path prefix in CGI mode
The client has changed a bit since we introduced the path prefix.  It is
now used for two things:

- its original purpose, of ensuring that when the client is run in CGI
  mode at arbitrary paths, then relative paths for assets continue to
  work

- we also now pass the path to the frontend and use wouter to manage
  routes for the various subpages of the client.

When the client is run behind a reverse proxy (as it is in Home
Assistant), it is common for the proxy to rewrite the request so that
the backend application doesn't see the path it's being served at. In
this case, we don't need to call enforcePrefix, since it's already
stripped before it reaches us.  However, wouter (or react router
library) still sees the original path in the browser, and needs to know
what part of it is the prefix that needs to be stripped off.

We're handling this by now only calling enforcePrefix when run in CGI
mode. For Home Assistant, or any other platform that runs the client
behind a reverse proxy with a custom path, they will still need to pass
the `-prefix` flag to `tailscale web`, but we will only use it for route
handling in the frontend.

Updates #10261

Signed-off-by: Will Norris <will@tailscale.com>
2023-12-08 14:54:22 -08:00
Sonia Appasamy
c2319f0dfa client/web: fix serveAPIAuth in Login mode
In Login mode, must first run system auth. But once authorized,
should be able to reach rest of auth logic to check whether the
user can manage the node. This results in showing/hiding the
sign in button in the frontend login toggle.

Updates #10261

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-12-08 17:42:46 -05:00
Sonia Appasamy
7c172df791 client/web: fix 500 error after logout
Calling DebugPacketFilterRules fails when the node is not logged
in, which was causing 500 errors on the node data endpoint after
logging the node out.

Updates #10261

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-12-08 17:17:50 -05:00
Mario Minardi
21958d2934
client/web: add logging of device management type for web client (#10492)
Add logging of device management type for the web client auth flow. Namely,
this differentiates between viewing a node you do not own, viewing a local
tagged node, viewing a remote tagged node, managing a local node, and
managing a remote node.

Updates https://github.com/tailscale/tailscale/issues/10261

Signed-off-by: Mario Minardi <mario@tailscale.com>
2023-12-08 13:15:57 -07:00
Sonia Appasamy
ddb4b51122 client/web: always run platform auth for login mode
Even if connected to the login client over tailscale, still check
platform auth so the browser can obtain the tokens it needs to make
platform requests complete successfully.

Updates #10261

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-12-08 13:42:10 -05:00
Sonia Appasamy
97f8577ad2 client/web: restructure api mutations into hook
This commit makes some restructural changes to how we handle api
posting from the web client frontend.

Now that we're using SWR, we have less of a need for hooks like
useNodeData that return a useSWR response alongside some mutation
callbacks. SWR makes it easy to mutate throughout the UI without
needing access to the original data state in order to reflect
updates. So, we can fetch data without having to tie it to post
callbacks that have to be passed around through components.

In an effort to consolidate our posting endpoints, and make it
easier to add more api handlers cleanly in the future, this change
introduces a new `useAPI` hook that returns a single `api` callback
that can make any changes from any component in the UI. The hook
itself handles using SWR to mutate the relevant data keys, which
get globally reflected throughout the UI.

As a concurrent cleanup, node types are also moved to their own
types.ts file, to consolidate data types across the app.

Updates #10261

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-12-07 18:32:32 -05:00
Sonia Appasamy
a95b3cbfa8 client/web: add copyable components throughout UI
Updates the IP address on home view to open a copyable list of node
addresses on click. And makes various values on the details view
copyable text items, mirroring the machine admin panel table.

As part of these changes, pulls the AddressCard, NiceIP and QuickCopy
components from the admin panel, with the AddressCard slightly modified
to avoid needing to also pull in the CommandLine component.

A new toaster interface is also added, allowing us to display success
and failure toasts throughout the UI. The toaster code is slightly
modified from it's admin form to avoid the need for some excess
libraries.

Updates #10261

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-12-05 16:52:19 -05:00
Mario Minardi
6b083a8ddf
client/web: add metric logging logic to the web client (#10434)
Add metric logging logic for the web client frontend. This is an initial
pass of adding the base logic, plus a single point where it is used for
validation that the logging is working correctly. More metric logging
calls will follow in subsquent PRs.

Updates https://github.com/tailscale/tailscale/issues/10261

Signed-off-by: Mario Minardi <mario@tailscale.com>
2023-12-05 08:28:19 -07:00
Will Norris
f5989f317f client/web: handle offline exit nodes
If the currently selected exit node is offline, render the exit node
selector in red with an error message. Update exit nodes in the dropdown
to indicate if they are offline, and don't allow them to be selected.

This also updates some older color values to use the new colors.

Updates #10261

Signed-off-by: Will Norris <will@tailscale.com>
2023-12-04 13:31:05 -08:00
Will Norris
f9550e0bed client/web: indicate if ACLs prevent access
Use the packet filter rules to determine if any device is allowed to
connect on port 5252.  This does not check whether a specific device can
connect (since we typically don't know the source device when this is
used).  Nor does it specifically check for wide-open ACLs, which is
something we may provide a warning about in the future.

Update the login popover content to display information when the src
device is unable to connect to the dst device over its Tailscale IP. If
we know it's an ACL issue, mention that, otherwise list a couple of
things to check. In both cases, link to a placeholder URL to get more
information about web client connection issues.

Updates #10261

Signed-off-by: Will Norris <will@tailscale.com>
2023-12-01 16:51:12 -08:00
Sonia Appasamy
7a4ba609d9 client/web: show features based on platform support
Hiding/disabling UI features when not available on the running
client.

Updates #10261

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-12-01 17:01:13 -05:00
Sonia Appasamy
bcc9b44cb1 client/web: hide admin panel links for non-tailscale control servers
Updates #10261

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-11-29 16:51:46 -05:00
Sonia Appasamy
ecd1ccb917 client/web: add subnet routes view
Add UI view for mutating the node's advertised subnet routes.

Updates #10261

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-11-29 15:09:07 -05:00
Sonia Appasamy
7aa981ba49 client/web: remove duplicate WhoIs call
Fixes a TODO in web.authorizeRequest.

`getSession` calls `WhoIs` already. Call `getSession` earlier in
`authorizeRequest` so we can avoid the duplicate `WhoIs` check on
the same request.

Updates #10261

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-11-29 14:46:57 -05:00
Will Norris
42dc843a87 client/web: add advanced login options
This adds an expandable section of the login view to allow users to
specify an auth key and an alternate control URL.

Input and Collapsible components and accompanying styles were brought
over from the adminpanel.

Updates #10261

Signed-off-by: Will Norris <will@tailscale.com>
2023-11-17 18:39:02 -08:00
Sonia Appasamy
e75be017e4 client/web: add exit node selector
Add exit node selector (in full management client only) that allows
for advertising as an exit node, or selecting another exit node on
the Tailnet for use.

Updates #10261

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-11-17 16:45:33 -05:00
Will Norris
f880c77df0 client/web: split login from nodeUpdate
This creates a new /api/up endpoint which is exposed in the login
client, and is solely focused on logging in. Login has been removed from
the nodeUpdate endpoint.

This also adds support in the LoginClientView for a stopped node that
just needs to reconnect, but not necessarily reauthenticate.  This
follows the same pattern in `tailscale up` of just setting the
WantRunning user pref.

Updates tailscale/corp#14335

Signed-off-by: Will Norris <will@tailscale.com>
2023-11-17 12:12:31 -08:00
Sonia Appasamy
bd534b971a {client/web},{ipn/ipnlocal}: replace localapi debug-web-client endpoint
This change removes the existing debug-web-client localapi endpoint
and replaces it with functions passed directly to the web.ServerOpts
when constructing a web.ManageServerMode client.

The debug-web-client endpoint previously handled making noise
requests to the control server via the /machine/webclient/ endpoints.
The noise requests must be made from tailscaled, which has the noise
connection open. But, now that the full client is served from
tailscaled, we no longer need to proxy this request over the localapi.

Updates tailscale/corp#14335

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-11-16 18:32:52 -05:00
Will Norris
d01fa857b1 client/web: allow login client to still run tailscale up
I don't believe this has ever worked, since we didn't allow POST
requests in the login client. But previously, we were primarily using
the legacy client, so it didn't really matter. Now that we've removed
the legacy client, we have no way to login.

This fixes the login client, allowing it to login, but it still needs to
be refactored to expose a dedicated login method, without exposing all
the node update functionality.

Updates tailscale/corp#14335

Signed-off-by: Will Norris <will@tailscale.com>
2023-11-16 07:30:04 -08:00
Sonia Appasamy
2dbd546766 client/web: remove DebugMode from GET /api/data
No longer using this! Readonly state fully managed via auth endpoint.
Also getting rid of old Legacy server mode.

A #cleanup

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-11-15 17:18:33 -05:00
Naman Sood
d5c460e83c
client/{tailscale,web}: add initial webUI frontend for self-updates (#10191)
Updates #10187.

Signed-off-by: Naman Sood <mail@nsood.in>
2023-11-15 16:04:44 -05:00
Sonia Appasamy
7c99a1763b client/web: fix panic on logout
Fix panic due to `CurrentTailnet` being nil.

Fixes tailscale/corp#15791

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-11-14 14:35:13 -05:00
Sonia Appasamy
c9bfb7c683 client/web: add Tailscale SSH view
Updates tailscale/corp#14335

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-11-13 15:49:45 -05:00
Sonia Appasamy
86c8ab7502 client/web: add readonly/manage toggle
Updates tailscale/corp#14335

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-11-10 15:01:34 -05:00
Sonia Appasamy
d544e80fc1 client/web: populate device details view
Fills /details page with real values, passed back from the /data
endpoint.

Updates tailscale/corp#14335

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-11-08 17:59:58 -05:00
Will Norris
623f669239 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>
2023-11-07 11:13:01 -08:00
Will Norris
e537d304ef client/web: relax CSP restrictions for manage client
Don't return CSP headers in dev mode, since that includes a bunch of
extra things like the vite server.

Allow images from any source, which is needed to load user profile
images.

Allow 'unsafe-inline' for various inline scripts and style react uses.
We can eliminate this by using CSP nonce or hash values, but we'll need
to look into the best way to handle that. There appear to be several
react plugins for this, but I haven't evaluated any of them.

Updates tailscale/corp#14335

Signed-off-by: Will Norris <will@tailscale.com>
2023-11-05 01:11:21 -07:00
Will Norris
a05ab9f3bc client/web: check r.Host rather than r.URL.Host
r.URL.Host is not typically populated on server requests.

Updates tailscale/corp#14335

Signed-off-by: Will Norris <will@tailscale.com>
2023-11-03 14:55:16 -07:00
Will Norris
6b956b49e0 client/web: add some security checks for full client
Require that requests to servers in manage mode are made to the
Tailscale IP (either ipv4 or ipv6) or quad-100. Also set various
security headers on those responses.  These might be too restrictive,
but we can relax them as needed.

Allow requests to /ok (even in manage mode) with no checks. This will be
used for the connectivity check from a login client to see if the
management client is reachable.

Updates tailscale/corp#14335

Signed-off-by: Will Norris <will@tailscale.com>
2023-11-03 14:15:59 -07:00
Sonia Appasamy
e5dcf7bdde client/web: move auth session creation out of /api/auth
Splits auth session creation into two new endpoints:

/api/auth/session/new - to request a new auth session

/api/auth/session/wait - to block until user has completed auth url

Updates tailscale/corp#14335

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-11-03 15:30:04 -04:00
Sonia Appasamy
0ecfc1d5c3 client/web: fill devMode from an env var
Avoids the need to pipe a web client dev flag through the tailscaled
command.

Updates tailscale/corp#14335

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-11-02 21:51:33 -04:00
Sonia Appasamy
191e2ce719 client/web: add ServerMode to web.Server
Adds a new Mode to the web server, indicating the specific
scenario the constructed server is intended to be run in. Also
starts filling this from the cli/web and ipn/ipnlocal callers.

From cli/web this gets filled conditionally based on whether the
preview web client node cap is set. If not set, the existing
"legacy" client is served. If set, both a login/lobby and full
management client are started (in "login" and "manage" modes
respectively).

Updates tailscale/corp#14335

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-11-02 17:20:05 -04:00
Will Norris
4ce4bb6271 client/web: limit authorization checks to API calls
This completes the migration to setting up authentication state in the
client first before fetching any node data or rendering the client view.

Notable changes:
 - `authorizeRequest` is now only enforced on `/api/*` calls (with the
   exception of /api/auth, which is handled early because it's needed to
   initially setup auth, particularly for synology)
 - re-separate the App and WebClient components to ensure that auth is
   completed before moving on
 - refactor platform auth (synology and QNAP) to fit into this new
   structure. Synology no longer returns redirect for auth, but returns
   authResponse instructing the client to fetch a SynoToken

Updates tailscale/corp#14335

Signed-off-by: Will Norris <will@tailscale.com>
2023-11-02 13:01:09 -07:00
Sonia Appasamy
7a725bb4f0 client/web: move more session logic to auth.go
Updates tailscale/corp#14335

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-11-01 18:35:43 -04:00
Will Norris
e5fbe57908 web/client: update synology token from /api/auth call
When the /api/auth response indicates that synology auth is needed,
fetch the SynoToken and store it for future API calls.  This doesn't yet
update the server-side code to set the new SynoAuth field.

Updates tailscale/corp#14335

Signed-off-by: Will Norris <will@tailscale.com>
2023-11-01 14:18:40 -07:00
Will Norris
237c6c44cd 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>
2023-11-01 12:09:38 -07:00
Sonia Appasamy
32ebc03591 client/web: move session logic to auth.go
Updates tailscale/corp#14335

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-11-01 13:29:59 -04:00
Sonia Appasamy
89953b015b ipn/ipnlocal,client/web: add web client to tailscaled
Allows for serving the web interface from tailscaled, with the
ability to start and stop the server via localapi endpoints
(/web/start and /web/stop).

This will be used to run the new full management web client,
which will only be accessible over Tailscale (with an extra auth
check step over noise) from the daemon. This switch also allows
us to run the web interface as a long-lived service in environments
where the CLI version is restricted to CGI, allowing us to manage
certain auth state in memory.

ipn/ipnlocal/web is stubbed out in ipn/ipnlocal/web_stub for
ios builds to satisfy ios restriction from adding "text/template"
and "html/template" dependencies.

Updates tailscale/corp#14335

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-10-31 13:15:07 -04:00
Sonia Appasamy
93aa8a8cff client/web: allow providing logger implementation
Also report metrics in separate go routine with a 5 second timeout.

Updates tailscale/corp#14335

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-10-31 13:15:07 -04:00
Sonia Appasamy
d79e0fde9c client/web: split errTaggedSelf resp from getTailscaleBrowserSession
Previously returned errTaggedSource in the case that of any tagged
source. Now distinguishing whether the source was local or remote.
We'll be presenting the two cases with varying copy on the frontend.

Updates tailscale/corp#14335

Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
2023-10-24 16:12:07 -04:00