diff --git a/.env.example b/.env.example index 9ae61c9..f1a4a31 100644 --- a/.env.example +++ b/.env.example @@ -2,3 +2,4 @@ PUSHOVER_USER= PUSHOVER_TOKEN= SSH_USERNAME= SSH_PASSWORD= +ROUTER_HOSTNAME= diff --git a/package.json b/package.json index ad598dc..778ef8b 100644 --- a/package.json +++ b/package.json @@ -13,11 +13,10 @@ "dependencies": { "@hono/node-server": "^1.13.2", "hono": "^4.6.5", - "ssh2": "^1.16.0", + "node-ssh": "^13.2.0", "zod": "^3.23.8" }, "devDependencies": { - "@types/ssh2": "^1.15.1", "@biomejs/biome": "1.9.3", "@types/node": "^20.11.17", "@dotenvx/dotenvx": "^1.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 494da61..b22b838 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,9 +14,9 @@ importers: hono: specifier: ^4.6.5 version: 4.6.5 - ssh2: - specifier: ^1.16.0 - version: 1.16.0 + node-ssh: + specifier: ^13.2.0 + version: 13.2.0 zod: specifier: ^3.23.8 version: 3.23.8 @@ -30,9 +30,6 @@ importers: '@types/node': specifier: ^20.11.17 version: 20.16.12 - '@types/ssh2': - specifier: ^1.15.1 - version: 1.15.1 tsx: specifier: ^4.7.1 version: 4.19.1 @@ -261,15 +258,9 @@ packages: resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} engines: {node: ^14.21.3 || >=16} - '@types/node@18.19.56': - resolution: {integrity: sha512-4EMJlWwwGnVPflJAtM14p9eVSa6BOv5b92mCsh5zcM1UagNtEtrbbtaE6WE1tw2TabavatnwqXjlIpcAEuJJNg==} - '@types/node@20.16.12': resolution: {integrity: sha512-LfPFB0zOeCeCNQV3i+67rcoVvoN5n0NVuR2vLG0O5ySQMgchuZlC4lgz546ZOJyDtj5KIgOxy+lacOimfqZAIA==} - '@types/ssh2@1.15.1': - resolution: {integrity: sha512-ZIbEqKAsi5gj35y4P4vkJYly642wIbY6PqoN0xiyQGshKUGXR9WQjF/iF9mXBQ8uBKy3ezfsCkcoHKhd0BzuDA==} - asn1@0.2.6: resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} @@ -352,6 +343,10 @@ packages: resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} engines: {node: '>=16'} + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -362,6 +357,10 @@ packages: nan@2.22.0: resolution: {integrity: sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==} + node-ssh@13.2.0: + resolution: {integrity: sha512-7vsKR2Bbs66th6IWCy/7SN4MSwlVt+G6QrHB631BjRUM8/LmvDugtYhi0uAmgvHS/+PVurfNBOmELf30rm0MZg==} + engines: {node: '>= 10'} + npm-run-path@4.0.1: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} @@ -388,6 +387,18 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sb-promise-queue@2.1.0: + resolution: {integrity: sha512-zwq4YuP1FQFkGx2Q7GIkZYZ6PqWpV+bg0nIO1sJhWOyGyhqbj0MsTvK6lCFo5TQwX5pZr6SCQ75e8PCDCuNvkg==} + engines: {node: '>= 8'} + + sb-scandir@3.1.0: + resolution: {integrity: sha512-70BVm2xz9jn94zSQdpvYrEG101/UV9TVGcfWr9T5iob3QhCK4lYXeculfBqPGFv3XTeKgx4dpWyYIDeZUqo4kg==} + engines: {node: '>= 8'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -396,6 +407,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shell-escape@0.2.0: + resolution: {integrity: sha512-uRRBT2MfEOyxuECseCZd28jC1AJ8hmqqneWQ4VWUTgCAFvb3wKU1jLqj6egC4Exrr88ogg3dp+zroH4wJuaXzw==} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -420,9 +434,6 @@ packages: engines: {node: '>=14.17'} hasBin: true - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -572,18 +583,10 @@ snapshots: '@noble/hashes@1.5.0': {} - '@types/node@18.19.56': - dependencies: - undici-types: 5.26.5 - '@types/node@20.16.12': dependencies: undici-types: 6.19.8 - '@types/ssh2@1.15.1': - dependencies: - '@types/node': 18.19.56 - asn1@0.2.6: dependencies: safer-buffer: 2.1.2 @@ -681,6 +684,10 @@ snapshots: isexe@3.1.1: {} + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + merge-stream@2.0.0: {} mimic-fn@2.1.0: {} @@ -688,6 +695,15 @@ snapshots: nan@2.22.0: optional: true + node-ssh@13.2.0: + dependencies: + is-stream: 2.0.1 + make-dir: 3.1.0 + sb-promise-queue: 2.1.0 + sb-scandir: 3.1.0 + shell-escape: 0.2.0 + ssh2: 1.16.0 + npm-run-path@4.0.1: dependencies: path-key: 3.1.1 @@ -706,12 +722,22 @@ snapshots: safer-buffer@2.1.2: {} + sb-promise-queue@2.1.0: {} + + sb-scandir@3.1.0: + dependencies: + sb-promise-queue: 2.1.0 + + semver@6.3.1: {} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} + shell-escape@0.2.0: {} + signal-exit@3.0.7: {} ssh2@1.16.0: @@ -735,8 +761,6 @@ snapshots: typescript@5.6.3: {} - undici-types@5.26.5: {} - undici-types@6.19.8: {} which@2.0.2: diff --git a/src/index.ts b/src/index.ts index b9e0aa7..e471a24 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,20 +1,28 @@ import { type HttpBindings, serve } from "@hono/node-server"; import { Hono } from "hono"; -import ssh from "ssh2"; +import { NodeSSH } from "node-ssh"; import { z } from "zod"; -ssh.createAgent(socketPath); - const env = z .object({ PUSHOVER_USER: z.string(), PUSHOVER_TOKEN: z.string(), + SSH_USERNAME: z.string(), + SSH_PASSWORD: z.string(), + ROUTER_HOSTNAME: z.string().ip({ version: "v4" }), }) .parse(process.env); const app = new Hono<{ Bindings: HttpBindings }>(); -app.get("/toggle-dns", (c) => { +app.get("/toggle-dns", async (c) => { + const ssh = new NodeSSH(); + await ssh.connect({ + hostname: env.ROUTER_HOSTNAME, + username: env.SSH_USERNAME, + password: env.SSH_PASSWORD, + }); + const resp = c.text("Hono meets Node.js"); console.log(`${c.env.incoming.method} ${c.env.incoming.url}`); return resp;