diff --git a/.github/workflows/jsr-publish.yml b/.github/workflows/jsr-publish.yml index 578212b..e3182ad 100644 --- a/.github/workflows/jsr-publish.yml +++ b/.github/workflows/jsr-publish.yml @@ -22,4 +22,5 @@ jobs: run: | bun install bun run build + bunx kksh verify --publish bunx jsr publish --allow-slow-types diff --git a/README.md b/README.md index a23bbd2..47cb860 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,9 @@ ``` - Windows ```powershell - $_, $ssid = ((netsh wlan show interface | findstr "Profile" | findstr /v "mode") -split ":",2).trim(); - $_, $pass = ((netsh wlan show profile name=$ssid key=clear | findstr Key) -split ":").trim(); + (((netsh wlan show profiles | findstr "Profile") -split ":",2) | findstr /v "Profile").trim(); # find all wifi ssid + $_, $ssid = ((netsh wlan show interface | findstr "Profile" | findstr /v "mode") -split ":",2).trim(); # find current wifi ssid + $_, $pass = ((netsh wlan show profile name=$ssid key=clear | findstr Key) -split ":").trim(); # find current wifi password ``` - Linux ```bash diff --git a/jsr.json b/jsr.json index a05a5a8..98059fc 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@kunkun/kunkun-ext-wifi-password", - "version": "0.1.5", + "version": "0.1.7", "license": "MIT", "exports": "./mod.ts", "publish": { diff --git a/package.json b/package.json index b4f95c8..e7288fa 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "$schema": "https://schema.kunkun.sh", "name": "kunkun-ext-wifi-password", "license": "MIT", - "version": "0.1.5", + "version": "0.1.7", "type": "module", "kunkun": { "name": "Wifi Password", @@ -35,6 +35,38 @@ "-w" ] } + }, + { + "cmd": { + "program": "netsh", + "args": [ + "wlan", + "show", + "profiles" + ] + } + }, + { + "cmd": { + "program": "netsh", + "args": [ + "wlan", + "show", + "interfaces" + ] + } + }, + { + "cmd": { + "program": "netsh", + "args": [ + "wlan", + "show", + "profile", + "name=.+", + "key=clear" + ] + } } ] } diff --git a/src/index.ts b/src/index.ts index 34f8a03..0dbad23 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,99 +1,164 @@ import { - Action, - clipboard, - expose, - Form, - fs, - Icon, - IconEnum, - List, - Markdown, - os, - path, - shell, - toast, - ui, - WorkerExtension -} from "@kksh/api/ui/worker" -import qrcode from "qrcode" + Action, + clipboard, + expose, + Form, + fs, + Icon, + IconEnum, + List, + Markdown, + os, + path, + shell, + toast, + ui, + WorkerExtension, +} from "@kksh/api/ui/worker"; +import qrcode from "qrcode"; -class ExtensionTemplate extends WorkerExtension { - networks: string[] = [] +async function windowsGetCurrentWifiSsid() { + const cmd = shell.createCommand("netsh", ["wlan", "show", "interfaces"]); + const result = await cmd.execute(); + if (result.code !== 0) { + return undefined; + } + const lines = result.stdout.split("\n"); + const ssid = lines.find((line) => line.includes("SSID")); + return ssid ? ssid.split(":")[1].trim() : undefined; +} - get listItems() { - return this.networks.map( - (x) => - new List.Item({ - title: x, - value: x, - icon: new Icon({ - type: IconEnum.Iconify, - value: "mdi:wifi" - }) - }) - ) - } +async function windowsGetWifiPassword(ssid: string) { + const cmd = shell.createCommand("netsh", [ + "wlan", + "show", + "profile", + "name=" + ssid, + "key=clear", + ]); + const result = await cmd.execute(); + if (result.code !== 0) { + return undefined; + } + return result.stdout + .split("\n") + .find((line) => line.includes("Key Content")) + ?.split(":")[1] + .trim(); +} - async load() { - ui.setSearchBarPlaceholder("Search for wifi and press enter to get password") - const platform = await os.platform() - if (platform === "macos") { - const cmd = shell.createCommand("networksetup", ["-listpreferredwirelessnetworks", "en0"]) - const result = await cmd.execute() - if (result.code !== 0) { - toast.error("Failed to get wifi password") - return - } - this.networks = result.stdout - .trim() - .split("\n") - .slice(1) - .map((x) => x.trim()) - } - return ui.render( - new List.List({ - items: this.listItems - }) - ) - } +async function windowsGetWifiSsids() { + const cmd = shell.createCommand("netsh", ["wlan", "show", "profiles"]); + const result = await cmd.execute(); + if (result.code !== 0) { + return undefined; + } + return result.stdout + .split("\n") + .filter((line) => line.includes("User Profile")) + .map((line) => line.split(":")[1].trim()); +} - async onListItemSelected(ssid: string): Promise { - ui.render( - new List.List({ - inherits: ["items"], - detail: undefined - }) - ) - const cmd = shell.createCommand("security", [ - "find-generic-password", - "-D", - `AirPort network password`, - "-a", - ssid, - "-w" - ]) - const result = await cmd.execute() - if (result.code !== 0) { - console.log(result.stderr) - toast.error("Failed to get wifi password") - return - } - const wifiPassword = result.stdout.trim() - toast.success(`Wifi password: ${wifiPassword}, written to clipboard`) - clipboard.writeText(wifiPassword) - const wifiConnectUrl = `WIFI:S:${ssid};T:WPA;P:${wifiPassword};;` - let qrcodeSvg: string | undefined - try { - qrcodeSvg = await qrcode.toString(wifiConnectUrl) - } catch (error) { - toast.error(`Failed to generate QR code: ${error}`) - console.error(error) - } - // - if (!qrcodeSvg) { - return toast.error("Failed to generate QR code") - } - const markdown = ` +class ListWifiPasswords extends WorkerExtension { + networks: string[] = []; + currentWifiPassword: string | undefined; + + get listItems() { + return this.networks.map( + (x) => + new List.Item({ + title: x, + value: x, + icon: new Icon({ + type: IconEnum.Iconify, + value: "mdi:wifi", + hexColor: this.currentWifiPassword === x ? "#ff0" : undefined, + }), + }) + ); + } + + async load() { + ui.setSearchBarPlaceholder( + "Search for wifi and press enter to get password" + ); + const platform = await os.platform(); + if (platform === "macos") { + const cmd = shell.createCommand("networksetup", [ + "-listpreferredwirelessnetworks", + "en0", + ]); + const result = await cmd.execute(); + if (result.code !== 0) { + toast.error("Failed to get wifi password"); + return; + } + this.networks = result.stdout + .trim() + .split("\n") + .slice(1) + .map((x) => x.trim()); + } else if (platform === "windows") { + this.currentWifiPassword = await windowsGetCurrentWifiSsid(); + this.networks = (await windowsGetWifiSsids()) ?? []; + } else if (platform === "linux") { + } + return ui.render( + new List.List({ + items: this.listItems, + }) + ); + } + + async onListItemSelected(ssid: string): Promise { + const platform = await os.platform(); + ui.render( + new List.List({ + inherits: ["items"], + detail: undefined, + }) + ); + let wifiPassword: string | undefined; + if (platform === "macos") { + const cmd = shell.createCommand("security", [ + "find-generic-password", + "-D", + `AirPort network password`, + "-a", + ssid, + "-w", + ]); + const result = await cmd.execute(); + if (result.code !== 0) { + console.log(result.stderr); + toast.error("Failed to get wifi password"); + return; + } + wifiPassword = result.stdout.trim(); + } else if (platform === "windows") { + wifiPassword = await windowsGetWifiPassword(ssid); + } + + if (!wifiPassword) { + toast.error("Failed to get wifi password"); + return; + } + + toast.success(`Wifi password: ${wifiPassword}, written to clipboard`); + clipboard.writeText(wifiPassword); + const wifiConnectUrl = `WIFI:S:${ssid};T:WPA;P:${wifiPassword};;`; + let qrcodeSvg: string | undefined; + try { + qrcodeSvg = await qrcode.toString(wifiConnectUrl); + } catch (error) { + toast.error(`Failed to generate QR code: ${error}`); + console.error(error); + } + // + if (!qrcodeSvg) { + return toast.error("Failed to generate QR code"); + } + const markdown = `
${qrcodeSvg} @@ -101,17 +166,17 @@ class ExtensionTemplate extends WorkerExtension {

Wifi Password: ${wifiPassword}

Connect URL: ${wifiConnectUrl}

-` - return ui.render( - new List.List({ - inherits: ["items"], - detail: new List.ItemDetail({ - width: 60, - children: [new Markdown(markdown)] - }) - }) - ) - } +`; + return ui.render( + new List.List({ + inherits: ["items"], + detail: new List.ItemDetail({ + width: 60, + children: [new Markdown(markdown)], + }), + }) + ); + } } -expose(new ExtensionTemplate()) +expose(new ListWifiPasswords());