Skip to content

Add standalone option #85

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 0 additions & 19 deletions .eslintrc.js

This file was deleted.

26 changes: 26 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 2018
},
"env": {
"node": true,
"es6": true
},
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
"rules": {
"no-ex-assign": "off",
"no-var":"error",
"object-shorthand": ["warn", "always"],
"prettier/prettier": ["warn", {"bracketSpacing": false, "trailingComma": "es5"}]
},
"overrides": [
{
"files": ["*.test.js"],
"env": {
"jest": true
}
}
],
"root": true
}
13 changes: 11 additions & 2 deletions bin/observable-database-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,20 @@ argv
name,
start
)
.command(`add <name>`, `Add a new database proxy configuration`, name, add)
.command(
`add <name> [--standalone]`,
`Add a new database proxy configuration`,
name,
add
)
.command(
`remove <name>`,
`Remove an existing database proxy configuration`,
name,
remove
)
.command(
`reset <name>`,
`reset <name> [--standalone]`,
`Reset the shared secret for an existing database proxy configuration`,
name,
reset
Expand All @@ -40,6 +45,10 @@ argv
`sslkey`,
`Set the SSL private key location for an HTTPS database proxy`
)
.describe(
`standalone`,
`Standalone mode: create a secret for standalone clients`
)
.example(`$0 start localdb`, `Run an HTTP database proxy named "localdb"`)
.example(
`$0 start localssl --sslkey ../ssl/localhost.key --sslcert ../ssl/localhost.crt`,
Expand Down
61 changes: 56 additions & 5 deletions lib/commands.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
/* eslint-disable no-console */

import {randomBytes} from "crypto";
import {createInterface} from "readline";
import open from "open";
import {
readConfig,
readDecodedConfig,
writeConfig,
decodeSecret,
encodeSecret,
} from "./config.js";
import {server} from "./server.js";
import {server, types} from "./server.js";
import {exit} from "./errors.js";

export function start(argv) {
Expand All @@ -17,7 +19,7 @@ export function start(argv) {
}

export async function add(argv, reset = false) {
const {name, sslkey, sslcert} = argv;
const {name, sslkey, sslcert, standalone} = argv;
let config = readConfig();
let url;
let token;
Expand All @@ -39,7 +41,12 @@ export async function add(argv, reset = false) {
if (reset) {
if (!config[name]) exit(`No configuration found for "${name}"`);
url = config[name].url;
} else {
token = config[name].token;
server_host = config[name].server_host;
path = config[name].path;
username = config[name].username;
password = config[name].password;
} else if (!standalone) {
const wantsSSL = sslkey || sslcert;
// open browser
const observable =
Expand All @@ -53,8 +60,50 @@ export async function add(argv, reset = false) {
);
}

// paste secret (secret, origin, name, type, host, port, ssl)
const secret = await question("Secret: ");
let secret;
if (standalone) {
let {type, host, origin, port, ssl} = reset
? decodeSecret(config[name].secret)
: {};
if (!type) {
for (;;) {
type = await question("Database type: ");
if (types.includes(type)) break;
console.log(`Invalid type, should be one of: ${types.join(", ")}`);
}
} else if (!types.includes(type)) {
exit(`Invalid type, should be one of: ${type.join(", ")}`);
}
if (!host || !port || !ssl) {
const proxyUrl = new URL(
(await question(
"Observable database proxy Url [http://127.0.0.1:2899]:"
)) || "http://127.0.0.1:2899"
);
host = proxyUrl.hostname;
port = proxyUrl.port;
ssl = proxyUrl.protocol !== "https" ? "disabled" : "required";
}
if (!origin) {
origin =
(await question("Standalone server origin [http://127.0.0.1:3000]:")) ||
"http://127.0.0.1:3000";
}

const secretPayload = {
name,
type,
host,
port,
ssl,
origin,
secret: randomBytes(32).toString("hex"),
};
secret = encodeSecret(secretPayload);
} else {
// paste secret (secret, origin, name, type, host, port, ssl)
secret = await question("Secret: ");
}
const decoded = decodeSecret(secret);
if (decoded.name !== name)
return exit(`Name mismatch: "${decoded.name}" (server), "${name} (proxy)"`);
Expand Down Expand Up @@ -104,6 +153,8 @@ export async function add(argv, reset = false) {
writeConfig(config);

console.log(`Configuration ${reset ? `reset` : `added`} for "${name}"`);
if (standalone)
console.log(`Secret for DabaseClient("${name}"):\ndb:${name}:${secret}`);
}

export function reset(argv) {
Expand Down
5 changes: 5 additions & 0 deletions lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,8 @@ export function decodeSecret(secret) {
exit(error);
}
}

export function encodeSecret(arg) {
const buffer = Buffer.from(JSON.stringify(arg)).toString("base64");
return buffer;
}
12 changes: 11 additions & 1 deletion lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,19 @@ import oracle from "./oracle.js";
import databricks from "./databricks.js";
import logger from "../middleware/logger.js";

export const types = [
"databricks",
"mysql",
"mssql",
"postgres",
"snowflake",
"oracle",
"mongosql",
];

export async function server(config, argv) {
const development = process.env.NODE_ENV === "development";
const developmentOrigin = "https://worker.test:5000";
const developmentOrigin = "https://login.worker.test:5000";

const {
name,
Expand Down
2 changes: 1 addition & 1 deletion lib/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const validateQueryPayload = ajv.compile({
required: ["sql"],
properties: {
sql: {type: "string", minLength: 1, maxLength: 32 * 1000},
params: {type: ["object", "array"]},
params: {anyOf: [{type: ["object"]}, {type: ["array"]}]}
},
});
export const validateDescribeColumnsPayload = ajv.compile({
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,14 @@
"@babel/preset-env": "^7.19.4",
"@babel/register": "^7.18.9",
"chai": "^4.3.6",
"eslint": "^8.50.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"mocha": "^10.1.0",
"mock-req": "^0.2.0",
"mock-res": "^0.6.0",
"nodemon": "^1.19.1",
"prettier": "^3.0.3",
"wait-on": "^6.0.1"
},
"peerDependencies": {
Expand Down
Loading