✨Add single use auth for terminal connect
This commit is contained in:
parent
c935c71cc2
commit
69fb282468
|
@ -12,13 +12,15 @@
|
|||
"@homebridge/node-pty-prebuilt-multiarch": "^0.11.14",
|
||||
"@types/koa": "^2.15.0",
|
||||
"@types/koa-router": "^7.4.8",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"events": "^3.3.0",
|
||||
"koa": "^2.15.3",
|
||||
"koa-body": "^6.0.1",
|
||||
"koa-router": "^12.0.1",
|
||||
"socket.io": "^4.7.5",
|
||||
"systeminformation": "^5.22.11",
|
||||
"typescript": "^5.4.5"
|
||||
"typescript": "^5.4.5",
|
||||
"uuid": "^10.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.14.6",
|
||||
|
|
|
@ -14,6 +14,9 @@ dependencies:
|
|||
'@types/koa-router':
|
||||
specifier: ^7.4.8
|
||||
version: 7.4.8
|
||||
'@types/uuid':
|
||||
specifier: ^10.0.0
|
||||
version: 10.0.0
|
||||
events:
|
||||
specifier: ^3.3.0
|
||||
version: 3.3.0
|
||||
|
@ -35,6 +38,9 @@ dependencies:
|
|||
typescript:
|
||||
specifier: ^5.4.5
|
||||
version: 5.5.2
|
||||
uuid:
|
||||
specifier: ^10.0.0
|
||||
version: 10.0.0
|
||||
|
||||
devDependencies:
|
||||
'@types/node':
|
||||
|
@ -246,6 +252,10 @@ packages:
|
|||
'@types/send': 0.17.4
|
||||
dev: false
|
||||
|
||||
/@types/uuid@10.0.0:
|
||||
resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==}
|
||||
dev: false
|
||||
|
||||
/accepts@1.3.8:
|
||||
resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
@ -1106,6 +1116,11 @@ packages:
|
|||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
dev: false
|
||||
|
||||
/uuid@10.0.0:
|
||||
resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/v8-compile-cache-lib@3.0.1:
|
||||
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
|
||||
dev: true
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
import { response, routerApp } from "../service/router";
|
||||
import SingleUseToken from "../service/single-use-token";
|
||||
|
||||
routerApp.on("auth/single-token", async (ctx, data) => {
|
||||
const stringPromise = await SingleUseToken.createToken(data.permission, data.info);
|
||||
response(ctx, stringPromise)
|
||||
})
|
|
@ -3,6 +3,7 @@ import { getSystemInfo } from "../service/system_info";
|
|||
import { NodeInfo } from "../../../common/types/daemon";
|
||||
|
||||
import * as pty from "@homebridge/node-pty-prebuilt-multiarch";
|
||||
import SingleUseToken from "../service/single-use-token";
|
||||
|
||||
routerApp.on("info", async (ctx, data) => {
|
||||
|
||||
|
@ -20,8 +21,27 @@ routerApp.on("info", async (ctx, data) => {
|
|||
|
||||
routerApp.on("terminal", async (ctx, data) => {
|
||||
|
||||
console.log("terminal data: ", data)
|
||||
const token = await SingleUseToken.auth(data, "terminal")
|
||||
if (!token) {
|
||||
ctx.socket.disconnect();
|
||||
return
|
||||
}
|
||||
|
||||
let cmd = "";
|
||||
let args = [];
|
||||
|
||||
// Start Command
|
||||
if (token.info === "bash") {
|
||||
cmd = "/bin/bash";
|
||||
args = ["--login"]
|
||||
} else {
|
||||
ctx.socket.disconnect();
|
||||
return
|
||||
}
|
||||
|
||||
// create a process and send to client
|
||||
const ptyProcess = pty.spawn("/bin/bash", ["--login"], {
|
||||
const ptyProcess = pty.spawn(cmd, args, {
|
||||
cols: 80,
|
||||
rows: 24,
|
||||
cwd: process.env.HOME, // 或你希望的起始目录
|
||||
|
|
|
@ -58,4 +58,5 @@ export function response(ctx: RouterCtx, data: any) {
|
|||
ctx.socket.emit(ctx.event, respPacket);
|
||||
}
|
||||
|
||||
import "../routers/overview"
|
||||
import "../routers/overview"
|
||||
import "../routers/auth-router"
|
|
@ -0,0 +1,57 @@
|
|||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
type SingleToken = {
|
||||
token: string;
|
||||
expire: number;
|
||||
permission: string;
|
||||
info: string;
|
||||
}
|
||||
|
||||
class SingleUseToken {
|
||||
private readonly tokenList: Map<string, SingleToken>;
|
||||
|
||||
constructor() {
|
||||
this.tokenList = new Map();
|
||||
}
|
||||
|
||||
async addToken(token: string, expire: number, permission: string, info: string) {
|
||||
this.tokenList.set(token, {
|
||||
token: token,
|
||||
expire: expire,
|
||||
permission: permission,
|
||||
info: info
|
||||
});
|
||||
}
|
||||
|
||||
async createToken(permission: string, info: string) {
|
||||
const token = uuidv4().replace(/-/g, "");
|
||||
const expire = Date.now() + 1000 * 60 * 60;
|
||||
await this.addToken(token, expire, permission, info);
|
||||
return token;
|
||||
}
|
||||
|
||||
async auth(token: string, permission: string) {
|
||||
const payload = this.tokenList.get(token);
|
||||
if (payload) {
|
||||
// Expire time
|
||||
if (payload.expire < Date.now()) {
|
||||
await this.removeToken(token);
|
||||
return null;
|
||||
}
|
||||
// Permission
|
||||
if (payload.permission === permission) {
|
||||
await this.removeToken(token);
|
||||
return payload;
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async removeToken(token: string) {
|
||||
this.tokenList.delete(token);
|
||||
}
|
||||
}
|
||||
|
||||
export default new SingleUseToken();
|
|
@ -1,5 +1,6 @@
|
|||
import Router from "koa-router";
|
||||
import RemoteManage from "../services/remote_manage";
|
||||
import RemoteRequest from "../services/remote_request";
|
||||
|
||||
const terminalRouter = new Router({
|
||||
prefix: "/terminal"
|
||||
|
@ -7,10 +8,15 @@ const terminalRouter = new Router({
|
|||
|
||||
terminalRouter.get("/:endpoint/:name", async (ctx) => {
|
||||
const server = await RemoteManage.getServer(ctx.params.endpoint);
|
||||
// Get Token
|
||||
if (server) {
|
||||
const resp = await new RemoteRequest(server).request("auth/single-token", {
|
||||
permission: "terminal",
|
||||
info: "bash"
|
||||
})
|
||||
ctx.body = {
|
||||
socket: server.getSocketUrl(),
|
||||
token: "1234567890"
|
||||
token: resp
|
||||
}
|
||||
} else {
|
||||
ctx.status = 404;
|
||||
|
|
|
@ -47,8 +47,8 @@ const BashTerminalModal: React.FC<BashTerminalModalProps> = (props) => {
|
|||
terminal?.reset();
|
||||
// auth
|
||||
socket?.emit("terminal", {
|
||||
uuid: "34567890",
|
||||
data: {}
|
||||
uuid: "",
|
||||
data: res.data.token
|
||||
})
|
||||
})
|
||||
|
||||
|
|
Loading…
Reference in New Issue