diff --git a/@types/tailscale/index.d.ts b/@types/tailscale/index.d.ts deleted file mode 100644 index e69de29..0000000 diff --git a/src/app.tsx b/src/app.tsx index 678dec0..4d9ed78 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,22 +1,28 @@ import React from 'react'; + +import { TailscaleBackendState, TailscaleStatusResponse, TailscaleUpResponse } from './types'; import { Card, CardTitle, CardBody } from '@patternfly/react-core'; type ApplicationProps = { } type ApplicationState = { - response: string + Status: TailscaleStatusResponse } + + export class Application extends React.Component { state: ApplicationState = { - response: "" + Status: null } + constructor(props: ApplicationProps) { super(props); - cockpit.spawn(['tailscale', 'status']).done(content => { - this.setState(state => ({response: content.trim()})); + cockpit.spawn(['tailscale', 'status', '--json']).done(content => { + const status: TailscaleStatusResponse = JSON.parse(content) + this.setState(state => ({Status: status})); }); } @@ -26,7 +32,11 @@ export class Application extends React.ComponentTailscale
-		        { this.state.response }
+                {
+                    this.state.Status != null
+                        ? this.state.Status.Self.TailscaleIPs[0]
+                        : 

Loading...

+ }
diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..d99f262 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,45 @@ +// BackendState +// Keep in sync with https://github.com/tailscale/tailscale/blob/main/ipn/backend.go +export type TailscaleBackendState = + | 'NoState' + | 'NeedsMachineAuth' + | 'NeedsLogin' + | 'InUseOtherUser' + | 'Stopped' + | 'Starting' + | 'Running'; + +export type TailscaleStatusResponse = { + BackendState: TailscaleBackendState; + AuthURL: string; + Self: { + ID: string; + UserID: number; + HostName: string; + DNSName: string; + OS: string; + TailscaleIPs: string[]; + Capabilities: string[]; + Online: boolean + }; + User: Record | null; + CurrentTailnet: { + Name: string; + MagicDNSSuffix: string; + MagicDNSEnabled: boolean; + } | null; +}; + +export type TailscaleUser = { + ID: number; + LoginName: string; + DisplayName: string; + ProfilePicURL: string; + Roles: string[]; +}; + +export type TailscaleUpResponse = { + BackendState: TailscaleBackendState; + AuthURL?: string; // e.g. https://login.tailscale.com/a/0123456789abcdef + QR?: string; // a DataURL-encoded QR code PNG of the AuthURL +}; \ No newline at end of file