feat: add splitOnFirstEquals function

This commit is contained in:
Joe Previte 2021-06-03 16:30:33 -07:00
parent 517aaf71c5
commit 531b7c0c25
No known key found for this signature in database
GPG Key ID: 2C91590C6B742C24
3 changed files with 62 additions and 11 deletions

View File

@ -240,6 +240,25 @@ export const optionDescriptions = (): string[] => {
}) })
} }
export function splitOnFirstEquals(str: string): string[] {
// we use regex instead of "=" to ensure we split at the first
// "=" and return the following substring with it
// important for the hashed-password which looks like this
// $argon2i$v=19$m=4096,t=3,p=1$0qR/o+0t00hsbJFQCKSfdQ$oFcM4rL6o+B7oxpuA4qlXubypbBPsf+8L531U7P9HYY
// 2 means return two items
// Source: https://stackoverflow.com/a/4607799/3015595
const split = str.split(/=(.+)/, 2)
// It should always return two elements
// because it's used in a place where
// it expected two elements
if (split.length === 1) {
split.push("")
}
return split
}
export const parse = ( export const parse = (
argv: string[], argv: string[],
opts?: { opts?: {
@ -270,6 +289,7 @@ export const parse = (
let key: keyof Args | undefined let key: keyof Args | undefined
let value: string | undefined let value: string | undefined
if (arg.startsWith("--")) { if (arg.startsWith("--")) {
// TODO fix this
const split = arg.replace(/^--/, "").split("=", 2) const split = arg.replace(/^--/, "").split("=", 2)
key = split[0] as keyof Args key = split[0] as keyof Args
value = split[1] value = split[1]
@ -543,6 +563,7 @@ export function parseConfigFile(configFile: string, configPath: string): ConfigA
const config = yaml.load(configFile, { const config = yaml.load(configFile, {
filename: configPath, filename: configPath,
}) })
console.log("what is this config", config)
if (!config || typeof config === "string") { if (!config || typeof config === "string") {
throw new Error(`invalid config: ${config}`) throw new Error(`invalid config: ${config}`)
} }
@ -555,9 +576,11 @@ export function parseConfigFile(configFile: string, configPath: string): ConfigA
} }
return `--${optName}=${opt}` return `--${optName}=${opt}`
}) })
console.log("what are the configFileArgv", configFileArgv)
const args = parse(configFileArgv, { const args = parse(configFileArgv, {
configFile: configPath, configFile: configPath,
}) })
console.log(args, "args")
return { return {
...args, ...args,
config: configPath, config: configPath,

View File

@ -2,18 +2,9 @@ import { Router, Request } from "express"
import { promises as fs } from "fs" import { promises as fs } from "fs"
import { RateLimiter as Limiter } from "limiter" import { RateLimiter as Limiter } from "limiter"
import * as path from "path" import * as path from "path"
import safeCompare from "safe-compare"
import { rootPath } from "../constants" import { rootPath } from "../constants"
import { authenticated, getCookieDomain, redirect, replaceTemplates } from "../http" import { authenticated, getCookieDomain, redirect, replaceTemplates } from "../http"
import { import { getPasswordMethod, handlePasswordValidation, humanPath } from "../util"
getPasswordMethod,
handlePasswordValidation,
hash,
hashLegacy,
humanPath,
isHashLegacyMatch,
isHashMatch,
} from "../util"
export enum Cookie { export enum Cookie {
Key = "key", Key = "key",

View File

@ -3,7 +3,7 @@ import { promises as fs } from "fs"
import * as net from "net" import * as net from "net"
import * as os from "os" import * as os from "os"
import * as path from "path" import * as path from "path"
import { Args, parse, setDefaults, shouldOpenInExistingInstance } from "../../src/node/cli" import { Args, parse, setDefaults, shouldOpenInExistingInstance, splitOnFirstEquals } from "../../src/node/cli"
import { tmpdir } from "../../src/node/constants" import { tmpdir } from "../../src/node/constants"
import { paths } from "../../src/node/util" import { paths } from "../../src/node/util"
@ -337,6 +337,18 @@ describe("parser", () => {
"proxy-domain": ["coder.com", "coder.org"], "proxy-domain": ["coder.com", "coder.org"],
}) })
}) })
it("should allow '=,$/' in strings", async () => {
const args = parse([
"--enable-proposed-api",
"$argon2i$v=19$m=4096,t=3,p=1$0qr/o+0t00hsbjfqcksfdq$ofcm4rl6o+b7oxpua4qlxubypbbpsf+8l531u7p9hyy",
])
expect(args).toEqual({
_: [],
"enable-proposed-api": [
"$argon2i$v=19$m=4096,t=3,p=1$0qr/o+0t00hsbjfqcksfdq$ofcm4rl6o+b7oxpua4qlxubypbbpsf+8l531u7p9hyy",
],
})
})
}) })
describe("cli", () => { describe("cli", () => {
@ -411,3 +423,28 @@ describe("cli", () => {
expect(await shouldOpenInExistingInstance(args)).toStrictEqual(undefined) expect(await shouldOpenInExistingInstance(args)).toStrictEqual(undefined)
}) })
}) })
describe("splitOnFirstEquals", () => {
it("should split on the first equals", () => {
const testStr = "--enabled-proposed-api=test=value"
const actual = splitOnFirstEquals(testStr)
const expected = ["--enabled-proposed-api", "test=value"]
expect(actual).toEqual(expect.arrayContaining(expected))
})
it("should split on first equals regardless of multiple equals signs", () => {
const testStr =
"--hashed-password=$argon2i$v=19$m=4096,t=3,p=1$0qR/o+0t00hsbJFQCKSfdQ$oFcM4rL6o+B7oxpuA4qlXubypbBPsf+8L531U7P9HYY"
const actual = splitOnFirstEquals(testStr)
const expected = [
"--hashed-password",
"$argon2i$v=19$m=4096,t=3,p=1$0qR/o+0t00hsbJFQCKSfdQ$oFcM4rL6o+B7oxpuA4qlXubypbBPsf+8L531U7P9HYY",
]
expect(actual).toEqual(expect.arrayContaining(expected))
})
it("should always return two elements", () => {
const testStr = ""
const actual = splitOnFirstEquals(testStr)
const expected = ["", ""]
expect(actual).toEqual(expect.arrayContaining(expected))
})
})