mirror of
https://github.com/coder/code-server.git
synced 2024-11-28 22:26:28 +03:00
Update dependencies and force-update qs (#6440)
* Update dependencies and force-update qs This is mainly an attempt to get rid of as many resolutions as possible since it seems they are unnecessary except for qs (according to yarn/npm audit). For qs use 6.9.7 since Express is using 6.9.6 and that matches the most closely. Also add overrides since this is npm's version of yarn's resolutions and we need it for the shrinkwrap to generate with the right dependencies. Decided to keep pinning @types/node as well although I am not sure it is necessary. Express is pulling in v20 types. Since this is development-only we only need it in resolutions. * Run formatter Some rules seem to have changed with the dependency updates. * Replace deprecated bodyParser.json() usage * Audit npm shrinkwrap as well * Skip installing dependencies in audit It seems the tools only require the lock files. * Fix tests when using ipv6 * Add missing openssl dependency to flake
This commit is contained in:
parent
47ee7ae670
commit
acc50a5d36
2
.github/workflows/build.yaml
vendored
2
.github/workflows/build.yaml
vendored
@ -31,7 +31,7 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Run prettier with actionsx/prettier
|
||||
uses: actionsx/prettier@v2
|
||||
uses: actionsx/prettier@v3
|
||||
with:
|
||||
args: --check --loglevel=warn .
|
||||
|
||||
|
19
.github/workflows/security.yaml
vendored
19
.github/workflows/security.yaml
vendored
@ -34,21 +34,12 @@ jobs:
|
||||
with:
|
||||
node-version: "18"
|
||||
|
||||
- name: Fetch dependencies from cache
|
||||
id: cache-yarn
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: "**/node_modules"
|
||||
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
|
||||
restore-keys: |
|
||||
yarn-build-
|
||||
- name: Audit yarn for vulnerabilities
|
||||
run: yarn audit
|
||||
if: success()
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.cache-yarn.outputs.cache-hit != 'true'
|
||||
run: SKIP_SUBMODULE_DEPS=1 yarn --frozen-lockfile
|
||||
|
||||
- name: Audit for vulnerabilities
|
||||
run: yarn _audit
|
||||
- name: Audit npm for vulnerabilities
|
||||
run: npm shrinkwrap && npm audit
|
||||
if: success()
|
||||
|
||||
trivy-scan-repo:
|
||||
|
@ -12,7 +12,7 @@
|
||||
in {
|
||||
devShells.default = pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs; [
|
||||
nodejs yarn' python3 pkg-config git rsync jq moreutils quilt bats
|
||||
nodejs yarn' python3 pkg-config git rsync jq moreutils quilt bats openssl
|
||||
];
|
||||
buildInputs = with pkgs; (lib.optionals (!stdenv.isDarwin) [ libsecret libkrb5 ]
|
||||
++ (with xorg; [ libX11 libxkbfile ])
|
||||
|
101
package.json
101
package.json
@ -38,75 +38,62 @@
|
||||
},
|
||||
"main": "out/node/entry.js",
|
||||
"devDependencies": {
|
||||
"@schemastore/package": "^0.0.6",
|
||||
"@types/compression": "^1.7.0",
|
||||
"@types/cookie-parser": "^1.4.2",
|
||||
"@types/express": "^4.17.8",
|
||||
"@types/http-proxy": "^1.17.4",
|
||||
"@types/js-yaml": "^4.0.0",
|
||||
"@schemastore/package": "^0.0.10",
|
||||
"@types/compression": "^1.7.3",
|
||||
"@types/cookie-parser": "^1.4.4",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/http-proxy": "1.17.7",
|
||||
"@types/js-yaml": "^4.0.6",
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/pem": "^1.9.5",
|
||||
"@types/pem": "^1.14.1",
|
||||
"@types/proxy-from-env": "^1.0.1",
|
||||
"@types/safe-compare": "^1.1.0",
|
||||
"@types/semver": "^7.1.0",
|
||||
"@types/trusted-types": "^2.0.2",
|
||||
"@types/ws": "^8.5.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.41.0",
|
||||
"@typescript-eslint/parser": "^5.41.0",
|
||||
"audit-ci": "^6.0.0",
|
||||
"doctoc": "2.2.1",
|
||||
"eslint": "^8.26.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-import-resolver-typescript": "^3.5.2",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-prettier": "^4.2.1",
|
||||
"prettier": "2.8.0",
|
||||
"prettier-plugin-sh": "^0.12.8",
|
||||
"ts-node": "^10.0.0",
|
||||
"typescript": "^5.0.4"
|
||||
},
|
||||
"resolutions": {
|
||||
"ansi-regex": "^5.0.1",
|
||||
"normalize-package-data": "^5.0.0",
|
||||
"doctoc/underscore": "^1.13.1",
|
||||
"doctoc/**/trim": "^1.0.0",
|
||||
"postcss": "^8.2.1",
|
||||
"browserslist": "^4.16.5",
|
||||
"safe-buffer": "^5.1.1",
|
||||
"vfile-message": "^2.0.2",
|
||||
"tar": "^6.1.9",
|
||||
"path-parse": "^1.0.7",
|
||||
"vm2": "^3.9.11",
|
||||
"follow-redirects": "^1.14.8",
|
||||
"node-fetch": "^2.6.7",
|
||||
"nanoid": "^3.1.31",
|
||||
"minimist": "npm:minimist-lite@2.2.1",
|
||||
"glob-parent": "^6.0.1",
|
||||
"@types/node": "^18.0.0",
|
||||
"qs": "^6.7.3"
|
||||
"@types/semver": "^7.5.2",
|
||||
"@types/trusted-types": "^2.0.4",
|
||||
"@types/ws": "^8.5.5",
|
||||
"@typescript-eslint/eslint-plugin": "^6.7.2",
|
||||
"@typescript-eslint/parser": "^6.7.2",
|
||||
"audit-ci": "^6.6.1",
|
||||
"doctoc": "^2.2.1",
|
||||
"eslint": "^8.49.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.0",
|
||||
"eslint-plugin-import": "^2.28.1",
|
||||
"eslint-plugin-prettier": "^5.0.0",
|
||||
"prettier": "^3.0.3",
|
||||
"prettier-plugin-sh": "^0.13.1",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@coder/logger": "^3.0.0",
|
||||
"argon2": "0.31.0",
|
||||
"@coder/logger": "^3.0.1",
|
||||
"argon2": "^0.31.1",
|
||||
"compression": "^1.7.4",
|
||||
"cookie-parser": "^1.4.5",
|
||||
"env-paths": "^2.2.0",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"env-paths": "^2.2.1",
|
||||
"express": "5.0.0-alpha.8",
|
||||
"http-proxy": "^1.18.0",
|
||||
"http-proxy": "^1.18.1",
|
||||
"httpolyglot": "^0.1.2",
|
||||
"i18next": "^23.2.11",
|
||||
"js-yaml": "^4.0.0",
|
||||
"i18next": "^23.5.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"limiter": "^2.1.0",
|
||||
"pem": "^1.14.2",
|
||||
"proxy-agent": "^6.2.1",
|
||||
"qs": "6.11.0",
|
||||
"rotating-file-stream": "^3.0.0",
|
||||
"safe-buffer": "^5.1.1",
|
||||
"pem": "^1.14.8",
|
||||
"proxy-agent": "^6.3.1",
|
||||
"qs": "6.9.7",
|
||||
"rotating-file-stream": "^3.1.1",
|
||||
"safe-buffer": "^5.2.1",
|
||||
"safe-compare": "^1.1.4",
|
||||
"semver": "^7.1.3",
|
||||
"ws": "^8.0.0",
|
||||
"semver": "^7.5.4",
|
||||
"ws": "^8.14.2",
|
||||
"xdg-basedir": "^4.0.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/node": "^18.0.0",
|
||||
"qs": "6.9.7"
|
||||
},
|
||||
"overrides": {
|
||||
"qs": "6.9.7"
|
||||
},
|
||||
"bin": {
|
||||
"code-server": "out/node/entry.js"
|
||||
},
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
@ -46,7 +46,9 @@ button {
|
||||
.card-box {
|
||||
background-color: rgb(250, 253, 258);
|
||||
border-radius: 5px;
|
||||
box-shadow: rgba(60, 66, 87, 0.117647) 0px 7px 14px 0px, rgba(0, 0, 0, 0.117647) 0px 3px 6px 0px;
|
||||
box-shadow:
|
||||
rgba(60, 66, 87, 0.117647) 0px 7px 14px 0px,
|
||||
rgba(0, 0, 0, 0.117647) 0px 3px 6px 0px;
|
||||
max-width: 650px;
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
@ -14,7 +14,11 @@ export enum HttpCode {
|
||||
* used in the HTTP response.
|
||||
*/
|
||||
export class HttpError extends Error {
|
||||
public constructor(message: string, public readonly statusCode: HttpCode, public readonly details?: object) {
|
||||
public constructor(
|
||||
message: string,
|
||||
public readonly statusCode: HttpCode,
|
||||
public readonly details?: object,
|
||||
) {
|
||||
super(message)
|
||||
this.name = this.constructor.name
|
||||
}
|
||||
|
@ -9,7 +9,10 @@ export class Heart {
|
||||
private heartbeatInterval = 60000
|
||||
public lastHeartbeat = 0
|
||||
|
||||
public constructor(private readonly heartbeatPath: string, private readonly isActive: () => Promise<boolean>) {
|
||||
public constructor(
|
||||
private readonly heartbeatPath: string,
|
||||
private readonly isActive: () => Promise<boolean>,
|
||||
) {
|
||||
this.beat = this.beat.bind(this)
|
||||
this.alive = this.alive.bind(this)
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import i18next, { init } from "i18next"
|
||||
import * as en from "./locales/en.json"
|
||||
import * as ja from "./locales/ja.json"
|
||||
import * as th from "./locales/th.json"
|
||||
import * as zhCn from "./locales/zh-cn.json"
|
||||
import * as ja from "./locales/ja.json"
|
||||
init({
|
||||
lng: "en",
|
||||
fallbackLng: "en", // language to use if translations in user language are not available.
|
||||
|
@ -78,7 +78,10 @@ type ChildMessage = RelaunchMessage | ChildHandshakeMessage
|
||||
type ParentMessage = ParentHandshakeMessage
|
||||
|
||||
class ProcessError extends Error {
|
||||
public constructor(message: string, public readonly code: number | undefined) {
|
||||
public constructor(
|
||||
message: string,
|
||||
public readonly code: number | undefined,
|
||||
) {
|
||||
super(message)
|
||||
this.name = this.constructor.name
|
||||
Error.captureStackTrace(this, this.constructor)
|
||||
|
@ -269,7 +269,10 @@ export class CodeServer {
|
||||
export class CodeServerPage {
|
||||
private readonly editorSelector = "div.monaco-workbench"
|
||||
|
||||
constructor(private readonly codeServer: CodeServer, public readonly page: Page) {
|
||||
constructor(
|
||||
private readonly codeServer: CodeServer,
|
||||
public readonly page: Page,
|
||||
) {
|
||||
this.page.on("console", (message) => {
|
||||
this.codeServer.logger.debug(message.text())
|
||||
})
|
||||
|
@ -92,7 +92,7 @@ describe("createApp", () => {
|
||||
app.dispose()
|
||||
}
|
||||
|
||||
expect(() => masterBall()).rejects.toThrow(`listen EACCES: permission denied 127.0.0.1:${port}`)
|
||||
expect(() => masterBall()).rejects.toThrow("listen EACCES: permission denied")
|
||||
})
|
||||
|
||||
it("should unlink a socket before listening on the socket", async () => {
|
||||
|
@ -1,4 +1,3 @@
|
||||
import * as bodyParser from "body-parser"
|
||||
import * as express from "express"
|
||||
import * as http from "http"
|
||||
import nodeFetch from "node-fetch"
|
||||
@ -110,7 +109,7 @@ describe("proxy", () => {
|
||||
})
|
||||
|
||||
it("should allow post bodies", async () => {
|
||||
e.use(bodyParser.json({ strict: false }))
|
||||
e.use(express.json({ strict: false }))
|
||||
e.post("/wsup", (req, res) => {
|
||||
res.json(req.body)
|
||||
})
|
||||
@ -127,7 +126,7 @@ describe("proxy", () => {
|
||||
})
|
||||
|
||||
it("should handle bad requests", async () => {
|
||||
e.use(bodyParser.json({ strict: false }))
|
||||
e.use(express.json({ strict: false }))
|
||||
e.post("/wsup", (req, res) => {
|
||||
res.json(req.body)
|
||||
})
|
||||
@ -154,7 +153,7 @@ describe("proxy", () => {
|
||||
})
|
||||
|
||||
it("should handle errors", async () => {
|
||||
e.use(bodyParser.json({ strict: false }))
|
||||
e.use(express.json({ strict: false }))
|
||||
e.post("/wsup", (req, res) => {
|
||||
throw new Error("BROKEN")
|
||||
})
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { logger } from "@coder/logger"
|
||||
import * as http from "http"
|
||||
import { AddressInfo } from "net"
|
||||
import * as path from "path"
|
||||
import { ensureAddress } from "../../../src/node/app"
|
||||
import { SettingsProvider, UpdateSettings } from "../../../src/node/settings"
|
||||
import { LatestResponse, UpdateProvider } from "../../../src/node/update"
|
||||
import { clean, isAddressInfo, mockLogger, tmpdir } from "../../utils/helpers"
|
||||
import { clean, mockLogger, tmpdir } from "../../utils/helpers"
|
||||
|
||||
describe("update", () => {
|
||||
let version = "1.0.0"
|
||||
@ -79,7 +79,6 @@ describe("update", () => {
|
||||
}
|
||||
|
||||
let _provider: UpdateProvider | undefined
|
||||
let _address: string | AddressInfo | null
|
||||
const provider = (): UpdateProvider => {
|
||||
if (!_provider) {
|
||||
throw new Error("Update provider has not been created")
|
||||
@ -87,6 +86,7 @@ describe("update", () => {
|
||||
return _provider
|
||||
}
|
||||
|
||||
let address = new URL("http://localhost")
|
||||
beforeAll(async () => {
|
||||
mockLogger()
|
||||
|
||||
@ -105,12 +105,13 @@ describe("update", () => {
|
||||
})
|
||||
})
|
||||
|
||||
_address = server.address()
|
||||
if (!isAddressInfo(_address)) {
|
||||
throw new Error("unexpected address")
|
||||
const addr = ensureAddress(server, "http")
|
||||
if (typeof addr === "string") {
|
||||
throw new Error("unable to run update tests with unix sockets")
|
||||
}
|
||||
|
||||
_provider = new UpdateProvider(`http://${_address?.address}:${_address?.port}/latest`, _settings)
|
||||
address = addr
|
||||
address.pathname = "/latest"
|
||||
_provider = new UpdateProvider(address.toString(), _settings)
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
@ -220,59 +221,51 @@ describe("update", () => {
|
||||
})
|
||||
|
||||
it("should reject if response has status code 500", async () => {
|
||||
if (isAddressInfo(_address)) {
|
||||
const mockURL = `http://${_address.address}:${_address.port}/reject-status-code`
|
||||
const provider = new UpdateProvider(mockURL, settings())
|
||||
const update = await provider.getUpdate(true)
|
||||
address.pathname = "/reject-status-code"
|
||||
const provider = new UpdateProvider(address.toString(), settings())
|
||||
const update = await provider.getUpdate(true)
|
||||
|
||||
expect(update.version).toBe("unknown")
|
||||
expect(logger.error).toHaveBeenCalled()
|
||||
expect(logger.error).toHaveBeenCalledWith("Failed to get latest version", {
|
||||
identifier: "error",
|
||||
value: `${mockURL}: 500`,
|
||||
})
|
||||
}
|
||||
expect(update.version).toBe("unknown")
|
||||
expect(logger.error).toHaveBeenCalled()
|
||||
expect(logger.error).toHaveBeenCalledWith("Failed to get latest version", {
|
||||
identifier: "error",
|
||||
value: `${address.toString()}: 500`,
|
||||
})
|
||||
})
|
||||
|
||||
it("should reject if no location header provided", async () => {
|
||||
if (isAddressInfo(_address)) {
|
||||
const mockURL = `http://${_address.address}:${_address.port}/no-location-header`
|
||||
const provider = new UpdateProvider(mockURL, settings())
|
||||
const update = await provider.getUpdate(true)
|
||||
address.pathname = "/no-location-header"
|
||||
const provider = new UpdateProvider(address.toString(), settings())
|
||||
const update = await provider.getUpdate(true)
|
||||
|
||||
expect(update.version).toBe("unknown")
|
||||
expect(logger.error).toHaveBeenCalled()
|
||||
expect(logger.error).toHaveBeenCalledWith("Failed to get latest version", {
|
||||
identifier: "error",
|
||||
value: `received redirect with no location header`,
|
||||
})
|
||||
}
|
||||
expect(update.version).toBe("unknown")
|
||||
expect(logger.error).toHaveBeenCalled()
|
||||
expect(logger.error).toHaveBeenCalledWith("Failed to get latest version", {
|
||||
identifier: "error",
|
||||
value: `received redirect with no location header`,
|
||||
})
|
||||
})
|
||||
|
||||
it("should resolve the request with response.headers.location", async () => {
|
||||
version = "4.1.1"
|
||||
if (isAddressInfo(_address)) {
|
||||
const mockURL = `http://${_address.address}:${_address.port}/with-location-header`
|
||||
const provider = new UpdateProvider(mockURL, settings())
|
||||
const update = await provider.getUpdate(true)
|
||||
address.pathname = "/with-location-header"
|
||||
const provider = new UpdateProvider(address.toString(), settings())
|
||||
const update = await provider.getUpdate(true)
|
||||
|
||||
expect(logger.error).not.toHaveBeenCalled()
|
||||
expect(update.version).toBe("4.1.1")
|
||||
}
|
||||
expect(logger.error).not.toHaveBeenCalled()
|
||||
expect(update.version).toBe("4.1.1")
|
||||
})
|
||||
|
||||
it("should reject if more than 10 redirects", async () => {
|
||||
if (isAddressInfo(_address)) {
|
||||
const mockURL = `http://${_address.address}:${_address.port}/redirect/11`
|
||||
const provider = new UpdateProvider(mockURL, settings())
|
||||
const update = await provider.getUpdate(true)
|
||||
address.pathname = "/redirect/11"
|
||||
const provider = new UpdateProvider(address.toString(), settings())
|
||||
const update = await provider.getUpdate(true)
|
||||
|
||||
expect(update.version).toBe("unknown")
|
||||
expect(logger.error).toHaveBeenCalled()
|
||||
expect(logger.error).toHaveBeenCalledWith("Failed to get latest version", {
|
||||
identifier: "error",
|
||||
value: `reached max redirects`,
|
||||
})
|
||||
}
|
||||
expect(update.version).toBe("unknown")
|
||||
expect(logger.error).toHaveBeenCalled()
|
||||
expect(logger.error).toHaveBeenCalledWith("Failed to get latest version", {
|
||||
identifier: "error",
|
||||
value: `reached max redirects`,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -108,20 +108,6 @@ export function idleTimer(message: string, reject: (error: Error) => void, delay
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper function which returns a boolean indicating whether
|
||||
* the given address is AddressInfo and has .address
|
||||
* and a .port property.
|
||||
*/
|
||||
export function isAddressInfo(address: unknown): address is net.AddressInfo {
|
||||
return (
|
||||
address !== null &&
|
||||
typeof address !== "string" &&
|
||||
(address as net.AddressInfo).port !== undefined &&
|
||||
(address as net.AddressInfo).address !== undefined
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* If using a proxy, return the address of the proxy.
|
||||
*
|
||||
|
@ -35,7 +35,7 @@ export class HttpServer {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.hs.on("error", reject)
|
||||
|
||||
this.hs.listen(0, "localhost", () => {
|
||||
this.hs.listen(0, "127.0.0.1", () => {
|
||||
this.hs.off("error", reject)
|
||||
resolve()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user