Skip to content

Commit ab122da

Browse files
author
Akash Satheesan
authored
Merge branch 'main' into vscode-1.56
2 parents 178028f + 4f320ad commit ab122da

23 files changed

+506
-268
lines changed

.github/workflows/ci.yaml

+28-4
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@ jobs:
4343
if: steps.cache-yarn.outputs.cache-hit != 'true'
4444
run: yarn --frozen-lockfile
4545

46-
- name: Audit for vulnerabilities
47-
run: yarn _audit
48-
if: success()
49-
5046
- name: Run yarn fmt
5147
run: yarn fmt
5248
if: success()
@@ -63,6 +59,34 @@ jobs:
6359
run: yarn coverage
6460
if: success()
6561

62+
audit-ci:
63+
name: Run audit-ci
64+
needs: prebuild
65+
runs-on: ubuntu-latest
66+
steps:
67+
- name: Checkout repo
68+
uses: actions/checkout@v2
69+
70+
- name: Install Node.js v12
71+
uses: actions/setup-node@v2
72+
with:
73+
node-version: "12"
74+
75+
- name: Fetch dependencies from cache
76+
id: cache-yarn
77+
uses: actions/cache@v2
78+
with:
79+
path: "**/node_modules"
80+
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
81+
82+
- name: Install dependencies
83+
if: steps.cache-yarn.outputs.cache-hit != 'true'
84+
run: yarn --frozen-lockfile
85+
86+
- name: Audit for vulnerabilities
87+
run: yarn _audit
88+
if: success()
89+
6690
build:
6791
name: Build
6892
needs: prebuild

docs/SECURITY.md

+19-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,28 @@
11
# Security Policy
22

3+
The code-server team (and Coder, the organization) care a lot about keeping the project secure and safe for end-users.
4+
5+
## Tools
6+
7+
We use a combination of tools to help us stay on top of vulnerabilities.
8+
9+
- [dependabot](https://dependabot.com/)
10+
- Submits pull requests to upgrade dependencies. We use dependabot's version upgrades as well as security updates.
11+
- code-scanning
12+
- [CodeQL](https://securitylab.github.com/tools/codeql/)
13+
- Semantic code analysis engine that runs on a regular schedule (see `codeql-analysis.yml`)
14+
- [trivy](https://github.com/aquasecurity/trivy)
15+
- Comprehensive vulnerability scanner that runs on PRs into the default branch and scans both our container image and repository code (see `trivy-scan-repo` and `trivy-scan-image` jobs in `ci.yaml`)
16+
- [`audit-ci`](https://github.com/IBM/audit-ci)
17+
- Audits npm and Yarn dependencies in CI (see "Audit for vulnerabilities" step in `ci.yaml`) on PRs into the default branch and fails CI if moderate or higher vulnerabilities(see the `audit.sh` script) are present.
18+
319
## Supported Versions
420

521
Coder sponsors development and maintenance of the code-server project. We will fix security issues within 90 days of receiving a report, and publish the fix in a subsequent release. The code-server project does not provide backports or patch releases for security issues at this time.
622

7-
| Version | Supported |
8-
| ------- | ------------------ |
9-
| 3.9.3 | :white_check_mark: |
23+
| Version | Supported |
24+
| ----------------------------------------------------- | ------------------ |
25+
| [Latest](https://github.com/cdr/code-server/releases) | :white_check_mark: |
1026

1127
## Reporting a Vulnerability
1228

lib/vscode/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@
195195
"tsec": "0.1.4",
196196
"typescript": "^4.3.0-dev.20210426",
197197
"typescript-formatter": "7.1.0",
198-
"underscore": "^1.8.2",
198+
"underscore": "^1.12.1",
199199
"vinyl": "^2.0.0",
200200
"vinyl-fs": "^3.0.0",
201201
"vscode-debugprotocol": "1.47.0",

lib/vscode/yarn.lock

+1-6
Original file line numberDiff line numberDiff line change
@@ -8915,16 +8915,11 @@ unc-path-regex@^0.1.2:
89158915
resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa"
89168916
integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo=
89178917

8918-
underscore@^1.8.2:
8918+
underscore@^1.8.2, underscore@~1.8.3:
89198919
version "1.13.1"
89208920
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.1.tgz#0c1c6bd2df54b6b69f2314066d65b6cde6fcf9d1"
89218921
integrity sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==
89228922

8923-
underscore@~1.8.3:
8924-
version "1.8.3"
8925-
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"
8926-
integrity sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=
8927-
89288923
undertaker-registry@^1.0.0:
89298924
version "1.0.1"
89308925
resolved "https://registry.yarnpkg.com/undertaker-registry/-/undertaker-registry-1.0.1.tgz#5e4bda308e4a8a2ae584f9b9a4359a499825cc50"

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@
144144
"clover"
145145
],
146146
"coveragePathIgnorePatterns": [
147-
"out"
147+
"/out"
148148
],
149149
"coverageThreshold": {
150150
"global": {

src/node/cli.ts

+9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import * as path from "path"
66
import { Args as VsArgs } from "../../typings/ipc"
77
import { canConnect, generateCertificate, generatePassword, humanPath, paths } from "./util"
88

9+
export enum Feature {
10+
/** Web socket compression. */
11+
PermessageDeflate = "permessage-deflate",
12+
}
13+
914
export enum AuthType {
1015
Password = "password",
1116
None = "none",
@@ -35,6 +40,7 @@ export interface Args extends VsArgs {
3540
"cert-key"?: string
3641
"disable-telemetry"?: boolean
3742
"disable-update-check"?: boolean
43+
enable?: string[]
3844
help?: boolean
3945
host?: string
4046
json?: boolean
@@ -128,6 +134,9 @@ const options: Options<Required<Args>> = {
128134
"Disable update check. Without this flag, code-server checks every 6 hours against the latest github release and \n" +
129135
"then notifies you once every week that a new release is available.",
130136
},
137+
// --enable can be used to enable experimental features. These features
138+
// provide no guarantees.
139+
enable: { type: "string[]" },
131140
help: { type: "boolean", short: "h", description: "Show this output." },
132141
json: { type: "boolean" },
133142
open: { type: "boolean", description: "Open in browser on startup. Does not work remotely." },

src/node/constants.ts

+1
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ export const version = pkg.version || "development"
2020
export const commit = pkg.commit || "development"
2121
export const rootPath = path.resolve(__dirname, "../..")
2222
export const tmpdir = path.join(os.tmpdir(), "code-server")
23+
export const isDevMode = commit === "development"

src/node/entry.ts

+4-149
Original file line numberDiff line numberDiff line change
@@ -1,163 +1,17 @@
1-
import { field, logger } from "@coder/logger"
2-
import * as cp from "child_process"
3-
import http from "http"
4-
import * as path from "path"
5-
import { CliMessage, OpenCommandPipeArgs } from "../../typings/ipc"
6-
import { plural } from "../common/util"
7-
import { createApp, ensureAddress } from "./app"
1+
import { logger } from "@coder/logger"
82
import {
9-
AuthType,
10-
DefaultedArgs,
113
optionDescriptions,
124
parse,
135
readConfigFile,
146
setDefaults,
157
shouldOpenInExistingInstance,
168
shouldRunVsCodeCli,
179
} from "./cli"
18-
import { coderCloudBind } from "./coder_cloud"
1910
import { commit, version } from "./constants"
11+
import { openInExistingInstance, runCodeServer, runVsCodeCli } from "./main"
2012
import * as proxyAgent from "./proxy_agent"
21-
import { register } from "./routes"
22-
import { humanPath, isFile, open } from "./util"
2313
import { isChild, wrapper } from "./wrapper"
2414

25-
export const runVsCodeCli = (args: DefaultedArgs): void => {
26-
logger.debug("forking vs code cli...")
27-
const vscode = cp.fork(path.resolve(__dirname, "../../lib/vscode/out/vs/server/fork"), [], {
28-
env: {
29-
...process.env,
30-
CODE_SERVER_PARENT_PID: process.pid.toString(),
31-
},
32-
})
33-
vscode.once("message", (message: any) => {
34-
logger.debug("got message from VS Code", field("message", message))
35-
if (message.type !== "ready") {
36-
logger.error("Unexpected response waiting for ready response", field("type", message.type))
37-
process.exit(1)
38-
}
39-
const send: CliMessage = { type: "cli", args }
40-
vscode.send(send)
41-
})
42-
vscode.once("error", (error) => {
43-
logger.error("Got error from VS Code", field("error", error))
44-
process.exit(1)
45-
})
46-
vscode.on("exit", (code) => process.exit(code || 0))
47-
}
48-
49-
export const openInExistingInstance = async (args: DefaultedArgs, socketPath: string): Promise<void> => {
50-
const pipeArgs: OpenCommandPipeArgs & { fileURIs: string[] } = {
51-
type: "open",
52-
folderURIs: [],
53-
fileURIs: [],
54-
forceReuseWindow: args["reuse-window"],
55-
forceNewWindow: args["new-window"],
56-
}
57-
58-
for (let i = 0; i < args._.length; i++) {
59-
const fp = path.resolve(args._[i])
60-
if (await isFile(fp)) {
61-
pipeArgs.fileURIs.push(fp)
62-
} else {
63-
pipeArgs.folderURIs.push(fp)
64-
}
65-
}
66-
67-
if (pipeArgs.forceNewWindow && pipeArgs.fileURIs.length > 0) {
68-
logger.error("--new-window can only be used with folder paths")
69-
process.exit(1)
70-
}
71-
72-
if (pipeArgs.folderURIs.length === 0 && pipeArgs.fileURIs.length === 0) {
73-
logger.error("Please specify at least one file or folder")
74-
process.exit(1)
75-
}
76-
77-
const vscode = http.request(
78-
{
79-
path: "/",
80-
method: "POST",
81-
socketPath,
82-
},
83-
(response) => {
84-
response.on("data", (message) => {
85-
logger.debug("got message from VS Code", field("message", message.toString()))
86-
})
87-
},
88-
)
89-
vscode.on("error", (error: unknown) => {
90-
logger.error("got error from VS Code", field("error", error))
91-
})
92-
vscode.write(JSON.stringify(pipeArgs))
93-
vscode.end()
94-
}
95-
96-
const main = async (args: DefaultedArgs): Promise<void> => {
97-
logger.info(`code-server ${version} ${commit}`)
98-
99-
logger.info(`Using user-data-dir ${humanPath(args["user-data-dir"])}`)
100-
logger.trace(`Using extensions-dir ${humanPath(args["extensions-dir"])}`)
101-
102-
if (args.auth === AuthType.Password && !args.password && !args["hashed-password"]) {
103-
throw new Error(
104-
"Please pass in a password via the config file or environment variable ($PASSWORD or $HASHED_PASSWORD)",
105-
)
106-
}
107-
108-
const [app, wsApp, server] = await createApp(args)
109-
const serverAddress = ensureAddress(server)
110-
await register(app, wsApp, server, args)
111-
112-
logger.info(`Using config file ${humanPath(args.config)}`)
113-
logger.info(`HTTP server listening on ${serverAddress} ${args.link ? "(randomized by --link)" : ""}`)
114-
115-
if (args.auth === AuthType.Password) {
116-
logger.info(" - Authentication is enabled")
117-
if (args.usingEnvPassword) {
118-
logger.info(" - Using password from $PASSWORD")
119-
} else if (args.usingEnvHashedPassword) {
120-
logger.info(" - Using password from $HASHED_PASSWORD")
121-
} else {
122-
logger.info(` - Using password from ${humanPath(args.config)}`)
123-
}
124-
} else {
125-
logger.info(` - Authentication is disabled ${args.link ? "(disabled by --link)" : ""}`)
126-
}
127-
128-
if (args.cert) {
129-
logger.info(` - Using certificate for HTTPS: ${humanPath(args.cert.value)}`)
130-
} else {
131-
logger.info(` - Not serving HTTPS ${args.link ? "(disabled by --link)" : ""}`)
132-
}
133-
134-
if (args["proxy-domain"].length > 0) {
135-
logger.info(` - ${plural(args["proxy-domain"].length, "Proxying the following domain")}:`)
136-
args["proxy-domain"].forEach((domain) => logger.info(` - *.${domain}`))
137-
}
138-
139-
if (args.link) {
140-
try {
141-
await coderCloudBind(serverAddress.replace(/^https?:\/\//, ""), args.link.value)
142-
logger.info(" - Connected to cloud agent")
143-
} catch (err) {
144-
logger.error(err.message)
145-
wrapper.exit(1)
146-
}
147-
}
148-
149-
if (!args.socket && args.open) {
150-
// The web socket doesn't seem to work if browsing with 0.0.0.0.
151-
const openAddress = serverAddress.replace("://0.0.0.0", "://localhost")
152-
try {
153-
await open(openAddress)
154-
logger.info(`Opened ${openAddress}`)
155-
} catch (error) {
156-
logger.error("Failed to open", field("address", openAddress), field("error", error))
157-
}
158-
}
159-
}
160-
16115
async function entry(): Promise<void> {
16216
proxyAgent.monkeyPatch(false)
16317

@@ -170,7 +24,8 @@ async function entry(): Promise<void> {
17024
if (isChild(wrapper)) {
17125
const args = await wrapper.handshake()
17226
wrapper.preventExit()
173-
return main(args)
27+
await runCodeServer(args)
28+
return
17429
}
17530

17631
const cliArgs = parse(process.argv.slice(2))

0 commit comments

Comments
 (0)