From 6b1d6512e5907c8d4f0b61693b51508fd3240fac Mon Sep 17 00:00:00 2001 From: Marwan Sulaiman Date: Fri, 30 Jun 2023 11:34:10 -0400 Subject: [PATCH 1/5] Make port discovery optional via settings --- README.md | 2 +- src/tailscale/cli.ts | 29 +++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c64a72a..73fb9d2 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ If the extension isn't working, we recommend following these steps to troublesho 2. Ensure that your Tailnet access controls (ACLs) are [configured to allow Tailscale Funnel](https://tailscale.com/kb/1223/tailscale-funnel/#setup) on your device. 3. Ensure that [magicDNS and HTTPS Certificates are enabled](https://tailscale.com/kb/1153/enabling-https/) on your tailnet. 4. If you are running `tailscaled` in a non-default path, you can set its path via the `tailscale.socketPath` setting in VS Code. - + (Make port discovery optional via settings) ## Contribute We appreciate your help! For information on contributing to this extension, refer to the [CONTRIBUTING](CONTRIBUTING.md) document. diff --git a/src/tailscale/cli.ts b/src/tailscale/cli.ts index a4b5cb1..6a0a685 100644 --- a/src/tailscale/cli.ts +++ b/src/tailscale/cli.ts @@ -35,6 +35,7 @@ export class Tailscale { private notifyExit?: () => void; private socket?: string; private ws?: WebSocket; + private snoozing?: boolean; constructor(vscode: vscodeModule) { this._vscode = vscode; @@ -363,13 +364,30 @@ export class Tailscale { if (msg.type != 'newPort') { return; } + if (this.snoozing) { + return; + } const shouldServe = await this._vscode.window.showInformationMessage( msg.message, { modal: false }, - 'Serve' + 'Serve', + 'Snooze Notifications' ); - if (shouldServe) { + if (shouldServe === 'Serve') { await this.runFunnel(msg.port); + } else if (shouldServe === 'Snooze Notifications') { + this.snooze(); + const openSettings = await this._vscode.window.showInformationMessage( + 'Snoozed for 15 minutes. You can fully turn off port discovery in the settings', + { modal: false }, + 'Open Settings' + ); + if (openSettings) { + this._vscode.commands.executeCommand( + 'workbench.action.openSettings', + 'tailscale.portDiscovery.enabled' + ); + } } }); this._vscode.window.onDidOpenTerminal(async (e: vscode.Terminal) => { @@ -401,6 +419,13 @@ export class Tailscale { }); } + async snooze() { + this.snoozing = true; + setTimeout(() => { + this.snoozing = false; + }, 900000); // fifteen minutes + } + async runFunnel(port: number) { await this.serveAdd({ protocol: 'https', From b39abe414dc68aca888da080097b8194d302dc70 Mon Sep 17 00:00:00 2001 From: Naman Sood Date: Thu, 28 Sep 2023 12:40:18 -0400 Subject: [PATCH 2/5] store snooze timer to disk Signed-off-by: Naman Sood --- src/config-manager.ts | 1 + src/extension.ts | 4 ++-- src/tailscale/cli.ts | 26 ++++++++++++-------------- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/config-manager.ts b/src/config-manager.ts index bd9d8f3..2205b4a 100644 --- a/src/config-manager.ts +++ b/src/config-manager.ts @@ -12,6 +12,7 @@ interface Host { interface Config { defaultHost?: Host; hosts?: Record; + portDiscoSnoozeUntil?: number; } export class ConfigManager { diff --git a/src/extension.ts b/src/extension.ts index ac1daee..941a8ae 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -24,10 +24,10 @@ let tailscaleInstance: Tailscale; export async function activate(context: vscode.ExtensionContext) { vscode.commands.executeCommand('setContext', 'tailscale.env', process.env.NODE_ENV); - tailscaleInstance = await Tailscale.withInit(vscode); - const configManager = ConfigManager.withGlobalStorageUri(context.globalStorageUri); + tailscaleInstance = await Tailscale.withInit(vscode, configManager); + // walkthrough completion tailscaleInstance.serveStatus().then((status) => { // assume if we have any BackendState we are installed diff --git a/src/tailscale/cli.ts b/src/tailscale/cli.ts index 7234b87..7d187da 100644 --- a/src/tailscale/cli.ts +++ b/src/tailscale/cli.ts @@ -8,6 +8,7 @@ import * as path from 'node:path'; import { LogLevel } from 'vscode'; import { trimSuffix } from '../utils'; import { EXTENSION_NS } from '../constants'; +import { ConfigManager } from '../config-manager'; const LOG_COMPONENT = 'tsrelay'; @@ -35,14 +36,15 @@ export class Tailscale { private notifyExit?: () => void; private socket?: string; private ws?: WebSocket; - private snoozing?: boolean; + private configManager: ConfigManager; - constructor(vscode: vscodeModule) { + constructor(vscode: vscodeModule, configManager: ConfigManager) { this._vscode = vscode; + this.configManager = configManager; } - static async withInit(vscode: vscodeModule): Promise { - const ts = new Tailscale(vscode); + static async withInit(vscode: vscodeModule, configManager: ConfigManager): Promise { + const ts = new Tailscale(vscode, configManager); await ts.init(); vscode.workspace.onDidChangeConfiguration((event) => { if (event.affectsConfiguration('tailscale.portDiscovery.enabled')) { @@ -382,7 +384,8 @@ export class Tailscale { if (msg.type != 'newPort') { return; } - if (this.snoozing) { + const snoozeUntil = this.configManager.config.portDiscoSnoozeUntil; + if (snoozeUntil && snoozeUntil <= Date.now()) { return; } const shouldServe = await this._vscode.window.showInformationMessage( @@ -394,9 +397,11 @@ export class Tailscale { if (shouldServe === 'Serve') { await this.runFunnel(msg.port); } else if (shouldServe === 'Snooze Notifications') { - this.snooze(); + // one hour + const snoozeDuration = 60 * 60 * 1000; + this.configManager.set('portDiscoSnoozeUntil', Date.now() + snoozeDuration); const openSettings = await this._vscode.window.showInformationMessage( - 'Snoozed for 15 minutes. You can fully turn off port discovery in the settings', + 'Snoozed for 1 hour. You can fully turn off port discovery in the settings', { modal: false }, 'Open Settings' ); @@ -437,13 +442,6 @@ export class Tailscale { }); } - async snooze() { - this.snoozing = true; - setTimeout(() => { - this.snoozing = false; - }, 900000); // fifteen minutes - } - async runFunnel(port: number) { await this.serveAdd({ protocol: 'https', From 5f7a15df63378c72fa03f815d56c0abbf7c17e95 Mon Sep 17 00:00:00 2001 From: Naman Sood Date: Fri, 6 Oct 2023 14:58:11 -0400 Subject: [PATCH 3/5] fix sign Signed-off-by: Naman Sood --- src/tailscale/cli.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tailscale/cli.ts b/src/tailscale/cli.ts index 7d187da..522e6fd 100644 --- a/src/tailscale/cli.ts +++ b/src/tailscale/cli.ts @@ -385,7 +385,7 @@ export class Tailscale { return; } const snoozeUntil = this.configManager.config.portDiscoSnoozeUntil; - if (snoozeUntil && snoozeUntil <= Date.now()) { + if (snoozeUntil && snoozeUntil >= Date.now()) { return; } const shouldServe = await this._vscode.window.showInformationMessage( From 0fd92c306bc9e4556cb0bacb25eb728e2d8e8b60 Mon Sep 17 00:00:00 2001 From: Naman Sood Date: Fri, 6 Oct 2023 15:08:59 -0400 Subject: [PATCH 4/5] fix text content Signed-off-by: Naman Sood --- src/tailscale/cli.ts | 13 +++++++++---- tsrelay/handler/portdisco.go | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/tailscale/cli.ts b/src/tailscale/cli.ts index 522e6fd..199960d 100644 --- a/src/tailscale/cli.ts +++ b/src/tailscale/cli.ts @@ -391,12 +391,13 @@ export class Tailscale { const shouldServe = await this._vscode.window.showInformationMessage( msg.message, { modal: false }, - 'Serve', - 'Snooze Notifications' + 'Expose', + 'Not now', + 'Learn more' ); - if (shouldServe === 'Serve') { + if (shouldServe === 'Expose') { await this.runFunnel(msg.port); - } else if (shouldServe === 'Snooze Notifications') { + } else if (shouldServe === 'Not now') { // one hour const snoozeDuration = 60 * 60 * 1000; this.configManager.set('portDiscoSnoozeUntil', Date.now() + snoozeDuration); @@ -411,6 +412,10 @@ export class Tailscale { 'tailscale.portDiscovery.enabled' ); } + } else if (shouldServe === 'Learn more') { + vscode.env.openExternal( + vscode.Uri.parse('https://tailscale.com/kb/1223/tailscale-funnel/') + ); } }); this._vscode.window.onDidOpenTerminal(async (e: vscode.Terminal) => { diff --git a/tsrelay/handler/portdisco.go b/tsrelay/handler/portdisco.go index cdf7952..6199f17 100644 --- a/tsrelay/handler/portdisco.go +++ b/tsrelay/handler/portdisco.go @@ -138,7 +138,7 @@ func (h *handler) handlePortUpdates(c *websocket.Conn, up []portlist.Port) error err = c.WriteJSON(&wsMessage{ Type: "newPort", Port: int(p.Port), - Message: fmt.Sprintf("Port %d was started by %q, would you like to share it over the internet with Tailscale Funnel?", p.Port, p.Process), + Message: fmt.Sprintf("%q started using port %d. Would you like to expose this port to the internet using Tailscale Funnel?", p.Process, p.Port), }) if err != nil { h.Unlock() From 0a4b3f9dc57ef865d2e12b41f7147202e3803119 Mon Sep 17 00:00:00 2001 From: Naman Sood Date: Tue, 10 Oct 2023 15:35:50 -0400 Subject: [PATCH 5/5] fix readme error Signed-off-by: Naman Sood --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1186185..1642e44 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ If the extension isn't working, we recommend following these steps to troublesho 2. Ensure that your Tailnet access controls (ACLs) are [configured to allow Tailscale Funnel](https://tailscale.com/kb/1223/tailscale-funnel/#setup) on your device. 3. Ensure that [magicDNS and HTTPS Certificates are enabled](https://tailscale.com/kb/1153/enabling-https/) on your tailnet. 4. If you are running `tailscaled` in a non-default path, you can set its path via the `tailscale.socketPath` setting in VS Code. - (Make port discovery optional via settings) + ## Contribute We appreciate your help! For information on contributing to this extension, refer to the [CONTRIBUTING](CONTRIBUTING.md) document.