Task: Add client and key for socket identified for user and updated client functions and configs for http tunnel client

This commit is contained in:
Sambo Chea 2022-06-25 14:32:31 +07:00
parent cf2ad12dac
commit c4e1ddd8dc
Signed by: sombochea
GPG Key ID: 3C7CF22A05D95490
4 changed files with 95 additions and 20 deletions

View File

@ -1,5 +1,11 @@
# HTTP Tunnel Client # CUBETIQ HTTP Tunnel Client
A lightweight http tunnel client using nodejs. A lightweight http tunnel client using nodejs and socket.io client.
### Usage
- Generate Client Key
```
npx @cubetiq/http-tunnel config client new
```
### Contributors ### Contributors
- Original [web-tunnel](https://github.com/web-tunnel/lite-http-tunnel-client) - Original [web-tunnel](https://github.com/web-tunnel/lite-http-tunnel-client)

View File

@ -6,7 +6,12 @@ const { io } = require("socket.io-client");
const HttpsProxyAgent = require("https-proxy-agent"); const HttpsProxyAgent = require("https-proxy-agent");
const { program, InvalidArgumentError, Argument } = require("commander"); const { program, InvalidArgumentError, Argument } = require("commander");
const { TunnelRequest, TunnelResponse } = require("./lib"); const { TunnelRequest, TunnelResponse } = require("./lib");
const { generateUUID, addPrefixOnHttpSchema } = require("./util");
// constants
const PROFILE_DEFAULT = "default";
// create socket instance
let socket = null; let socket = null;
function keepAlive() { function keepAlive() {
@ -19,11 +24,24 @@ function keepAlive() {
} }
function initClient(options) { function initClient(options) {
// Please change this if your domain goes wrong here
// Current style using sub-domain: https://{{clientId}}-tunnel.myhostingdomain.com
// (Original server: https://tunnel.myhostingdomain.com)
const profile = options.profile || PROFILE_DEFAULT;
const clientId = `${options.clientId || generateUUID()}`;
const clientIdSub = `${clientId}-${profile}-`;
const serverUrl = addPrefixOnHttpSchema(options.server, clientIdSub);
const initParams = { const initParams = {
path: "/$web_tunnel", path: "/$cubetiq_http_tunnel",
transports: ["websocket"], transports: ["websocket"],
auth: { auth: {
token: options.token, token: options.token,
apiKey: options.apiKey,
clientId: options.clientId,
profile: options.profile,
clientIdSub: clientIdSub,
serverUrl: serverUrl,
}, },
}; };
@ -32,20 +50,23 @@ function initClient(options) {
initParams.agent = new HttpsProxyAgent(http_proxy); initParams.agent = new HttpsProxyAgent(http_proxy);
} }
socket = io(options.server, initParams); // Connecting to socket server and agent here...
console.log(`client connecting to server: ${serverUrl}`);
socket = io(serverUrl, initParams);
const clientLogPrefix = `client: ${clientId} on profile: ${profile}`;
socket.on("connect", () => { socket.on("connect", () => {
if (socket.connected) { if (socket.connected) {
console.log("client connect to server successfully"); console.log(`${clientLogPrefix} is connected to server successfully!`);
} }
}); });
socket.on("connect_error", (e) => { socket.on("connect_error", (e) => {
console.log("connect error", e && e.message); console.log(`${clientLogPrefix} connect error!`, e && e.message);
}); });
socket.on("disconnect", () => { socket.on("disconnect", () => {
console.log("client disconnected"); console.log(`${clientLogPrefix} disconnected!`);
}); });
socket.on("request", (requestId, request) => { socket.on("request", (requestId, request) => {
@ -132,7 +153,7 @@ function initClient(options) {
keepAlive(); keepAlive();
} }
program.name("http-tunnel").description("HTTP tunnel client"); program.name("http-tunnel").description("CUBETIQ HTTP tunnel client");
program program
.command("start") .command("start")
@ -143,7 +164,7 @@ program
} }
return port; return port;
}) })
.option("-p, --profile <string>", "setting profile name", "default") .option("-p, --profile <string>", "setting profile name", PROFILE_DEFAULT)
.option("-h, --host <string>", "local host value", "localhost") .option("-h, --host <string>", "local host value", "localhost")
.option("-o, --origin <string>", "change request origin") .option("-o, --origin <string>", "change request origin")
.action((port, options) => { .action((port, options) => {
@ -162,32 +183,52 @@ program
} }
if (!config.server) { if (!config.server) {
console.log("Please set remote tunnel server firstly"); console.error("Please set remote tunnel server firstly!");
return; return;
} }
if (!config.token) { if (!config.token) {
console.log(`Please set jwt token for ${config.server} firstly`); console.error(`Please set jwt token for ${config.server} firstly!`);
return;
}
if (!config.clientId) {
console.error(`Please create client for ${config.server} firstly!`);
return; return;
} }
options.port = port; options.port = port;
options.token = config.token; options.token = config.token;
options.server = config.server; options.server = config.server;
options.clientId = config.clientId;
options.apiKey = config.apiKey;
initClient(options); initClient(options);
}); });
program program
.command("config") .command("config")
.addArgument(new Argument("<type>", "config type").choices(["jwt", "server"])) .addArgument(
new Argument("<type>", "config type").choices([
"token",
"server",
"client",
"key",
])
)
.argument("<value>", "config value") .argument("<value>", "config value")
.option("-p --profile <string>", "setting profile name", "default") .option("-p --profile <string>", "setting profile name", PROFILE_DEFAULT)
.action((type, value, options) => { .action((type, value, options) => {
if (!type) {
console.error("type config is required!");
return;
}
const configDir = path.resolve(os.homedir(), ".http-tunnel"); const configDir = path.resolve(os.homedir(), ".http-tunnel");
if (!fs.existsSync(configDir)) { if (!fs.existsSync(configDir)) {
fs.mkdirSync(configDir); fs.mkdirSync(configDir);
console.log(`config file ${configDir} was created!`);
} }
let config = {}; let config = {};
@ -198,16 +239,24 @@ program
config = JSON.parse(fs.readFileSync(configFilePath, "utf8")); config = JSON.parse(fs.readFileSync(configFilePath, "utf8"));
} }
if (type === "jwt") { if (type === "token" || type === "jwt") {
config.token = value; config.token = value;
} } else if (type === "server") {
if (type === "server") {
config.server = value; config.server = value;
} else if (type === "clientId" || type === "client") {
if (!value || value === "new") {
config.clientId = generateUUID();
} else {
config.clientId = value;
}
} else if (type === "apiKey" || type === "key") {
config.apiKey = value;
} else {
config[key] = value;
} }
fs.writeFileSync(configFilePath, JSON.stringify(config, null, 2)); fs.writeFileSync(configFilePath, JSON.stringify(config, null, 2));
console.log(`${type} config saved successfully to: ${configFilePath}`); console.log(`${type} config saved successfully to: ${configFilePath}!`);
}); });
program.parse(); program.parse();

View File

@ -1,7 +1,7 @@
{ {
"name": "@cubetiq/http-tunnel-client", "name": "@cubetiq/http-tunnel-client",
"version": "1.0.0", "version": "1.0.0",
"description": "A lightweight http tunnel client", "description": "A lightweight http tunnel client using nodejs and socket.io client.",
"main": "client.js", "main": "client.js",
"bin": { "bin": {
"http-tunnel": "bin/http-tunnel" "http-tunnel": "bin/http-tunnel"
@ -14,7 +14,8 @@
"url": "https://git.cubetiqs.com/cubetiq/http-tunnel-client.git" "url": "https://git.cubetiqs.com/cubetiq/http-tunnel-client.git"
}, },
"keywords": [ "keywords": [
"http-tunnel-client" "http-tunnel-client",
"socket.io-client"
], ],
"author": "Sambo Chea <sombochea@cubetiqs.com>", "author": "Sambo Chea <sombochea@cubetiqs.com>",
"license": "ISC", "license": "ISC",

19
util.js Normal file
View File

@ -0,0 +1,19 @@
const crypto = require("crypto");
const addPrefixOnHttpSchema = (url, prefixDomain) => {
let prefixSubDomain = prefixDomain;
const prefixSchema = url.substring(0, url.indexOf("://") + 3);
const splitDomain = url.substring(url.indexOf("://") + 3);
// if (!prefixSubDomain.endsWith(".")) {
// prefixSubDomain = `${prefixSubDomain}.`;
// }
return `${prefixSchema}${prefixSubDomain}${splitDomain}`;
};
const generateUUID = () => {
return crypto.randomUUID();
};
module.exports = { addPrefixOnHttpSchema, generateUUID };