Compare commits

..

284 Commits

Author SHA1 Message Date
Asher
0c802ba165 Remove node-gyp install (#6831)
Seems to install fine without it now.
2024-06-08 20:07:51 -08:00
Asher
1bd2b9cf08 Fix segfault in CI (#6830)
Setting DISABLE_V8_COMPILE_CACHE=1 seems to fix it.
2024-06-08 20:07:24 -08:00
Asher
3b467dec95 Update changelog for 1.90.0 2024-06-06 15:05:12 -08:00
Olivier Benz
6d9530aa6b Update Code to 1.90.0 (#6824)
Additionally:

- Update Node to 20.11.1
- Update documentation
- Disable extension signature verification

This works around an issue where the Open VSX is not returning the
expected zip.  Verification is skipped later anyway because
@vscode/vsce-sign is missing in the OSS version.
2024-06-06 15:02:13 -08:00
dependabot[bot]
fc47b4f1c5 chore: bump aquasecurity/trivy-action from 0.19.0 to 0.21.0 (#6819)
Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.19.0 to 0.21.0.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](d710430a67...fd25fed697)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-03 10:44:54 -08:00
dependabot[bot]
479eb5bfa5 chore: bump @typescript-eslint/eslint-plugin from 6.21.0 to 7.0.0 (#6818)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.21.0 to 7.0.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.0.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-03 10:44:33 -08:00
Paweł Wiśniewski
095c072a43 Add Ubuntu Noble image (#6812) 2024-05-24 20:02:32 +00:00
XiaoZhang
4ff509d8db Allow emptyDir type volume mounts (#6803) 2024-05-22 10:52:42 -08:00
Simon Merschjohann
efc6edf536 Support copying to clipboard from CLI (#6807)
Use --stdin-to-clipboard or -c to pass stdin to clipboard
2024-05-21 10:39:36 -08:00
Asher
3b6ad479a6 Release v4.89.1 and v4.89.0 2024-05-14 10:17:35 -08:00
Olivier Benz
effc6e95b4 Update Code to 1.89.1 (#6796) 2024-05-13 10:41:25 -08:00
Asher
ab4b36f573 Fix setuptools install on macOS
This is erroring now with "This environment is externally managed".
2024-05-07 13:41:21 -08:00
Asher
0f4791b816 Add remote machine ID to telemetry 2024-05-07 11:35:01 -08:00
Asher
97653152dd Flush telemetry appender on dispose 2024-05-06 19:36:52 -08:00
Asher
2633bca30b Move telemetry endpoint to product service
This will let us use it in the client.
2024-05-06 18:39:39 -08:00
Asher
125a972c81 Do not add extra args in toCodeArgs
It should only convert the args that are passed in.
2024-05-06 18:39:22 -08:00
Asher
7050002fb6 Add missing semicolon 2024-05-06 18:39:21 -08:00
Asher
4563517d90 Add isContainer property to telemetry 2024-05-06 18:37:41 -08:00
dependabot[bot]
b8cdab2184 chore: bump ws and @types/ws (#6775)
Bumps [ws](https://github.com/websockets/ws) and [@types/ws](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/ws). These dependencies needed to be updated together.

Updates `ws` from 8.14.2 to 8.17.0
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.14.2...8.17.0)

Updates `@types/ws` from 8.5.5 to 8.5.10
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/ws)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: "@types/ws"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-06 14:17:49 -08:00
dependabot[bot]
264e023ab8 chore: bump eslint from 8.53.0 to 8.57.0 (#6776)
Bumps [eslint](https://github.com/eslint/eslint) from 8.53.0 to 8.57.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.53.0...v8.57.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-06 14:17:30 -08:00
dependabot[bot]
ea815df22d chore: bump semver and @types/semver (#6777)
Bumps [semver](https://github.com/npm/node-semver) and [@types/semver](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/semver). These dependencies needed to be updated together.

Updates `semver` from 7.5.4 to 7.6.0
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v7.5.4...v7.6.0)

Updates `@types/semver` from 7.5.2 to 7.5.8
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/semver)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: "@types/semver"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-06 14:17:15 -08:00
dependabot[bot]
6757907c8b chore: bump i18next from 23.10.1 to 23.11.3 (#6778)
Bumps [i18next](https://github.com/i18next/i18next) from 23.10.1 to 23.11.3.
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v23.10.1...v23.11.3)

---
updated-dependencies:
- dependency-name: i18next
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-06 14:16:54 -08:00
dependabot[bot]
2adb215d03 chore: bump robinraju/release-downloader from 1.9 to 1.10 (#6779)
Bumps [robinraju/release-downloader](https://github.com/robinraju/release-downloader) from 1.9 to 1.10.
- [Release notes](https://github.com/robinraju/release-downloader/releases)
- [Commits](https://github.com/robinraju/release-downloader/compare/v1.9...v1.10)

---
updated-dependencies:
- dependency-name: robinraju/release-downloader
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-06 14:16:27 -08:00
dependabot[bot]
1a7265b392 chore: bump azure/setup-helm from 3.5 to 4 (#6780)
Bumps [azure/setup-helm](https://github.com/azure/setup-helm) from 3.5 to 4.
- [Release notes](https://github.com/azure/setup-helm/releases)
- [Changelog](https://github.com/Azure/setup-helm/blob/main/CHANGELOG.md)
- [Commits](https://github.com/azure/setup-helm/compare/v3.5...v4)

---
updated-dependencies:
- dependency-name: azure/setup-helm
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-06 14:16:06 -08:00
Olivier Benz
e6dd7fe228 Update Code to 1.89.0 (#6783) 2024-05-06 14:14:53 -08:00
Asher
fb2afbd9d6 Handle undefined body
In the latest Express it seems the body is undefined when no data is
passed (instead of being empty).
2024-04-16 11:29:12 -08:00
Asher
3d8d544f89 Refactor VS Code routes to match others 2024-04-16 11:00:33 -08:00
Asher
323a1f3234 Only require unsafe-perm if you are root
Remove it from the docs, as the error message should be sufficient and
it seems weird to recommend unsafe-perm by default.
2024-04-16 10:48:46 -08:00
Asher
b8d830b826 Update path syntax for Express
It seems that * matches a literal * now, so we have to use a regular
expression.

Parentheses around a parameter no longer works (it causes it to match on
the parameter name literally) and I am not sure why we had it anyway as
it had no effect previously.

Matching with a leading / does not appear to work either, but we do not
need the leading / anyway since the proxy logic was changed to use the
whole path.  Consequently it will never be / anymore from what I can
tell but I left that check in just in case.  I turned it into a named
parameter as well, because that seems better.
2024-04-16 09:54:33 -08:00
Asher
417c1f36cb Release 4.23.1 2024-04-15 16:37:01 -08:00
Asher
3eb9cf7a08 Update express and qs
It does not appear we have to pin qs anymore.
2024-04-15 16:32:52 -08:00
dependabot[bot]
f81fe3030a chore: bump tar from 6.2.0 to 6.2.1 (#6753)
Bumps [tar](https://github.com/isaacs/node-tar) from 6.2.0 to 6.2.1.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v6.2.0...v6.2.1)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-15 16:25:27 -08:00
dependabot[bot]
4bc9956537 chore: bump tar from 6.1.11 to 6.2.1 in /test (#6752)
Bumps [tar](https://github.com/isaacs/node-tar) from 6.1.11 to 6.2.1.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v6.1.11...v6.2.1)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-15 16:25:04 -08:00
Olivier Benz
9a28bc29db Update Code to 1.88.1 (#6754)
* Update Code to 1.88.1
* Install node-gyp

---------

Co-authored-by: Asher <ash@coder.com>
2024-04-15 15:00:21 -08:00
Asher
deebb21345 Release 4.23.0 2024-04-08 13:24:39 -08:00
Asher
73e615da4e Fix extension installation test
This throws now that the exit is non-zero.
2024-04-05 17:39:21 -08:00
Asher
bec6ab2678 Fix masking exit code
Addresses the part of #6367 that we can fix.
2024-04-05 16:31:58 -08:00
dependabot[bot]
ebd79ed958 chore: bump aquasecurity/trivy-action from 0.18.0 to 0.19.0 (#6739)
Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.18.0 to 0.19.0.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](062f259268...d710430a67)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-05 14:24:18 -08:00
dependabot[bot]
30d343c0bd chore: bump follow-redirects from 1.15.4 to 1.15.6 (#6725)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-05 14:22:50 -08:00
dependabot[bot]
71780f6f00 chore: bump typescript from 5.3.3 to 5.4.3 (#6736)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.3.3 to 5.4.3.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v5.3.3...v5.4.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-05 14:22:30 -08:00
dependabot[bot]
93f9dfcb1d chore: bump i18next from 23.8.2 to 23.10.1 (#6738)
Bumps [i18next](https://github.com/i18next/i18next) from 23.8.2 to 23.10.1.
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v23.8.2...v23.10.1)

---
updated-dependencies:
- dependency-name: i18next
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-05 14:22:07 -08:00
dependabot[bot]
1abb2ee567 chore: bump softprops/action-gh-release from 1 to 2 (#6740)
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 1 to 2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v1...v2)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-05 14:21:48 -08:00
dependabot[bot]
1c5bfeeb99 chore: bump tj-actions/changed-files from 42 to 44 (#6741)
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 42 to 44.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v42...v44)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-05 14:21:27 -08:00
Puneeth Rai
bae68548d0 Update Node to 18.18.2 (#6676) 2024-04-05 14:21:01 -08:00
Olivier Benz
0cca7c67a4 Update Code to 1.88.0 (#6745) 2024-04-05 14:20:28 -08:00
Asher
45e96ec3b0 Shorten bug dropdown descriptions 2024-03-14 12:19:13 -08:00
Asher
66364429e3 Release 4.22.1 2024-03-14 12:16:35 -08:00
Asher
0e384d5442 Tweak issue templates
- Remove the redundant title prefix.
- Remove outdated assignees.
- Improve reproduction step description (trying to get folks to submit
  more specific/detailed reproductions).
- Render logs with shell (not sure if this actually changes anything).
- Use dropdowns for testing in VS Code and Codespaces.  I think the
  existing checkboxes are still confusing so hopefully this sorts it.
2024-03-14 12:16:33 -08:00
Olivier Benz
760d1318e9 Update Code to 1.87.2 (#6721) 2024-03-12 19:30:02 +00:00
Asher
c65b1f2870 Continue release drafting on Codecov failure 2024-03-12 09:41:21 -08:00
Asher
132f7d1470 Default keepAlive to true for proxy agent 2024-03-11 14:13:21 -08:00
Olivier Benz
8c65ff8d0d Update Code to 1.87.1 (#6714) 2024-03-11 12:51:08 -08:00
dependabot[bot]
f9c0624f85 chore: bump @typescript-eslint/eslint-plugin from 6.20.0 to 6.21.0 (#6701)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.20.0 to 6.21.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.21.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-07 11:04:03 -09:00
dependabot[bot]
4c4c566d86 chore: bump proxy-agent from 6.3.1 to 6.4.0 (#6702)
Bumps [proxy-agent](https://github.com/TooTallNate/proxy-agents/tree/HEAD/packages/proxy-agent) from 6.3.1 to 6.4.0.
- [Release notes](https://github.com/TooTallNate/proxy-agents/releases)
- [Changelog](https://github.com/TooTallNate/proxy-agents/blob/main/packages/proxy-agent/CHANGELOG.md)
- [Commits](https://github.com/TooTallNate/proxy-agents/commits/proxy-agent@6.4.0/packages/proxy-agent)

---
updated-dependencies:
- dependency-name: proxy-agent
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-07 11:03:16 -09:00
dependabot[bot]
720d14db3e chore: bump rotating-file-stream from 3.1.1 to 3.2.1 (#6704)
Bumps [rotating-file-stream](https://github.com/iccicci/rotating-file-stream) from 3.1.1 to 3.2.1.
- [Changelog](https://github.com/iccicci/rotating-file-stream/blob/master/CHANGELOG.md)
- [Commits](https://github.com/iccicci/rotating-file-stream/compare/v3.1.1...v3.2.1)

---
updated-dependencies:
- dependency-name: rotating-file-stream
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-07 10:32:06 -09:00
dependabot[bot]
5453d02872 chore: bump aquasecurity/trivy-action from 0.16.1 to 0.18.0 (#6705)
Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.16.1 to 0.18.0.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](d43c1f16c0...062f259268)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-07 10:20:04 -09:00
dependabot[bot]
9f2c776a77 chore: bump prettier-plugin-sh from 0.13.1 to 0.14.0 (#6700)
Bumps [prettier-plugin-sh](https://github.com/un-ts/prettier) from 0.13.1 to 0.14.0.
- [Release notes](https://github.com/un-ts/prettier/releases)
- [Changelog](https://github.com/un-ts/prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/un-ts/prettier/compare/prettier-plugin-sh@0.13.1...prettier-plugin-sh@0.14.0)

---
updated-dependencies:
- dependency-name: prettier-plugin-sh
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-07 10:18:02 -09:00
dependabot[bot]
66c7f7d8b1 chore: bump @typescript-eslint/parser from 6.17.0 to 6.21.0 (#6703)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.17.0 to 6.21.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.21.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-07 10:17:25 -09:00
dependabot[bot]
107a3fd410 chore: bump codecov/codecov-action from 3 to 4 (#6706)
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3 to 4.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-07 10:15:42 -09:00
Asher
56b5992280 Pin Arch Linux action version
We are still getting the old one, I think?
2024-03-06 14:10:57 -09:00
Asher
275c130845 Update Arch Linux action username
This broke due to the username being changed, and GitHub does not appear
to put any redirects in place.
2024-03-06 14:04:32 -09:00
Asher
223ecf7c30 Release v4.22.0 2024-03-04 06:52:54 -09:00
Olivier Benz
e5d145fdf3 Update Code to 1.87.0 (#6697)
Fixes https://github.com/coder/code-server/issues/6694
2024-02-29 12:30:03 -09:00
Asher
2248c8bdd4 Correct changelog link 2024-02-28 14:56:38 -09:00
Asher
d2dfeedb2f Release v4.21.2 2024-02-28 14:22:31 -09:00
Asher
460a4564c3 Revert "chore: bump codecov/codecov-action from 3 to 4 (#6652)"
This reverts commit 63beaaabd7.

It appears to be no longer capable of finding git.
2024-02-28 14:04:55 -09:00
Muhammad Atif Ali
963fcfc3a5 docs: add coder module as an installation method (#6692)
Co-authored-by: Asher <ash@coder.com>
2024-02-28 22:06:49 +00:00
dependabot[bot]
75611411b4 chore: bump ip from 1.1.5 to 1.1.9 in /test (#6682)
Bumps [ip](https://github.com/indutny/node-ip) from 1.1.5 to 1.1.9.
- [Commits](https://github.com/indutny/node-ip/compare/v1.1.5...v1.1.9)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-21 13:50:59 -09:00
dependabot[bot]
1e5666b68e chore: bump ip from 1.1.8 to 1.1.9 (#6681)
Bumps [ip](https://github.com/indutny/node-ip) from 1.1.8 to 1.1.9.
- [Commits](https://github.com/indutny/node-ip/compare/v1.1.8...v1.1.9)

---
updated-dependencies:
- dependency-name: ip
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-21 13:50:49 -09:00
Olivier Benz
9d70cbc8b2 Update Code to 1.86.2 (#6677) 2024-02-15 22:12:56 +00:00
ckesc
853ab407de Update FAQ: clarify about hashed pass and compose file (#6671) 2024-02-12 22:11:45 +00:00
Asher
c31d2a0e37 Release v4.21.1 2024-02-09 13:02:44 -09:00
Dmitry Sharshakov
45164bf749 Use rpm to install in Fedora image (#6670)
Dnf will pull caches if invoked for local file install and is also unnecessary
2024-02-09 12:56:57 -09:00
Dmitry Sharshakov
a2d35ad815 docker: add Fedora 39 and openSUSE Tumbleweed based images (#6669) 2024-02-08 12:31:50 -09:00
Olivier Benz
76e6f75758 Update Code to 1.86.1 (#6668) 2024-02-08 11:10:43 -09:00
Asher
413c47a86d Update Node to 18.17.1
For https://github.com/coder/code-server/issues/6666.
2024-02-07 21:11:27 -09:00
Asher
5b62943216 Release v4.21.0 2024-02-05 09:41:51 -09:00
dependabot[bot]
84ca27278b chore: bump eslint-config-prettier from 9.0.0 to 9.1.0 (#6648)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 9.0.0 to 9.1.0.
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v9.0.0...v9.1.0)

---
updated-dependencies:
- dependency-name: eslint-config-prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-02 02:14:33 +00:00
dependabot[bot]
1471a152ff chore: bump i18next from 23.7.6 to 23.8.2 (#6645)
Bumps [i18next](https://github.com/i18next/i18next) from 23.7.6 to 23.8.2.
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v23.7.6...v23.8.2)

---
updated-dependencies:
- dependency-name: i18next
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-01 16:39:31 -09:00
dependabot[bot]
6adbfc461b chore: bump @typescript-eslint/eslint-plugin from 6.16.0 to 6.20.0 (#6646)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.16.0 to 6.20.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.20.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-01 16:39:14 -09:00
dependabot[bot]
2a55212027 chore: bump prettier from 3.1.1 to 3.2.4 (#6647)
Bumps [prettier](https://github.com/prettier/prettier) from 3.1.1 to 3.2.4.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.1.1...3.2.4)

---
updated-dependencies:
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-01 16:39:00 -09:00
dependabot[bot]
b63fda4bf7 chore: bump eslint-plugin-prettier from 5.0.0 to 5.1.3 (#6649)
Bumps [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) from 5.0.0 to 5.1.3.
- [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/master/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-plugin-prettier/compare/v5.0.0...v5.1.3)

---
updated-dependencies:
- dependency-name: eslint-plugin-prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-01 16:38:45 -09:00
dependabot[bot]
ab17495e3a chore: bump actions/cache from 3 to 4 (#6650)
Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-01 16:38:25 -09:00
dependabot[bot]
53b0fda510 chore: bump robinraju/release-downloader from 1.8 to 1.9 (#6651)
Bumps [robinraju/release-downloader](https://github.com/robinraju/release-downloader) from 1.8 to 1.9.
- [Release notes](https://github.com/robinraju/release-downloader/releases)
- [Commits](https://github.com/robinraju/release-downloader/compare/v1.8...v1.9)

---
updated-dependencies:
- dependency-name: robinraju/release-downloader
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-01 16:37:57 -09:00
dependabot[bot]
63beaaabd7 chore: bump codecov/codecov-action from 3 to 4 (#6652)
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3 to 4.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-01 16:37:42 -09:00
dependabot[bot]
2db0184c4a chore: bump github/codeql-action from 2 to 3 (#6653)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-01 16:37:33 -09:00
dependabot[bot]
dd9cefab66 chore: bump tj-actions/changed-files from 41 to 42 (#6654)
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 41 to 42.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v41...v42)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-01 16:37:09 -09:00
Olivier Benz
1d774d01bf Update Code to 1.86.0 (#6655) 2024-02-01 16:36:47 -09:00
Asher
d6ef385de2 Release v4.20.1 2024-01-22 08:34:02 -09:00
Olivier Benz
e76afa4a2b Update Code to 1.85.2 (#6631) 2024-01-19 22:30:16 +00:00
Asher
fdb46d3fe5 Exit with 1 when VS Code CLI errors
Addresses part of #6367.  The script bundled with VS Code still has the
same problem but it would be better to fix that one upstream.
2024-01-11 12:46:09 -09:00
Asher
d49b3bf159 Fix query string being double-encoding over path proxy
Instead of trying to piece together the original URL and re-encode what
needs to be re-encoded, strip out the base from the original URL.

Fixes #6307.
2024-01-11 12:26:06 -09:00
dependabot[bot]
e87499c301 chore: bump follow-redirects from 1.15.3 to 1.15.4 (#6624)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.3 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.3...v1.15.4)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-11 02:32:57 +00:00
dependabot[bot]
cc68c0fb0f chore: bump @typescript-eslint/parser from 6.9.1 to 6.17.0 (#6622)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.9.1 to 6.17.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.17.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-05 13:46:28 -09:00
dependabot[bot]
749e105cd9 chore: bump @types/node from 18.18.1 to 18.19.4 (#6613)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 18.18.1 to 18.19.4.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-05 13:33:10 -09:00
dependabot[bot]
94f759a53c chore: bump actions/download-artifact from 3 to 4 (#6609)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-05 13:32:33 -09:00
dependabot[bot]
2786f60752 chore: bump actions/upload-artifact from 3 to 4 (#6610)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-05 13:32:10 -09:00
dependabot[bot]
aea28cb499 chore: bump dawidd6/action-download-artifact from 2 to 3 (#6612)
Bumps [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) from 2 to 3.
- [Release notes](https://github.com/dawidd6/action-download-artifact/releases)
- [Commits](https://github.com/dawidd6/action-download-artifact/compare/v2...v3)

---
updated-dependencies:
- dependency-name: dawidd6/action-download-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-05 13:29:50 -09:00
dependabot[bot]
2cabe799e2 chore: bump @typescript-eslint/parser from 6.9.1 to 6.16.0 (#6614)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.9.1 to 6.16.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.16.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-05 13:28:30 -09:00
dependabot[bot]
c1be39abc7 chore: bump prettier from 3.0.3 to 3.1.1 (#6615)
Bumps [prettier](https://github.com/prettier/prettier) from 3.0.3 to 3.1.1.
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.0.3...3.1.1)

---
updated-dependencies:
- dependency-name: prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-05 13:28:15 -09:00
dependabot[bot]
21e798ccdf chore: bump aquasecurity/trivy-action from 0.14.0 to 0.16.1 (#6621)
Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.14.0 to 0.16.1.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](2b6a709cf9...d43c1f16c0)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-05 13:28:00 -09:00
dependabot[bot]
871030e997 chore: bump typescript from 5.2.2 to 5.3.3 (#6616)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.2.2 to 5.3.3.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v5.2.2...v5.3.3)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-05 13:27:42 -09:00
dependabot[bot]
a143dcf111 chore: bump @typescript-eslint/eslint-plugin from 6.11.0 to 6.16.0 (#6617)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.11.0 to 6.16.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.16.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-05 13:27:25 -09:00
dependabot[bot]
5214555683 chore: bump tj-actions/changed-files from 40 to 41 in /.github/workflows (#6618)
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 40 to 41.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v40...v41)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-05 13:27:05 -09:00
Merith
ff0fcf6cde Fix non-functional Docker Hub link (#6595)
registry.hub.docker.com leads to an blank white page
removing "registry' from the URL fixes it and takes the user to the correct page
2024-01-05 11:22:33 -09:00
Asher
07901026a0 Release v4.20.0 2023-12-21 12:53:25 -09:00
Asher
d0215eca88 Tweak bug report template
These checkboxes keep getting checked despite the submitter using an
insecure context or not having tested upstream.  I think two things are
at play here:

1. Folks might be interpreting "cannot reproduce" as "did not
   reproduce" or "did not have time to reproduce".
2. The checkboxes are required to submit the issue so folks might be
   marking them just so they can get their issue submitted; maybe they
   are not even reading the checkboxes and are just seeing the error
   that they need to be marked and blindly marking them because while
   in some cases folks will add "I had to check this but it is not
   true", usually they say nothing.

In any case, hopefully these changes make the checkboxes more accurate,
and then if they are unchecked we can ask them to go reproduce in VS
Code or use a secure context or whatever the case may be.
2023-12-18 13:56:35 -09:00
Dov Benyomin Sohacheski
d6c5a4af9c Add Debian bookworm config to bakefile (#6590) 2023-12-18 21:30:16 +00:00
Olivier Benz
0b84523121 Update Code to 1.85.1 (#6588) 2023-12-18 20:18:44 +00:00
Olivier Benz
45694d38c4 Update Code to 1.85.0 (#6573) 2023-12-15 12:38:01 -09:00
Dov Benyomin Sohacheski
d9fe46a6be Update and organize release image packages, add wget (#6581) 2023-12-15 20:32:14 +00:00
Ammar Bandukwala
6f078a48a6 Improve README callout to coder/coder (#6579) 2023-12-12 14:23:54 -09:00
Dov Benyomin Sohacheski
7649b6e6ca Update base release image to Debian:12 (#6574) 2023-12-12 11:37:17 -09:00
Jeff Miller
9622830518 Disable "Show Local" button, add --disable-file-uploads option and add file operation trace level logs (#6557) 2023-12-07 12:10:22 -09:00
Asher
26a3437849 Use debug instead of trace
Trace outputs stack traces which is entirely unnecessary for these two
log entries and makes the logs noisier than they need to be.
2023-12-06 13:19:36 -09:00
Evan Rush
1fac50d6f6 Fix Helm boolean environment variable (#6563) 2023-12-04 19:32:16 +00:00
Asher
3e8100b70e Release v4.19.1 2023-11-29 12:23:25 -09:00
Asher
0c98611e6b Ensure we only ever set workspace initialized to true
This is just a guard in case there are paths where the workspace is
already marked as initialized but the workspace configuration is not and
we end up actually un-initializing it.
2023-11-27 17:36:26 -09:00
Asher
73cb236535 Add back local storage patch
And fix the workspace bug.  It is caused by an issue with how some
global variables are being used asynchronously and is exacerbated by the
delay reading settings from the remote introduces.

1. The workspace is created and is marked as not initialized.
2. The configuration's change handler is triggered, and now
   initialization is complete.
3. The handler tries to set the global workspace variable to initialized
   but the workspace has not been set yet so we get an undefined error.
4. The workspace global is now set, but it is set to the old value with
   initialized still set to false.
5. Workspace is never marked as initialized until something else
   triggers the on change handler again.

Fixes #3061, and closes #6546.

My guess is this logic changed in one of the VS Code updates,
introducing this async bug but never getting caught probably because for
them the settings are always local thus minimal delay.
2023-11-27 17:25:38 -09:00
Asher
9ba66ec468 Use machine settings for e2e tests
User settings are browser-based so use machine settings instead.
2023-11-20 15:42:34 -09:00
Asher
09dd5fe44d Delete local storage patch
The main goal of this patch was to make user settings stored on disk
instead of in the browser, but this stopped working some time ago.  Not
only that but it is causing a bug where a workspace will not fully open.

A secondary goal was to fix the Vim extension but the extension appears
to work just fine without this change now (both the server and browser
versions).

This patch is not useful anymore anyway because there are remote-level
settings that *do* get stored on disk and can be used instead of
user-level settings when necessary.

Fixes #3061, and possibly #6153.
2023-11-20 13:32:59 -09:00
Quentin Quaadgras
958c5203ec Update Termux docs on how to enable keyboard shortcuts and tab key (#6539) 2023-11-20 08:16:17 -09:00
Asher
edf078d1d2 Release v4.19.0 2023-11-20 07:29:25 -09:00
Asher
984fb135dc Fix node-gyp failure on macOS (#6537) 2023-11-16 10:10:36 -09:00
Olivier Benz
9658969084 Update Code to 1.84.2 (#6524) 2023-11-14 13:44:21 -09:00
Asher
da254c39ee Set Node version in a single place (#6534)
This should make it much easier to update.  Also use 18.15.0
specifically since that is what VS Code ships with.

Additionally, it fixes the post-install script being skipped due to
a Yarn v1 bug that happens when Yarn installs node-gyp, which
it does because 18.18 onward stopped bundling node-gyp.
2023-11-14 12:45:56 -09:00
dependabot[bot]
239df56634 chore: bump @typescript-eslint/eslint-plugin from 6.7.2 to 6.11.0 (#6533)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 6.7.2 to 6.11.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.11.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-14 09:38:31 -09:00
dependabot[bot]
c285b99c74 chore: bump eslint from 8.49.0 to 8.53.0 (#6532)
Bumps [eslint](https://github.com/eslint/eslint) from 8.49.0 to 8.53.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.49.0...v8.53.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-14 09:36:26 -09:00
dependabot[bot]
f64bc022e9 chore: bump i18next from 23.5.1 to 23.7.6 (#6531)
Bumps [i18next](https://github.com/i18next/i18next) from 23.5.1 to 23.7.6.
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v23.5.1...v23.7.6)

---
updated-dependencies:
- dependency-name: i18next
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-14 09:27:30 -09:00
dependabot[bot]
22c54c3b2e chore: bump eslint-plugin-import from 2.28.1 to 2.29.0 (#6507)
Bumps [eslint-plugin-import](https://github.com/import-js/eslint-plugin-import) from 2.28.1 to 2.29.0.
- [Release notes](https://github.com/import-js/eslint-plugin-import/releases)
- [Changelog](https://github.com/import-js/eslint-plugin-import/blob/main/CHANGELOG.md)
- [Commits](https://github.com/import-js/eslint-plugin-import/compare/v2.28.1...v2.29.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-import
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-14 09:27:10 -09:00
dependabot[bot]
ae75f76e30 chore: bump aquasecurity/trivy-action from 0.13.1 to 0.14.0 (#6530)
Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.13.1 to 0.14.0.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](f78e9ecf42...2b6a709cf9)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-14 09:26:40 -09:00
dependabot[bot]
53d856d3c6 chore: bump @babel/traverse from 7.16.8 to 7.23.2 in /test (#6495)
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.16.8 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)

---
updated-dependencies:
- dependency-name: "@babel/traverse"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-14 09:26:04 -09:00
dependabot[bot]
4e4d510238 chore: bump docker/setup-qemu-action from 2 to 3 (#6464)
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-14 09:25:33 -09:00
dependabot[bot]
3a0f4a2773 chore: bump i18next from 23.5.1 to 23.6.0 (#6508)
Bumps [i18next](https://github.com/i18next/i18next) from 23.5.1 to 23.6.0.
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v23.5.1...v23.6.0)

---
updated-dependencies:
- dependency-name: i18next
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-14 09:24:53 -09:00
dependabot[bot]
cbc17516fd chore: bump @typescript-eslint/parser from 6.7.2 to 6.9.1 (#6511)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 6.7.2 to 6.9.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v6.9.1/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-14 09:23:33 -09:00
dependabot[bot]
c4efcaf079 chore: bump actions/setup-node from 3 to 4 (#6512)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3 to 4.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-14 09:23:05 -09:00
dependabot[bot]
f44b57393c chore: bump docker/login-action from 2 to 3 (#6513)
Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-14 09:21:54 -09:00
dependabot[bot]
3fc30cae3e chore: bump aquasecurity/trivy-action from 0.12.0 to 0.13.1 (#6514)
Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.12.0 to 0.13.1.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](fbd16365eb...f78e9ecf42)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-14 09:21:03 -09:00
dependabot[bot]
91f8ec6295 chore: bump tj-actions/changed-files from 39 to 40 (#6515)
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 39 to 40.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v39...v40)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-14 09:20:36 -09:00
Asher
11e6e656c0 Release v4.18.0 2023-10-20 12:03:13 -08:00
Olivier Benz
d7a2b4936a Update Code to 1.83.1 (#6488)
* Update Code to 1.83.1

* Patch out lookbehind for Safari support

Not sure why it needs a lookbehind unless a number followed by a capital
letter is not supposed to be considered a new word, which seems wrong to
me.  The tests do not contain any numbers so I can only guess.

---------

Co-authored-by: Asher <ash@coder.com>
2023-10-19 00:50:21 +00:00
Asher
c2d79d94f9 Use secure context in bug report template
Some folks run over localhost, which will work just fine for service
workers.
2023-10-11 17:19:19 -08:00
dependabot[bot]
9fec2d7cad chore: bump docker/setup-buildx-action from 2 to 3 (#6463)
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-11 15:51:24 -08:00
dependabot[bot]
80dfb2b2a9 chore: bump actions/checkout from 3 to 4 (#6462)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-04 15:50:11 -08:00
Asher
27e7b931e7 Remove mention of legacy extension API
We would like to shut this down.
2023-10-04 15:44:54 -08:00
liuxhit
db9f678477 Update default nginx config in guide.md (#6471)
update nginx config to avoid wss error when expose code-server using a custom domain and a custom port via nginx.

see also: 
[issue of code-server](https://github.com/coder/code-server/issues/4443)
[different between `$host` and `$http_host`](https://stackoverflow.com/a/76875724)
2023-10-04 10:41:35 -08:00
Olivier Benz
c095c26dbc Update Code to 1.82.3 (#6472) 2023-10-04 17:17:27 +00:00
dependabot[bot]
262f66abf6 chore: bump @types/node from 18.17.18 to 18.18.1 (#6467)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 18.17.18 to 18.18.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-02 13:25:52 -08:00
dependabot[bot]
8ee45686b0 chore: bump aquasecurity/trivy-action from 0.11.2 to 0.12.0 (#6461)
Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.11.2 to 0.12.0.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](41f05d9ecf...fbd16365eb)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-02 13:24:45 -08:00
dependabot[bot]
512d97f22f chore: bump tj-actions/changed-files from 38 to 39 (#6460)
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 38 to 39.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v38...v39)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-02 13:24:15 -08:00
Daniel T. Lee
897e0ae1da Modify manifest for window control overlay support (#6468)
Since the release of code-server v4.17.0 (Code 1.82), "Command Center" has become a default option. However, the current code-server PWA app lacks support for the Windows control overlay, resulting in an untidy appearance of the title bar. This commit introduces modifications to the manifest file to enable support for the window control overlay.
2023-10-02 18:03:37 +00:00
Asher
f4bf492051 Release v4.17.1 2023-09-29 15:21:48 -08:00
Asher
2eba7af117 Use code-server commit in product.json
Also remove github.com from the trusted domains.  This causes the
browser to block the popup instead (probably because the space between
interaction and popup is too great), which is difficult to notice in
Chromium.  Even in Firefox with the extra bar they add at the top it can
be easy to miss.
2023-09-29 13:58:01 -08:00
Asher
0dc59c0da2 Add trusted extension list
Also trust github.com to make the auth flow smoother.
2023-09-29 10:39:00 -08:00
Asher
6275520348 Fix incorrect argon2 target in arm builds (#6453)
* Fix building from source on arm

Not building from source causes argon2 to pull the wrong arch, so we
have to build from source.

But building from source is causing the new Kerberos module to fail on
arm64 and keytar to fail on both.

The latter has been very difficult to debug because the GitHub image
provides a different result to containers based on Ubuntu 20.04.
Because of this, use a container instead.

Use debian:buster as the container because it is easier to set up the
architecture sources (no need to modify the sources) and because it
seems to come with glibc 2.28 rather than 2.31.

Also use the exact version of Node (18.15.0) for reproducibility.

* Set owner and group during tar to zero

Otherwise you get IDs that can cause (benign) errors while extracting,
which might be confusing.  At the very least, I did not see these errors
from previous tars (although they seem to use 1001).

There is no guarantee what IDs might exist so 0 seems the most
reasonable.
2023-09-27 19:17:47 -08:00
Asher
2bb51a25a9 Refresh proxy URI patch 2023-09-26 12:19:13 -08:00
Asher
7a213161f2 Build from source on cross-compile step
The comment said the issue with argon2 was related to CentOS 7 but the
cross-compile steps never used CentOS 7 so maybe the real issue is with
the architecture.
2023-09-26 09:58:53 -08:00
Asher
a1131fadf2 Enable secret storage (#6450)
* Remove unused dependency patch

* Enable secret storage based on local storage

* Remove unnecessary GitHub auth patch

It works now without the patch.
2023-09-26 08:35:41 -08:00
Asher
468cf5c6ce Update npm publish workflow to use v18 2023-09-22 17:53:56 -08:00
Asher
800bf364d6 Release v4.17.0 2023-09-22 17:49:40 -08:00
DevMirza
5428442628 feat(lang): Add Urdu Locale (#6444) 2023-09-22 17:16:51 -08:00
Dov Benyomin Sohacheski
020f280458 Add .local mount to example Docker command (#6419) 2023-09-22 17:07:07 -08:00
Asher
58f6e24a07 Fix installation of kerberos module on armv7l (#6442)
Also build with the same version of Node we will release with.
2023-09-22 00:54:14 -08:00
Asher
7868f4db23 Fix cross-compilation (#6441)
* Avoid packaging yarn.lock

Since the shrinkwrap is what we want everything to use.

* Build with npm

It seems we stuck with yarn because npm was giving us errors but I will try
sorting it out now so we can build with npm as originally intended.

* Remove build from source

Not using CentOS 7 anymore so based on the comment we no longer need
this.  Keytar seems to install fine now.

* Update missed Node version

These numbers are all over the place.

* npm_config_arch must be lowercase

* Patch out Kerberos

I am not sure exactly how it is used but I think it is not a path code-server
worries about, at least not right now.  Just going to patch it out rather than
figure out how to build it on armv7l but we can revisit later.
2023-09-21 23:21:01 -08:00
Asher
acc50a5d36 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
2023-09-21 16:13:34 -08:00
Asher
47ee7ae670 Bump minimum glibc to 2.28 (#6439)
At least, for the standalone and for anyone running on default Node 18.

If support for 2.17 is needed then one would need to build Node 18 with 2.17 and then build code-server with that version (specifically, the native npm modules).
2023-09-21 13:42:17 -08:00
Asher
70d0c603cc Update to VS Code 1.82.2 (#6436)
* Update VS Code to 1.82.2

* Add new libkrb5 dependency

* Update patches

The only changes were to context except:

- The URL callback provider uses a new _callbackRoute argument and moved
  locations.
- The telemetry provider gets passed the request service as the first
  argument now.
- CSP hash changed, as usual.

* Update Node to v18

* Revert back to es2020

es2022 is breaking Safari.
2023-09-20 15:33:28 -08:00
dependabot[bot]
2e29c233ea chore: bump tj-actions/changed-files from 37 to 38 (#6417)
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 37 to 38.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v37...v38)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-18 11:54:56 -08:00
dependabot[bot]
331a017309 chore: bump argon2 from 0.30.3 to 0.31.0 (#6415)
Bumps [argon2](https://github.com/ranisalt/node-argon2) from 0.30.3 to 0.31.0.
- [Release notes](https://github.com/ranisalt/node-argon2/releases)
- [Commits](https://github.com/ranisalt/node-argon2/compare/v0.30.3...v0.31.0)

---
updated-dependencies:
- dependency-name: argon2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-18 11:53:31 -08:00
dependabot[bot]
f915d1e2c8 chore: bump eslint from 8.44.0 to 8.48.0 (#6414)
Bumps [eslint](https://github.com/eslint/eslint) from 8.44.0 to 8.48.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.44.0...v8.48.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-18 11:52:54 -08:00
Kaoru Yamamoto
95bcf101d7 Add Japanese locale (#6433) 2023-09-18 17:23:03 +00:00
James MacDonald
d80568df20 Add pod annotations (#6432) 2023-09-16 00:31:05 +00:00
Asher
03dc8cd808 Propagate post-installation failures
pipefail might be ideal here but not sure how wide the support is yet
considering this may run on plain sh.
2023-09-11 09:27:29 -08:00
Asher
3e1c00e017 Run formatter
Not sure why CI missed these, will have to look into it.
2023-09-11 09:27:28 -08:00
Cyanoure
a76e5241b6 Add "CODE_SERVER_HOST" environment variable (#6423) 2023-09-08 22:50:11 +00:00
Asher
913fc30866 Upgrade @coder/logger (#6409)
This gets rid of the unused peer dependency that was pulling in
protobufjs.
2023-08-30 12:10:34 -08:00
Asher
eb498b0d6d Remove humanPath (#6404)
The tilde is ambiguous and it can be helpful to know exactly what paths
code-server is trying to use, especially if it is running as a different
user than you expected.
2023-08-29 14:25:24 -08:00
Antoine
eb8099ff89 feat(helm): Don't create Secret if existingSecret is provided (#6397) 2023-08-28 11:01:11 -08:00
Efren
56d3548fa2 Add braces to Caddyfile example (#6382) 2023-08-10 00:44:23 +00:00
jothi prasath
2d335bd1ea Update screenshots (#6372) 2023-08-07 19:02:54 +00:00
dependabot[bot]
291682e1c0 chore: bump i18next from 23.2.11 to 23.4.1 (#6362)
Bumps [i18next](https://github.com/i18next/i18next) from 23.2.11 to 23.4.1.
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v23.2.11...v23.4.1)

---
updated-dependencies:
- dependency-name: i18next
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-02 10:17:13 -08:00
dependabot[bot]
97aeb77abe chore: bump eslint-plugin-import from 2.27.5 to 2.28.0 (#6363)
Bumps [eslint-plugin-import](https://github.com/import-js/eslint-plugin-import) from 2.27.5 to 2.28.0.
- [Release notes](https://github.com/import-js/eslint-plugin-import/releases)
- [Changelog](https://github.com/import-js/eslint-plugin-import/blob/main/CHANGELOG.md)
- [Commits](https://github.com/import-js/eslint-plugin-import/compare/v2.27.5...v2.28.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-import
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-02 10:16:13 -08:00
dependabot[bot]
76fd2389e4 chore: bump proxy-agent from 6.2.1 to 6.3.0 (#6361)
Bumps [proxy-agent](https://github.com/TooTallNate/proxy-agents/tree/HEAD/packages/proxy-agent) from 6.2.1 to 6.3.0.
- [Release notes](https://github.com/TooTallNate/proxy-agents/releases)
- [Changelog](https://github.com/TooTallNate/proxy-agents/blob/main/packages/proxy-agent/CHANGELOG.md)
- [Commits](https://github.com/TooTallNate/proxy-agents/commits/proxy-agent@6.3.0/packages/proxy-agent)

---
updated-dependencies:
- dependency-name: proxy-agent
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-08-02 09:51:46 -08:00
Asher
3cb92edc76 Release v4.16.1 2023-07-31 11:21:45 -08:00
Olivier Benz
94ef3776ad Update Code to 1.80.2 (#6357) 2023-07-31 09:14:29 -08:00
Asher
a82f1ceaa5 Add missing FAQ table of contents entry 2023-07-28 17:46:36 -08:00
Asher
25254214fb Release v4.16.0 2023-07-28 17:32:57 -08:00
Asher
feb5e6770c Add entry for location of configuration
Closes #6324.
2023-07-28 17:32:48 -08:00
Asher
e37b35278d Account for disabled proxy in startup logs 2023-07-27 09:26:11 -08:00
Asher
2ffbcfdfcb Release v4.15.0 2023-07-21 15:30:03 -08:00
Ryan Brainard
74da5167a2 Add --disable-proxy option (#6349) 2023-07-21 15:23:21 -08:00
dependabot[bot]
daac46b3cf chore: bump i18next from 22.5.1 to 23.2.11 (#6326)
Bumps [i18next](https://github.com/i18next/i18next) from 22.5.1 to 23.2.11.
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v22.5.1...v23.2.11)

---
updated-dependencies:
- dependency-name: i18next
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-20 14:03:21 -05:00
dependabot[bot]
ea3c79ffd1 chore: bump @typescript-eslint/eslint-plugin from 5.59.1 to 5.62.0 (#6327)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.59.1 to 5.62.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.62.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-20 13:31:37 -05:00
Alex Thillen
93e60f7b0e add trusted-origins cli argument (#6319) 2023-07-19 14:04:03 -08:00
dependabot[bot]
7926647058 chore: bump tough-cookie from 4.0.0 to 4.1.3 in /test (#6318)
Bumps [tough-cookie](https://github.com/salesforce/tough-cookie) from 4.0.0 to 4.1.3.
- [Release notes](https://github.com/salesforce/tough-cookie/releases)
- [Changelog](https://github.com/salesforce/tough-cookie/blob/master/CHANGELOG.md)
- [Commits](https://github.com/salesforce/tough-cookie/compare/v4.0.0...v4.1.3)

---
updated-dependencies:
- dependency-name: tough-cookie
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-19 14:02:19 -08:00
dependabot[bot]
d27cd43dce chore: bump @typescript-eslint/parser from 5.61.0 to 5.62.0 (#6328)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.61.0 to 5.62.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.62.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-19 14:01:32 -08:00
dependabot[bot]
1befd37310 chore: bump word-wrap from 1.2.3 to 1.2.4 (#6342)
Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.4.
- [Release notes](https://github.com/jonschlinkert/word-wrap/releases)
- [Commits](https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.4)

---
updated-dependencies:
- dependency-name: word-wrap
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-19 14:01:14 -08:00
dependabot[bot]
2b3b5e7051 chore: bump word-wrap from 1.2.3 to 1.2.4 in /test (#6343)
Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.4.
- [Release notes](https://github.com/jonschlinkert/word-wrap/releases)
- [Commits](https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.4)

---
updated-dependencies:
- dependency-name: word-wrap
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-19 14:00:56 -08:00
Olivier Benz
788da5d495 Update Code to 1.80.1 (#6340)
* Update Code to 1.80.1 (#6340)
* Give build workflow more time to run
2023-07-19 14:00:31 -08:00
dependabot[bot]
070a5a3179 chore: bump semver from 6.3.0 to 6.3.1 in /test (#6320)
Bumps [semver](https://github.com/npm/node-semver) from 6.3.0 to 6.3.1.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/v6.3.1/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v6.3.0...v6.3.1)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-14 13:52:42 -08:00
Michael Thomas
7cbb6a8b09 Add Svelte to guide (#6269)
Added a guide on proxying to a Svelte app since there wasn't one already. Used the vue and angular guides as a template and included a link to an issue post on sveltekits website which adds some context.
2023-07-13 16:17:25 -05:00
dependabot[bot]
7fb54073db chore: bump @typescript-eslint/parser from 5.59.11 to 5.61.0 (#6312)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.59.11 to 5.61.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.61.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-13 16:04:32 -05:00
dependabot[bot]
e72e8bb6b5 chore: bump aquasecurity/trivy-action from 0.10.0 to 0.11.2 (#6303)
Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.10.0 to 0.11.2.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](e5f43133f6...41f05d9ecf)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-13 16:04:18 -05:00
dependabot[bot]
411846528b chore: bump eslint from 8.39.0 to 8.44.0 (#6299)
Bumps [eslint](https://github.com/eslint/eslint) from 8.39.0 to 8.44.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.39.0...v8.44.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-13 16:03:55 -05:00
dependabot[bot]
7f024eda6e chore: bump typescript from 5.0.4 to 5.1.6 (#6297)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.0.4 to 5.1.6.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/commits)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-06 13:59:24 -05:00
dependabot[bot]
2617623ed6 chore: bump tj-actions/changed-files from 36 to 37 (#6302)
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 36 to 37.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v36...v37)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-06 13:59:01 -05:00
Asher
70aa1b7722 Release v4.14.1 2023-06-26 10:21:35 -08:00
dependabot[bot]
90a4147381 chore: bump semver from 7.3.8 to 7.5.2 (#6287)
Bumps [semver](https://github.com/npm/node-semver) from 7.3.8 to 7.5.2.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/main/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v7.3.8...v7.5.2)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-26 12:12:45 -05:00
Asher
5c19962930 Set session socket into environment variable (#6282)
* Avoid spawning code-server with --reuse-window and --new-window

These flags mean the user explicitly wants to open in an existing
instance so if the socket is down it should error rather than try to
spawn code-server normally.

* Set session socket into environment variable

While I was at it I added a CLI flag to override the default.  I also
swapped the default to --user-data-dir.

The value is set on an environment variable so it can be used by the
extension host similar to VSCODE_IPC_HOOK_CLI.

* Add e2e test for opening files externally
2023-06-21 22:47:01 -08:00
Asher
56d10d82bf Enforce Node binary permissions
In some cases it may have extra write permissions.
2023-06-21 11:23:40 -08:00
Asher
cef2aa22dc Move session server log after HTTP server logs
The indented logs technically apply to the HTTP server so move the
session server log afterward to avoid making them look like they apply
to the session server.
2023-06-21 10:59:02 -08:00
Sean Lee
b5a9ef80e7 Use unique socket per user for managing editor sessions (#6278)
Also warn if editor session manager socket cannot be created rather than failing.
2023-06-21 13:39:25 -05:00
Asher
5d3c9edce4 Release v4.14.0 2023-06-16 13:38:21 -08:00
Asher
9955cd91a4 Update Code to 1.79.1 (#6264)
Mostly just the usual shifting or changing of the surrounding context
but I did refactor the getting started block we insert because it keeps
getting mangled on each update.  Instead of shifting things around the
columns I just prepend it to the right column.

Getting 404s on some vsda module but everything seems to work 
without it and I do not see it referenced in the package.json nor a
nywhere on npmjs.com so it seems to be optional.
2023-06-15 08:00:03 -08:00
dependabot[bot]
fdeaba9581 chore: bump proxy-agent from 5.0.0 to 6.2.1 (#6247)
* chore: bump proxy-agent from 5.0.0 to 6.2.1

Bumps [proxy-agent](https://github.com/TooTallNate/proxy-agents/tree/HEAD/packages/proxy-agent) from 5.0.0 to 6.2.1.
- [Release notes](https://github.com/TooTallNate/proxy-agents/releases)
- [Changelog](https://github.com/TooTallNate/proxy-agents/blob/main/packages/proxy-agent/CHANGELOG.md)
- [Commits](https://github.com/TooTallNate/proxy-agents/commits/proxy-agent@6.2.1/packages/proxy-agent)

---
updated-dependencies:
- dependency-name: proxy-agent
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* Update proxy-agent usage

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Asher <ash@coder.com>
2023-06-14 14:27:15 -08:00
dependabot[bot]
40ff2e6049 chore: bump @typescript-eslint/parser from 5.57.1 to 5.59.11 (#6262)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.57.1 to 5.59.11.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.59.11/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-14 14:08:39 -08:00
dependabot[bot]
73d42f7ea0 chore: bump i18next from 22.4.6 to 22.5.1 (#6261)
Bumps [i18next](https://github.com/i18next/i18next) from 22.4.6 to 22.5.1.
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](https://github.com/i18next/i18next/compare/v22.4.6...v22.5.1)

---
updated-dependencies:
- dependency-name: i18next
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-14 13:33:51 -08:00
Sean Lee
fb73742b2b Prefer matching editor sessions when opening files. (#6191)
Signed-off-by: Sean Lee <freshdried@gmail.com>
2023-06-14 13:32:07 -08:00
Asher
ccb0d3a34f Remove unused dependency split2
This was used with now-removed `--link`.
2023-06-13 10:38:13 -08:00
dependabot[bot]
4a121edd16 chore: bump tj-actions/changed-files from 35 to 36 (#6246)
Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 35 to 36.
- [Release notes](https://github.com/tj-actions/changed-files/releases)
- [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md)
- [Commits](https://github.com/tj-actions/changed-files/compare/v35...v36)

---
updated-dependencies:
- dependency-name: tj-actions/changed-files
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-13 18:28:24 +00:00
dependabot[bot]
f6db985712 chore: bump robinraju/release-downloader from 1.7 to 1.8 (#6245)
Bumps [robinraju/release-downloader](https://github.com/robinraju/release-downloader) from 1.7 to 1.8.
- [Release notes](https://github.com/robinraju/release-downloader/releases)
- [Commits](https://github.com/robinraju/release-downloader/compare/v1.7...v1.8)

---
updated-dependencies:
- dependency-name: robinraju/release-downloader
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-13 12:47:40 -05:00
dependabot[bot]
6d00fc7f46 chore: bump typescript from 4.6.4 to 5.0.4 (#6182)
Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.6.4 to 5.0.4.
- [Release notes](https://github.com/Microsoft/TypeScript/releases)
- [Commits](https://github.com/Microsoft/TypeScript/compare/v4.6.4...v5.0.4)

---
updated-dependencies:
- dependency-name: typescript
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-06-13 12:45:49 -05:00
Jonas
ee024f3f2d docs: mention Termux extension workarounds (#6227) 2023-05-31 15:00:58 -08:00
Simon Merschjohann
0703ef008c Allow {{host}} and {{port}} in domain proxy (#6225) 2023-05-31 16:31:30 -05:00
Asher
2109d1cf6a Add new unreleased section to changelog 2023-05-22 12:21:30 -08:00
Asher
74af05dfbe Release v4.13.0 2023-05-19 13:14:29 -08:00
dependabot[bot]
2798322b03 chore: bump vm2 from 3.9.17 to 3.9.19 (#6216)
Bumps [vm2](https://github.com/patriksimek/vm2) from 3.9.17 to 3.9.19.
- [Release notes](https://github.com/patriksimek/vm2/releases)
- [Changelog](https://github.com/patriksimek/vm2/blob/master/CHANGELOG.md)
- [Commits](https://github.com/patriksimek/vm2/compare/3.9.17...3.9.19)

---
updated-dependencies:
- dependency-name: vm2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-17 12:38:38 -08:00
Asher
b3b971480f Support X-Forwarded-Host with multiple hosts
Closes #6215.
2023-05-17 11:51:05 -08:00
Asher
6745a46034 Fix extension install test
This is not a valid ID (to install a specific version you use @) and,
quite strangely, Code is now returning an "extension not found" error if
the ID is invalid, breaking the test since we expect it to error about
the marketplace not existing.
2023-05-15 20:54:37 -08:00
Asher
43ef50b404 Update to 1.78.2 (#6201)
* Update to 1.78.1

No changes needed in the patches other than moving some lines around and
updating the CSP hash as usual.

The flake had to be updated as it was using Node 16.16 and 16.17 is
required at minimum now.  Also python seems to install python2 which is
marked as deprecated so explicitly install python3.

* Update to 1.78.2

Patches applied without any conflicts.

* Update commit environment variable

This was causing the commit not to be set.  It broke display languages
since that has a hard dependency on the commit for directory names.
Possibly broke other things.
2023-05-15 15:44:03 -08:00
dependabot[bot]
45c89856fd chore: bump eslint-config-prettier from 8.6.0 to 8.8.0 (#6179)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 8.6.0 to 8.8.0.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v8.6.0...v8.8.0)

---
updated-dependencies:
- dependency-name: eslint-config-prettier
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-08 12:43:37 -08:00
Jim van Abkoude
5f4ae75431 Add nix-on-droid as an Android installation method (#6196) 2023-05-08 12:42:43 -08:00
易良
521ff44aed fix: relative path in markdown (#6188)
Co-authored-by: jinjing.zzj <jinjing.zzj@alibaba-inc.com>
2023-05-08 12:38:52 -08:00
Asher
5708e6ce32 Format redacted arg lines
Pushing straight to main again.
2023-05-05 14:44:40 -08:00
Asher
3f7db15fde Redact sensitive args from handshake debug log 2023-05-04 10:54:41 -08:00
Asher
8c99f41b90 Fix parent process log level 2023-05-04 10:48:32 -08:00
Asher
e02d56dbfd Do not trace child process messages
All this does is add a stack trace which is not helpful here.
2023-05-04 10:48:31 -08:00
Asher
aac5efa046 Do not log < 500 on web sockets as errors
For example if someone spams a web socket without authentication we
should not log "forbidden".  Forbidden is normal/expected operation, not
an error.
2023-05-04 10:48:30 -08:00
dependabot[bot]
ff2764f7b1 chore: bump rotating-file-stream from 3.0.0 to 3.1.0 (#6183)
Bumps [rotating-file-stream](https://github.com/iccicci/rotating-file-stream) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/iccicci/rotating-file-stream/releases)
- [Changelog](https://github.com/iccicci/rotating-file-stream/blob/master/CHANGELOG.md)
- [Commits](https://github.com/iccicci/rotating-file-stream/compare/v3.0.0...v3.1.0)

---
updated-dependencies:
- dependency-name: rotating-file-stream
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-03 08:33:32 -08:00
dependabot[bot]
bda6b631ab chore: bump @typescript-eslint/eslint-plugin from 5.57.1 to 5.59.1 (#6180)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.57.1 to 5.59.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.59.1/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-01 16:49:48 -08:00
dependabot[bot]
9bac70ea0d chore: bump eslint from 8.26.0 to 8.39.0 (#6181)
Bumps [eslint](https://github.com/eslint/eslint) from 8.26.0 to 8.39.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v8.26.0...v8.39.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-01 16:49:18 -08:00
dependabot[bot]
7722ef1437 chore: bump aquasecurity/trivy-action from 0.9.2 to 0.10.0 (#6178)
Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.9.2 to 0.10.0.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](1f0aa582c8...e5f43133f6)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-05-01 11:17:06 -05:00
smalllady
951d8ac45e Fix proxying non-ASCII (#6154)
This only affects the path proxy since `req.originalUrl` is in escaped format.
2023-04-25 11:41:33 -08:00
Asher
2e17735795 Release v4.12.0 (#6157) 2023-04-21 14:04:07 -05:00
dependabot[bot]
1da7cda39e chore: bump vm2 from 3.9.15 to 3.9.17 (#6155)
Bumps [vm2](https://github.com/patriksimek/vm2) from 3.9.15 to 3.9.17.
- [Release notes](https://github.com/patriksimek/vm2/releases)
- [Changelog](https://github.com/patriksimek/vm2/blob/master/CHANGELOG.md)
- [Commits](https://github.com/patriksimek/vm2/compare/3.9.15...3.9.17)

---
updated-dependencies:
- dependency-name: vm2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-20 10:58:58 -08:00
Asher
c829d74203 Update to Code 1.77.3 (#6148) 2023-04-13 10:34:33 -08:00
Asher
39075b2cf3 Update to Code 1.77.2 (#6142)
No changes necessary.
2023-04-12 08:52:16 -08:00
dependabot[bot]
aed1fc0119 chore: bump cross-fetch from 3.1.4 to 3.1.5 in /test (#6087)
Bumps [cross-fetch](https://github.com/lquixada/cross-fetch) from 3.1.4 to 3.1.5.
- [Release notes](https://github.com/lquixada/cross-fetch/releases)
- [Commits](https://github.com/lquixada/cross-fetch/compare/v3.1.4...v3.1.5)

---
updated-dependencies:
- dependency-name: cross-fetch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-11 14:17:03 -05:00
Asher
6e411adb01 Update Code to 1.77.1 (#6135) 2023-04-10 10:28:13 -08:00
dependabot[bot]
36ba646bcb chore: bump json5 from 2.2.0 to 2.2.3 in /test (#6085)
Bumps [json5](https://github.com/json5/json5) from 2.2.0 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.0...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-10 09:45:09 -08:00
dependabot[bot]
278d0f2184 chore: bump vm2 from 3.9.11 to 3.9.15 (#6134)
Bumps [vm2](https://github.com/patriksimek/vm2) from 3.9.11 to 3.9.15.
- [Release notes](https://github.com/patriksimek/vm2/releases)
- [Changelog](https://github.com/patriksimek/vm2/blob/master/CHANGELOG.md)
- [Commits](https://github.com/patriksimek/vm2/compare/3.9.11...3.9.15)

---
updated-dependencies:
- dependency-name: vm2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-07 22:01:25 +00:00
dependabot[bot]
b954250018 chore: bump eslint-plugin-import from 2.26.0 to 2.27.5 (#6123)
Bumps [eslint-plugin-import](https://github.com/import-js/eslint-plugin-import) from 2.26.0 to 2.27.5.
- [Release notes](https://github.com/import-js/eslint-plugin-import/releases)
- [Changelog](https://github.com/import-js/eslint-plugin-import/blob/main/CHANGELOG.md)
- [Commits](https://github.com/import-js/eslint-plugin-import/compare/v2.26.0...v2.27.5)

---
updated-dependencies:
- dependency-name: eslint-plugin-import
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-07 21:40:43 +00:00
dependabot[bot]
2b72da22e6 chore: bump @typescript-eslint/parser from 5.41.0 to 5.57.1 (#6132)
Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 5.41.0 to 5.57.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.57.1/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-07 21:21:36 +00:00
dependabot[bot]
3c838e2d02 chore: bump @typescript-eslint/eslint-plugin from 5.56.0 to 5.57.1 (#6133)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.56.0 to 5.57.1.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.57.1/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-07 20:55:02 +00:00
dependabot[bot]
f8d563c49b chore: bump split2 from 4.1.0 to 4.2.0 (#6121)
Bumps [split2](https://github.com/mcollina/split2) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/mcollina/split2/releases)
- [Commits](https://github.com/mcollina/split2/compare/v4.1.0...v4.2.0)

---
updated-dependencies:
- dependency-name: split2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-07 20:36:33 +00:00
dependabot[bot]
39e63af359 chore: bump ts-node from 10.1.0 to 10.9.1 (#6125)
Bumps [ts-node](https://github.com/TypeStrong/ts-node) from 10.1.0 to 10.9.1.
- [Release notes](https://github.com/TypeStrong/ts-node/releases)
- [Changelog](https://github.com/TypeStrong/ts-node/blob/main/development-docs/release-template.md)
- [Commits](https://github.com/TypeStrong/ts-node/compare/v10.1.0...v10.9.1)

---
updated-dependencies:
- dependency-name: ts-node
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-07 12:17:22 -08:00
Asher
c995988b70 Set proxy URI to domain proxy when possible (#6115)
This will make the ports panel use it instead of the default path-based
proxy.
2023-03-30 12:01:49 -08:00
watchakorn-18k
a44bd71043 Add thai language i18n (#6103) 2023-03-30 13:00:58 -05:00
Asher
19bcd043d7 Add debug log for origin check (#6096)
Extracted host detection into a separate function to avoid multiple log
lines on each return and went with a thrown error to consolidate the
common log text.
2023-03-30 12:24:33 -05:00
dependabot[bot]
c32a31d802 chore: bump ws from 8.2.0 to 8.13.0 (#6100)
Bumps [ws](https://github.com/websockets/ws) from 8.2.0 to 8.13.0.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.2.0...8.13.0)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-22 14:08:53 -05:00
dependabot[bot]
45ca68c362 chore: bump jpeg-js from 0.4.3 to 0.4.4 in /test (#6086)
Bumps [jpeg-js](https://github.com/eugeneware/jpeg-js) from 0.4.3 to 0.4.4.
- [Release notes](https://github.com/eugeneware/jpeg-js/releases)
- [Commits](https://github.com/eugeneware/jpeg-js/compare/v0.4.3...v0.4.4)

---
updated-dependencies:
- dependency-name: jpeg-js
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-22 14:03:39 -05:00
dependabot[bot]
8f1a70339d chore: bump node-fetch from 2.6.6 to 2.6.7 in /test (#6084)
Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.6 to 2.6.7.
- [Release notes](https://github.com/node-fetch/node-fetch/releases)
- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.6...v2.6.7)

---
updated-dependencies:
- dependency-name: node-fetch
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-22 14:03:09 -05:00
dependabot[bot]
35209aa5b5 chore: bump minimatch from 3.0.4 to 3.1.2 in /test (#6083)
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-22 14:02:52 -05:00
dependabot[bot]
87f44599e5 chore: bump audit-ci from 6.0.0 to 6.6.1 (#6040)
Bumps [audit-ci](https://github.com/IBM/audit-ci) from 6.0.0 to 6.6.1.
- [Release notes](https://github.com/IBM/audit-ci/releases)
- [Commits](https://github.com/IBM/audit-ci/compare/v6.0.0...v6.6.1)

---
updated-dependencies:
- dependency-name: audit-ci
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-22 14:02:41 -05:00
dependabot[bot]
71f01ec0f0 chore: bump @types/node from 16.11.41 to 16.18.18 (#6099)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 16.11.41 to 16.18.18.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-22 14:02:22 -05:00
dependabot[bot]
f8e2d00099 chore: bump @typescript-eslint/eslint-plugin from 5.51.0 to 5.56.0 (#6102)
Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 5.51.0 to 5.56.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v5.56.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-22 14:02:00 -05:00
dependabot[bot]
a485fec27c chore: bump minimist from 1.2.5 to 1.2.8 in /test (#6095)
Bumps [minimist](https://github.com/minimistjs/minimist) from 1.2.5 to 1.2.8.
- [Release notes](https://github.com/minimistjs/minimist/releases)
- [Changelog](https://github.com/minimistjs/minimist/blob/main/CHANGELOG.md)
- [Commits](https://github.com/minimistjs/minimist/compare/v1.2.5...v1.2.8)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-22 18:58:55 +00:00
dependabot[bot]
aa2276293a chore: bump cookiejar from 2.1.3 to 2.1.4 in /test (#6094)
Bumps [cookiejar](https://github.com/bmeck/node-cookiejar) from 2.1.3 to 2.1.4.
- [Release notes](https://github.com/bmeck/node-cookiejar/releases)
- [Commits](https://github.com/bmeck/node-cookiejar/commits)

---
updated-dependencies:
- dependency-name: cookiejar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-22 18:11:42 +00:00
Felix K
72eae01684 Add information on using PWA with desktop Firefox (#6098)
Co-authored-by: Felix Kuhlmann <felix-kuhlmann@gmx.de>
2023-03-22 17:52:35 +00:00
Ahmed El-Sharnoby
bca733de3d Allow app-name configuration to change the name of the PWA (#6093) 2023-03-22 01:02:31 +00:00
Asher
78282a1fd6 Make random formatting change to security.yaml
This is an attempt to set myself as the notification target.

Closes #6090.
2023-03-21 12:24:10 -08:00
Asher
dbdd2edb62 Fix proxy error on web sockets
Fixes #6088.
2023-03-21 12:24:09 -08:00
Asher
a9d61daa91 Release v4.11.0 2023-03-16 10:04:57 -08:00
Initial-heart
6c08466b05 Correct default shell docs for npm on Windows (#6078) 2023-03-16 12:46:11 -05:00
dependabot[bot]
85e083580d chore: bump aquasecurity/trivy-action from 0.9.0 to 0.9.2 (#6075)
Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.9.0 to 0.9.2.
- [Release notes](https://github.com/aquasecurity/trivy-action/releases)
- [Commits](cff3e9a7f6...1f0aa582c8)

---
updated-dependencies:
- dependency-name: aquasecurity/trivy-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-14 16:49:25 -05:00
Asher
b0431069a1 Replace CI deprecations (#6072)
* Replace deprecated set-output usage in CI

* Update tj-actions/changed-files

CI is saying it uses Node 12 and that Node 12 actions are deprecated.
2023-03-14 15:52:53 -05:00
Asher
f9cc07926b Update Code to 1.76.1 (#6070)
* Update Code to 1.76.1

- worker-src already contains blob so we can avoid patching that.
- localeService moved.
- Remaining changes were just line changes.

* Make language extensions installable again

Still might want to look into making the native language support work
but for now it seems better not to break backwards compatibility since
the native implementation is quite different.

* Avoid "install in browser" for language packs

It will not work.

* Import correct locale service

I believe before the contributions imported this but now we have to do
it here.
2023-03-14 15:03:53 -05:00
Asher
be40eca5d9 Release v4.10.1 2023-03-03 22:24:54 -09:00
Asher
9ba08907da Fix Node version failure in publish workflow
Looks like the images got updated to v18 so they started failing.  For
npm install v16 and for Docker just run the script directly, it seems
silly to waste time installing v16 just to run a script through yarn.
2023-03-03 22:23:21 -09:00
Asher
d477972c68 Add origin checks to web sockets (#6048)
* Move splitOnFirstEquals to util

I will be making use of this to parse the forwarded header.

* Type splitOnFirstEquals with two items

Also add some test cases.

* Check origin header on web sockets

* Update changelog with origin check

* Fix web sockets not closing with error code
2023-03-03 03:12:34 -06:00
Asher
a47cd81d8c Update FAQ: code-server is not using a direct fork
Also the wrapper process is another major difference along with the
update notifications.
2023-02-27 14:29:55 -09:00
Asher
c9fbcffd53 Rewrite differences in FAQ
- Move differences to the Codespaces section since they apply to both
  Codespaces and OpenVSCode-Server
- Add some important missing differences
- Exclude settings sync (not being worked on)
- Exclude the plugin API (deprecated)
- Exclude certificate support (browsers these days are starting to
  require trusted certs so better not to recommend using this)
2023-02-27 14:21:11 -09:00
Michael Tinsley
befa76d09d Fix extra prefix dashes in install.sh (#6028) 2023-02-27 22:57:57 +00:00
Asher
e0ece195c1 Update changelog and chart with new version 2023-02-15 11:16:09 -09:00
121 changed files with 5964 additions and 3233 deletions

View File

@@ -1,6 +1,5 @@
name: Bug report
description: File a bug report
title: "[Bug]: "
labels: ["bug", "triage"]
body:
- type: checkboxes
@@ -10,6 +9,7 @@ body:
options:
- label: I have searched the existing issues
required: true
- type: textarea
attributes:
label: OS/Web Information
@@ -28,58 +28,82 @@ body:
- `code-server --version`:
validations:
required: true
- type: textarea
attributes:
label: Steps to Reproduce
description: |
1. open code-server
2. install extension
3. run command
Please describe exactly how to reproduce the bug. For example:
1. Open code-server in Firefox
2. Install extension `foo.bar` from the extensions sidebar
3. Run command `foo.bar.baz`
value: |
1.
1.
2.
3.
validations:
required: true
- type: textarea
attributes:
label: Expected
description: What should happen?
validations:
required: true
- type: textarea
attributes:
label: Actual
description: What actually happens?
validations:
required: true
- type: textarea
id: logs
attributes:
label: Logs
description: Run code-server with the --verbose flag and then paste any relevant logs from the server, from the browser console and/or the browser network tab. For issues with installation, include installation logs (i.e. output of `yarn global add code-server`).
render: shell
- type: textarea
attributes:
label: Screenshot/Video
description: Please include a screenshot, gif or screen recording of your issue.
validations:
required: false
- type: dropdown
attributes:
label: Does this bug reproduce in native VS Code?
description: If the bug reproduces in native VS Code, submit the issue upstream instead (https://github.com/microsoft/vscode).
options:
- Yes, this is also broken in native VS Code
- No, this works as expected in native VS Code
- This cannot be tested in native VS Code
- I did not test native VS Code
validations:
required: true
- type: dropdown
attributes:
label: Does this bug reproduce in GitHub Codespaces?
description: If the bug reproduces in GitHub Codespaces, submit the issue upstream instead (https://github.com/microsoft/vscode).
options:
- Yes, this is also broken in GitHub Codespaces
- No, this works as expected in GitHub Codespaces
- This cannot be tested in GitHub Codespaces
- I did not test GitHub Codespaces
validations:
required: true
- type: checkboxes
attributes:
label: Does this issue happen in VS Code or GitHub Codespaces?
description: Please try reproducing this issue in VS Code or GitHub Codespaces
label: Are you accessing code-server over a secure context?
description: code-server relies on service workers (which only work in secure contexts) for many features. Double-check that you are using a secure context like HTTPS or localhost.
options:
- label: I cannot reproduce this in VS Code.
required: true
- label: I cannot reproduce this in GitHub Codespaces.
required: true
- type: checkboxes
attributes:
label: Are you accessing code-server over HTTPS?
description: code-server relies on service workers for many features. Double-check that you are using HTTPS.
options:
- label: I am using HTTPS.
required: true
- label: I am using a secure context.
required: false
- type: textarea
attributes:
label: Notes

View File

@@ -1,9 +1,7 @@
---
name: Documentation improvement
about: Suggest a documentation improvement
title: "[Docs]: "
labels: "docs"
assignees: "@jsjoeio"
---
## What is your suggestion?

View File

@@ -1,9 +1,7 @@
---
name: Feature request
about: Suggest an idea to improve code-server
title: "[Feat]: "
labels: enhancement
assignees: ""
---
## What is your suggestion?

View File

@@ -28,10 +28,10 @@ jobs:
timeout-minutes: 5
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Run prettier with actionsx/prettier
uses: actionsx/prettier@v2
uses: actionsx/prettier@v3
with:
args: --check --loglevel=warn .
@@ -41,20 +41,20 @@ jobs:
timeout-minutes: 5
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v26.1
uses: tj-actions/changed-files@v44
with:
files: |
docs/**
- name: Install Node.js v16
- name: Install Node.js
if: steps.changed-files.outputs.any_changed == 'true'
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: "16"
node-version-file: .node-version
cache: "yarn"
- name: Install doctoc
@@ -70,20 +70,20 @@ jobs:
timeout-minutes: 5
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v26.1
uses: tj-actions/changed-files@v44
with:
files: |
ci/helm-chart/**
- name: Install helm
if: steps.changed-files.outputs.any_changed == 'true'
uses: azure/setup-helm@v3.5
uses: azure/setup-helm@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
@@ -101,13 +101,13 @@ jobs:
timeout-minutes: 5
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v26.1
uses: tj-actions/changed-files@v44
with:
files: |
**/*.ts
@@ -115,16 +115,16 @@ jobs:
files_ignore: |
lib/vscode/**
- name: Install Node.js v16
- name: Install Node.js
if: steps.changed-files.outputs.any_changed == 'true'
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: "16"
node-version-file: .node-version
- name: Fetch dependencies from cache
if: steps.changed-files.outputs.any_changed == 'true'
id: cache-node-modules
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
@@ -144,7 +144,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Check workflow files
run: |
bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/7fdc9630cc360ea1a469eed64ac6d78caeda1234/scripts/download-actionlint.bash)
@@ -157,29 +157,29 @@ jobs:
timeout-minutes: 5
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v26.1
uses: tj-actions/changed-files@v44
with:
files: |
**/*.ts
files_ignore: |
lib/vscode/**
- name: Install Node.js v16
- name: Install Node.js
if: steps.changed-files.outputs.any_changed == 'true'
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: "16"
node-version-file: .node-version
- name: Fetch dependencies from cache
if: steps.changed-files.outputs.any_changed == 'true'
id: cache-node-modules
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
@@ -195,7 +195,7 @@ jobs:
run: yarn test:unit
- name: Upload coverage report to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
if: success()
@@ -203,15 +203,19 @@ jobs:
build:
name: Build code-server
runs-on: ubuntu-20.04
timeout-minutes: 30
timeout-minutes: 60
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
DISABLE_V8_COMPILE_CACHE: 1
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
submodules: true
- name: Install system dependencies
run: sudo apt update && sudo apt install -y libkrb5-dev
- name: Install quilt
uses: awalsh128/cache-apt-pkgs-action@latest
with:
@@ -221,14 +225,14 @@ jobs:
- name: Patch Code
run: quilt push -a
- name: Install Node.js v16
uses: actions/setup-node@v3
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: "16"
node-version-file: .node-version
- name: Fetch dependencies from cache
id: cache-node-modules
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: "**/node_modules"
key: yarn-build-code-server-${{ hashFiles('**/yarn.lock') }}
@@ -248,7 +252,7 @@ jobs:
# different and we need to rebuild.
- name: Get latest lib/vscode rev
id: vscode-rev
run: echo "::set-output name=rev::$(git rev-parse HEAD:./lib/vscode)"
run: echo "rev=$(git rev-parse HEAD:./lib/vscode)" >> $GITHUB_OUTPUT
# We need to rebuild when we have a new version of Code, when any of
# the patches changed, or when the code-server version changes (since
@@ -256,7 +260,7 @@ jobs:
# force a rebuild.
- name: Fetch prebuilt Code package from cache
id: cache-vscode
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: lib/vscode-reh-web-*
key: vscode-reh-package-${{ secrets.VSCODE_CACHE_VERSION }}-${{ steps.vscode-rev.outputs.rev }}-${{ hashFiles('patches/*.diff', 'ci/build/build-vscode.sh') }}
@@ -278,7 +282,7 @@ jobs:
run: tar -czf package.tar.gz release
- name: Upload npm package artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: npm-package
path: ./package.tar.gz
@@ -290,16 +294,19 @@ jobs:
timeout-minutes: 25
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Node.js v16
uses: actions/setup-node@v3
- name: Install system dependencies
run: sudo apt update && sudo apt install -y libkrb5-dev
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: "16"
node-version-file: .node-version
- name: Fetch dependencies from cache
id: cache-node-modules
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
@@ -307,7 +314,7 @@ jobs:
yarn-build-
- name: Download npm package
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: npm-package
@@ -331,7 +338,7 @@ jobs:
- name: Upload test artifacts
if: always()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: failed-test-videos
path: ./test/test-results
@@ -346,16 +353,19 @@ jobs:
timeout-minutes: 25
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Node.js v16
uses: actions/setup-node@v3
- name: Install system dependencies
run: sudo apt update && sudo apt install -y libkrb5-dev
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: "16"
node-version-file: .node-version
- name: Fetch dependencies from cache
id: cache-node-modules
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: "**/node_modules"
key: yarn-build-${{ hashFiles('**/yarn.lock') }}
@@ -363,7 +373,7 @@ jobs:
yarn-build-
- name: Download npm package
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: npm-package
@@ -383,7 +393,7 @@ jobs:
./test/node_modules/.bin/playwright install
- name: Cache Caddy
uses: actions/cache@v3
uses: actions/cache@v4
id: caddy-cache
with:
path: |
@@ -411,7 +421,7 @@ jobs:
- name: Upload test artifacts
if: always()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: failed-test-videos-proxy
path: ./test/test-results

View File

@@ -30,7 +30,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install code-server
run: ./install.sh
@@ -44,7 +44,7 @@ jobs:
container: "alpine:3.17"
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install curl
run: apk add curl
@@ -67,7 +67,7 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install code-server
run: ./install.sh

View File

@@ -27,10 +27,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code-server
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: "yarn"
- name: Download npm package from release artifacts
uses: robinraju/release-downloader@v1.7
uses: robinraju/release-downloader@v1.10
with:
repository: "coder/code-server"
tag: ${{ github.event.inputs.version || github.ref_name }}
@@ -64,7 +70,7 @@ jobs:
uses: Homebrew/actions/setup-homebrew@master
- name: Checkout code-server
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Configure git
run: |
@@ -95,13 +101,13 @@ jobs:
steps:
# We need to checkout code-server so we can get the version
- name: Checkout code-server
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
path: "./code-server"
- name: Checkout code-server-aur repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
repository: "cdrci/code-server-aur"
token: ${{ secrets.HOMEBREW_GITHUB_API_TOKEN }}
@@ -126,7 +132,7 @@ jobs:
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- name: Validate package
uses: hapakaien/archlinux-package-action@v2
uses: heyhusen/archlinux-package-action@v2.2.1
env:
VERSION: ${{ env.VERSION }}
with:
@@ -141,7 +147,7 @@ jobs:
VERSION: ${{ env.VERSION }}
run: |
git checkout -b update-version-${{ env.VERSION }}
git add .
git add .
git commit -m "chore: updating version to ${{ env.VERSION }}"
git push -u origin $(git branch --show)
gh pr create --repo coder/code-server-aur --title "chore: bump version to ${{ env.VERSION }}" --body "PR opened by @$GITHUB_ACTOR" --assignee $GITHUB_ACTOR
@@ -149,22 +155,22 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Checkout code-server
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login to GHCR
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -177,16 +183,24 @@ jobs:
TAG="${{ github.event.inputs.version || github.ref_name }}"
echo "VERSION=${TAG#v}" >> $GITHUB_ENV
- name: Download release artifacts
uses: robinraju/release-downloader@v1.7
- name: Download deb artifacts
uses: robinraju/release-downloader@v1.10
with:
repository: "coder/code-server"
tag: v${{ env.VERSION }}
fileName: "*.deb"
out-file-path: "release-packages"
- name: Download rpm artifacts
uses: robinraju/release-downloader@v1.10
with:
repository: "coder/code-server"
tag: v${{ env.VERSION }}
fileName: "*.rpm"
out-file-path: "release-packages"
- name: Publish to Docker
run: yarn publish:docker
run: ./ci/steps/docker-buildx-push.sh
env:
VERSION: ${{ env.VERSION }}
GITHUB_TOKEN: ${{ github.token }}

View File

@@ -27,25 +27,25 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 15
needs: npm-version
container: "centos:7"
container: "centos:8"
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Node.js v16
uses: actions/setup-node@v3
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: "16"
node-version-file: .node-version
- name: Install development tools
run: |
yum install -y epel-release centos-release-scl make
yum install -y devtoolset-9-{make,gcc,gcc-c++} jq rsync python3
# for keytar
yum install -y libsecret-devel
cd /etc/yum.repos.d/
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
yum install -y gcc-c++ make jq rsync python3 libsecret-devel krb5-devel
- name: Install nfpm and envsubst
run: |
@@ -60,17 +60,15 @@ jobs:
run: npm install -g yarn
- name: Download npm package
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: npm-release-package
- name: Decompress npm package
run: tar -xzf package.tar.gz
# NOTE: && here is deliberate - GitHub puts each line in its own `.sh`
# file when running inside a docker container.
- name: Build standalone release
run: source scl_source enable devtoolset-9 && npm run release:standalone
run: npm run release:standalone
- name: Install test dependencies
run: SKIP_SUBMODULE_DEPS=1 yarn --frozen-lockfile
@@ -79,10 +77,11 @@ jobs:
run: yarn test:integration
- name: Upload coverage report to Codecov
uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
if: success()
continue-on-error: true
# NOTE@jsjoeio - we do this so we can strip out the v
# i.e. v4.9.1 -> 4.9.1
@@ -96,60 +95,65 @@ jobs:
VERSION: ${{ env.VERSION }}
run: yarn package
- uses: softprops/action-gh-release@v1
- uses: softprops/action-gh-release@v2
with:
draft: true
discussion_category_name: "📣 Announcements"
files: ./release-packages/*
# NOTE@oxy:
# We use Ubuntu 16.04 here, so that our build is more compatible
# with older libc versions. We used to (Q1'20) use CentOS 7 here,
# but it has a full update EOL of Q4'20 and a 'critical security'
# update EOL of 2024. We're dropping full support a few years before
# the final EOL, but I don't believe CentOS 7 has a large arm64 userbase.
# It is not feasible to cross-compile with CentOS.
# Cross-compile notes: To compile native dependencies for arm64,
# we install the aarch64/armv7l cross toolchain and then set it as the default
# compiler/linker/etc. with the AR/CC/CXX/LINK environment variables.
# qemu-user-static on ubuntu-16.04 currently doesn't run Node correctly,
# so we just build with "native"/x86_64 node, then download arm64/armv7l node
# and then put it in our release. We can't smoke test the cross build this way,
# but this means we don't need to maintain a self-hosted runner!
# NOTE@jsjoeio:
# We used to use 18.04 until GitHub browned it out on December 15, 2022
# See here: https://github.com/actions/runner-images/issues/6002
package-linux-cross:
name: Linux cross-compile builds
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
timeout-minutes: 15
needs: npm-version
container: "debian:buster"
strategy:
matrix:
include:
- prefix: aarch64-linux-gnu
arch: arm64
npm_arch: arm64
apt_arch: arm64
- prefix: arm-linux-gnueabihf
arch: armv7l
npm_arch: armv7l
apt_arch: armhf
env:
AR: ${{ format('{0}-ar', matrix.prefix) }}
AS: ${{ format('{0}-as', matrix.prefix) }}
CC: ${{ format('{0}-gcc', matrix.prefix) }}
CPP: ${{ format('{0}-cpp', matrix.prefix) }}
CXX: ${{ format('{0}-g++', matrix.prefix) }}
LINK: ${{ format('{0}-g++', matrix.prefix) }}
NPM_CONFIG_ARCH: ${{ matrix.arch }}
NODE_VERSION: v16.13.0
FC: ${{ format('{0}-gfortran', matrix.prefix) }}
LD: ${{ format('{0}-ld', matrix.prefix) }}
STRIP: ${{ format('{0}-strip', matrix.prefix) }}
PKG_CONFIG_PATH: ${{ format('/usr/lib/{0}/pkgconfig', matrix.prefix) }}
TARGET_ARCH: ${{ matrix.apt_arch }}
npm_config_arch: ${{ matrix.npm_arch }}
# Not building from source results in an x86_64 argon2, as if
# npm_config_arch is being ignored.
npm_config_build_from_source: true
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Node.js v16
uses: actions/setup-node@v3
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: "16"
node-version-file: .node-version
- name: Install cross-compiler and system dependencies
run: |
dpkg --add-architecture $TARGET_ARCH
apt-get update && apt-get install -y --no-install-recommends \
crossbuild-essential-$TARGET_ARCH \
libx11-dev:$TARGET_ARCH \
libx11-xcb-dev:$TARGET_ARCH \
libxkbfile-dev:$TARGET_ARCH \
libsecret-1-dev:$TARGET_ARCH \
libkrb5-dev:$TARGET_ARCH \
ca-certificates \
curl wget rsync gettext-base
- name: Install nfpm
run: |
@@ -157,28 +161,22 @@ jobs:
curl -sSfL https://github.com/goreleaser/nfpm/releases/download/v2.3.1/nfpm_2.3.1_`uname -s`_`uname -m`.tar.gz | tar -C ~/.local/bin -zxv nfpm
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install cross-compiler
run: sudo apt update && sudo apt install $PACKAGE
env:
PACKAGE: ${{ format('g++-{0}', matrix.prefix) }}
- name: Download npm package
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: npm-release-package
- name: Decompress npm package
run: tar -xzf package.tar.gz
# NOTE@jsjoeio - npm fails here
# so use yarn
- name: Build standalone release
run: yarn release:standalone
run: npm run release:standalone
- name: Replace node with cross-compile equivalent
run: |
wget https://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-linux-${NPM_CONFIG_ARCH}.tar.xz
tar -xf node-${NODE_VERSION}-linux-${NPM_CONFIG_ARCH}.tar.xz node-${NODE_VERSION}-linux-${NPM_CONFIG_ARCH}/bin/node --strip-components=2
node_version=$(node --version)
wget https://nodejs.org/dist/${node_version}/node-${node_version}-linux-${npm_config_arch}.tar.xz
tar -xf node-${node_version}-linux-${npm_config_arch}.tar.xz node-${node_version}-linux-${npm_config_arch}/bin/node --strip-components=2
mv ./node ./release-standalone/lib/node
# NOTE@jsjoeio - we do this so we can strip out the v
@@ -191,9 +189,9 @@ jobs:
- name: Build packages with nfpm
env:
VERSION: ${{ env.VERSION }}
run: yarn package ${NPM_CONFIG_ARCH}
run: npm run package ${npm_config_arch}
- uses: softprops/action-gh-release@v1
- uses: softprops/action-gh-release@v2
with:
draft: true
discussion_category_name: "📣 Announcements"
@@ -206,12 +204,12 @@ jobs:
needs: npm-version
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install Node.js v16
uses: actions/setup-node@v3
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: "16"
node-version-file: .node-version
- name: Install nfpm
run: |
@@ -219,8 +217,15 @@ jobs:
curl -sSfL https://github.com/goreleaser/nfpm/releases/download/v2.3.1/nfpm_2.3.1_`uname -s`_`uname -m`.tar.gz | tar -C ~/.local/bin -zxv nfpm
echo "$HOME/.local/bin" >> $GITHUB_PATH
# The version of node-gyp we use depends on distutils but it was removed
# in Python 3.12. It seems to be fixed in the latest node-gyp so when we
# next update Node we can probably remove this. For now, install
# setuptools since it contains distutils.
- name: Install Python utilities
run: brew install python-setuptools
- name: Download npm package
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: npm-release-package
@@ -248,7 +253,7 @@ jobs:
VERSION: ${{ env.VERSION }}
run: yarn package
- uses: softprops/action-gh-release@v1
- uses: softprops/action-gh-release@v2
with:
draft: true
discussion_category_name: "📣 Announcements"
@@ -261,11 +266,11 @@ jobs:
needs: npm-version
steps:
- name: Download npm package
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: npm-release-package
- uses: softprops/action-gh-release@v1
- uses: softprops/action-gh-release@v2
with:
draft: true
discussion_category_name: "📣 Announcements"
@@ -277,7 +282,7 @@ jobs:
timeout-minutes: 15
steps:
- name: Download artifacts
uses: dawidd6/action-download-artifact@v2
uses: dawidd6/action-download-artifact@v3
id: download
with:
branch: ${{ github.ref }}
@@ -305,7 +310,7 @@ jobs:
npm version --prefix release "$VERSION"
echo "Updating version in lib/vscode/product.json"
tmp=$(mktemp)
tmp=$(mktemp)
jq ".codeServerVersion = \"$VERSION\"" release/lib/vscode/product.json > "$tmp" && mv "$tmp" release/lib/vscode/product.json
# Ensure it has the same permissions as before
chmod 644 release/lib/vscode/product.json
@@ -314,7 +319,7 @@ jobs:
run: tar -czf package.tar.gz release
- name: Upload npm package artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: npm-release-package
path: ./package.tar.gz

View File

@@ -41,7 +41,7 @@ jobs:
container: "alpine:3.17"
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install test utilities
run: apk add bats checkbashisms
@@ -58,7 +58,7 @@ jobs:
timeout-minutes: 5
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Install lint utilities
run: sudo apt install shellcheck

View File

@@ -12,9 +12,8 @@ on:
# Runs every Monday morning PST
- cron: "17 15 * * 1"
# Cancel in-progress runs for pull requests when developers push
# additional changes, and serialize builds in branches.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-concurrency-to-cancel-any-in-progress-job-or-run
# Cancel in-progress runs for pull requests when developers push additional
# changes, and serialize builds in branches.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
@@ -26,30 +25,21 @@ jobs:
timeout-minutes: 15
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Node.js v16
uses: actions/setup-node@v3
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: "16"
node-version-file: .node-version
- 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:
@@ -60,12 +50,12 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run Trivy vulnerability scanner in repo mode
uses: aquasecurity/trivy-action@cff3e9a7f62c41dd51975266d0ae235709e39c41
uses: aquasecurity/trivy-action@fd25fed6972e341ff0007ddb61f77e88103953c2
with:
scan-type: "fs"
scan-ref: "."
@@ -76,7 +66,7 @@ jobs:
severity: "HIGH,CRITICAL"
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: "trivy-repo-results.sarif"
@@ -90,17 +80,17 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
config-file: ./.github/codeql-config.yml
languages: javascript
- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3

View File

@@ -48,10 +48,10 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner in image mode
uses: aquasecurity/trivy-action@cff3e9a7f62c41dd51975266d0ae235709e39c41
uses: aquasecurity/trivy-action@fd25fed6972e341ff0007ddb61f77e88103953c2
with:
image-ref: "docker.io/codercom/code-server:latest"
ignore-unfixed: true
@@ -60,6 +60,6 @@ jobs:
severity: "HIGH,CRITICAL"
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: "trivy-image-results.sarif"

View File

@@ -1 +1 @@
16
20.11.1

View File

@@ -20,7 +20,321 @@ Code v99.99.999
-->
## [4.10.0](https://github.com/coder/code-server/releases/tag/v4.10.0) - TBD
## Unreleased
Code v1.90.0
## Changed
- Updated to Code 1.90.0.
- Updated Node to 20.11.1.
## Added
- Send contents to the clipboard in the integrated terminal by piping to
`code-server --stdin-to-clipboard` or `code-server -c`.
You may want to make this an alias:
```
alias xclip="code-server --stdin-to-clipboard"
echo -n "hello world" | xclip
```
## [4.89.1](https://github.com/coder/code-server/releases/tag/v4.89.1) - 2024-04-14
Code v1.89.1
## Changed
- Updated to Code 1.89.1.
## [4.89.0](https://github.com/coder/code-server/releases/tag/v4.89.0) - 2024-04-08
Code v1.89.0
## Changed
- Updated to Code 1.89.0.
## [4.23.1](https://github.com/coder/code-server/releases/tag/v4.23.1) - 2024-04-15
Code v1.88.1
## Changed
- Updated to Code 1.88.1.
## [4.23.0](https://github.com/coder/code-server/releases/tag/v4.23.0) - 2024-04-08
Code v1.88.0
## Changed
- Updated to Code 1.88.0.
- Updated Node to 18.18.2.
## Fixed
- Fix masking the exit code when failing to install extensions on the command
line outside the integrated terminal. Installing extensions inside the
integrated terminal still masks the exit code and is an upstream bug.
## [4.22.1](https://github.com/coder/code-server/releases/tag/v4.22.1) - 2024-03-14
Code v1.87.2
## Changed
- Updated to Code 1.87.2.
- Enable keep-alive for proxy agent.
## [4.22.0](https://github.com/coder/code-server/releases/tag/v4.22.0) - 2024-03-03
Code v1.87.0
## Changed
- Updated to Code 1.87.0.
## [4.21.2](https://github.com/coder/code-server/releases/tag/v4.21.2) - 2024-02-28
Code v1.86.2
## Changed
- Updated to Code 1.86.2.
## [4.21.1](https://github.com/coder/code-server/releases/tag/v4.21.1) - 2024-02-09
Code v1.86.1
## Changed
- Updated to Code 1.86.1.
- Updated to Node 18.17.1.
## Added
- Docker images for Fedora and openSUSE.
## [4.21.0](https://github.com/coder/code-server/releases/tag/v4.21.0) - 2024-02-05
Code v1.86.0
## Changed
- Updated to Code 1.86.0.
## [4.20.1](https://github.com/coder/code-server/releases/tag/v4.20.1) - 2024-01-22
Code v1.85.2
## Changed
- Updated to Code 1.85.2.
## Fixed
- Query variables are no longer double-encoded when going over the path proxy.
## [4.20.0](https://github.com/coder/code-server/releases/tag/v4.20.0) - 2023-12-21
Code v1.85.1
### Added
- New flag `--disable-file-uploads` to disable uploading files to the remote by
drag and drop and to disable opening local files via the "show local" button
in the file open prompt. Note that you can still open local files by drag and
dropping the file onto the editor pane.
- Added `wget` to the release image.
### Changed
- Updated to Code 1.85.1.
- The `--disable-file-downloads` flag will now disable the "show local" button
in the file save prompt as well.
- Debian release image updated to use Bookworm.
## [4.19.1](https://github.com/coder/code-server/releases/tag/v4.19.1) - 2023-11-29
Code v1.84.2
### Fixed
- Fixed an issue where parts of the editor would not load (like the file
explorer, source control, etc) when using a workspace file.
## [4.19.0](https://github.com/coder/code-server/releases/tag/v4.19.0) - 2023-11-18
Code v1.84.2
### Changed
- Updated to Code 1.84.2.
## [4.18.0](https://github.com/coder/code-server/releases/tag/v4.18.0) - 2023-10-20
Code v1.83.1
### Changed
- Updated to Code 1.83.1.
## [4.17.1](https://github.com/coder/code-server/releases/tag/v4.17.1) - 2023-09-29
Code v1.82.2
### Fixed
- Make secret storage persistent. For example, logging in with GitHub should
persist between browser refreshes and code-server restarts.
- Issues with argon2 on arm builds should be fixed now.
## [4.17.0](https://github.com/coder/code-server/releases/tag/v4.17.0) - 2023-09-22
Code v1.82.2
### Added
- Japanese locale.
- `CODE_SERVER_HOST` environment variable.
### Changed
- Update to Code 1.82.2. This includes an update to Node 18, which also means
that the minimum glibc is now 2.28. If you need to maintain a lower glibc then
you can take a version of Node 18 that is compiled with a lower glibc and use
that to build code-server (or at a minimum rebuild the native modules).
- Display paths to config files in full rather than abbreviated. If you have
trouble with the password not working please update and make sure the
displayed config paths are what you expect.
### Fixed
- Fix some dependency issues for the standalone arm64 and armv7l releases. If
you had issues with missing or failing modules please try these new builds.
## [4.16.1](https://github.com/coder/code-server/releases/tag/v4.16.1) - 2023-07-31
Code v1.80.2
### Changed
- Updated to Code 1.80.2.
## [4.16.0](https://github.com/coder/code-server/releases/tag/v4.16.0) - 2023-07-28
Code v1.80.1
### Added
- `--disable-proxy` flag. This disables the domain and path proxies but it does
not disable the ports panel in Code. That can be disabled by using
`remote.autoForwardPorts=false` in your settings.
## [4.15.0](https://github.com/coder/code-server/releases/tag/v4.15.0) - 2023-07-21
Code v1.80.1
### Changed
- Updated to Code 1.80.1.
### Added
- `--trusted-origin` flag for specifying origins that you trust but do not
control (for example a reverse proxy).
Code v1.79.2
## [4.14.1](https://github.com/coder/code-server/releases/tag/v4.14.1) - 2023-06-26
Code v1.79.2
### Security
- Remove extra write permissions on the Node binary bundled with the linux-amd64
tarball. If you extract the tar without a umask this could mean the Node
binary would be unexpectedly writable.
### Fixed
- Inability to launch multiple instances of code-server for different users.
### Added
- `--session-socket` CLI flag to configure the location of the session socket.
By default it will be placed in `<user data dir>/code-server-ipc.sock`.
## [4.14.0](https://github.com/coder/code-server/releases/tag/v4.14.0) - 2023-06-16
Code v1.79.2
### Added
- `--domain-proxy` now supports `{{port}}` and `{{host}}` template variables.
### Changed
- Updated to Code 1.79.2
- Files opened from an external terminal will now open in the most closely
related window rather than in the last opened window.
## [4.13.0](https://github.com/coder/code-server/releases/tag/v4.13.0) - 2023-05-19
Code v1.78.2
### Changed
- Updated to Code 1.78.2.
### Fixed
- Proxying files that contain non-ASCII characters.
- Origin check when X-Forwarded-Host contains comma-separated hosts.
## [4.12.0](https://github.com/coder/code-server/releases/tag/v4.12.0) - 2023-04-21
Code v1.77.3
### Changed
- Updated to Code 1.77.3
- Ports panel will use domain-based proxy (instead of the default path-based
proxy) when set via --proxy-domain.
- Apply --app-name to the PWA title.
### Added
- Thai translation for login page.
- Debug logs around the origin security check. If you are getting forbidden
errors on web sockets please run code-server with `--log debug` to see why the
requests are being blocked.
## [4.11.0](https://github.com/coder/code-server/releases/tag/v4.11.0) - 2023-03-16
Code v1.76.1
### Changed
- Updated to Code 1.76.1
## [4.10.1](https://github.com/coder/code-server/releases/tag/v4.10.1) - 2023-03-04
Code v1.75.1
### Security
Added an origin check to web sockets to prevent cross-site hijacking attacks on
users using older or niche browser that do not support SameSite cookies and
attacks across sub-domains that share the same root domain.
The check requires the host header to be set so if you use a reverse proxy
ensure it forwards that information otherwise web sockets will be blocked.
## [4.10.0](https://github.com/coder/code-server/releases/tag/v4.10.0) - 2023-02-15
Code v1.75.1
@@ -30,7 +344,7 @@ Code v1.75.1
### Removed
- Removed `--link` (was deprecated in 4.0.1).
- Removed `--link` (was deprecated over thirteen months ago in 4.0.1).
## [4.9.1](https://github.com/coder/code-server/releases/tag/v4.9.1) - 2022-12-15
@@ -154,7 +468,7 @@ Code v1.71.0
### Fixed
- Add flags --unsafe-perm --legacy-peer-deps in `npm-postinstsall.sh` which ensures installing with npm works correctly
- Add flags --unsafe-perm --legacy-peer-deps in `npm-postinstall.sh` which ensures installing with npm works correctly
## [4.6.1](https://github.com/coder/code-server/releases/tag/v4.6.1) - 2022-09-31

View File

@@ -29,7 +29,7 @@ This directory contains scripts used for the development of code-server.
- [./ci/dev/watch.ts](./dev/watch.ts) (`yarn watch`)
- Starts a process to build and launch code-server and restart on any code changes.
- Example usage in [./docs/CONTRIBUTING.md](../docs/CONTRIBUTING.md).
- [./ci/dev/gen_icons.sh](./ci/dev/gen_icons.sh) (`yarn icons`)
- [./ci/dev/gen_icons.sh](./dev/gen_icons.sh) (`yarn icons`)
- Generates the various icons from a single `.svg` favicon in
`src/browser/media/favicon.svg`.
- Requires [imagemagick](https://imagemagick.org/index.php)
@@ -75,7 +75,7 @@ You can disable minification by setting `MINIFY=`.
This directory contains the release docker container image.
- [./ci/steps/build-docker-buildx-push.sh](./ci/steps/docker-buildx-push.sh)
- [./ci/steps/build-docker-buildx-push.sh](./steps/docker-buildx-push.sh)
- Builds the release containers with tags `codercom/code-server-$ARCH:$VERSION` for amd64 and arm64 with `docker buildx` and pushes them.
- Assumes debian releases are ready in `./release-packages`.

View File

@@ -27,7 +27,7 @@ main() {
release_archive() {
local release_name="code-server-$VERSION-$OS-$ARCH"
if [[ $OS == "linux" ]]; then
tar -czf "release-packages/$release_name.tar.gz" --transform "s/^\.\/release-standalone/$release_name/" ./release-standalone
tar -czf "release-packages/$release_name.tar.gz" --owner=0 --group=0 --transform "s/^\.\/release-standalone/$release_name/" ./release-standalone
else
tar -czf "release-packages/$release_name.tar.gz" -s "/^release-standalone/$release_name/" release-standalone
fi

View File

@@ -56,7 +56,6 @@ bundle_code_server() {
}
EOF
) > "$RELEASE_PATH/package.json"
rsync yarn.lock "$RELEASE_PATH"
mv npm-shrinkwrap.json "$RELEASE_PATH"
rsync ci/build/npm-postinstall.sh "$RELEASE_PATH/postinstall.sh"
@@ -95,12 +94,10 @@ bundle_vscode() {
"$VSCODE_SRC_PATH/remote/package.json" \
"$VSCODE_SRC_PATH/package.json" > "$VSCODE_OUT_PATH/package.json"
rsync "$VSCODE_SRC_PATH/remote/yarn.lock" "$VSCODE_OUT_PATH/yarn.lock"
mv "$VSCODE_SRC_PATH/remote/npm-shrinkwrap.json" "$VSCODE_OUT_PATH/npm-shrinkwrap.json"
# Include global extension dependencies as well.
rsync "$VSCODE_SRC_PATH/extensions/package.json" "$VSCODE_OUT_PATH/extensions/package.json"
rsync "$VSCODE_SRC_PATH/extensions/yarn.lock" "$VSCODE_OUT_PATH/extensions/yarn.lock"
mv "$VSCODE_SRC_PATH/extensions/npm-shrinkwrap.json" "$VSCODE_OUT_PATH/extensions/npm-shrinkwrap.json"
rsync "$VSCODE_SRC_PATH/extensions/postinstall.mjs" "$VSCODE_OUT_PATH/extensions/postinstall.mjs"
}

View File

@@ -1,10 +1,6 @@
#!/usr/bin/env bash
set -euo pipefail
# This is due to an upstream issue with RHEL7/CentOS 7 comptability with node-argon2
# See: https://github.com/cdr/code-server/pull/3422#pullrequestreview-677765057
export npm_config_build_from_source=true
main() {
cd "$(dirname "${0}")/../.."
@@ -13,17 +9,19 @@ main() {
rsync "$RELEASE_PATH/" "$RELEASE_PATH-standalone"
RELEASE_PATH+=-standalone
# We cannot find the path to node from $PATH because yarn shims a script to ensure
# we use the same version it's using so we instead run a script with yarn that
# will print the path to node.
# We cannot get the path to Node from $PATH (for example via `which node`)
# because Yarn shims a script called `node` and we would end up just copying
# that script. Instead we run Node and have it print its actual path.
local node_path
node_path="$(yarn -s node <<< 'console.info(process.execPath)')"
node_path="$(node <<< 'console.info(process.execPath)')"
mkdir -p "$RELEASE_PATH/bin"
mkdir -p "$RELEASE_PATH/lib"
rsync ./ci/build/code-server.sh "$RELEASE_PATH/bin/code-server"
rsync "$node_path" "$RELEASE_PATH/lib/node"
chmod 755 "$RELEASE_PATH/lib/node"
pushd "$RELEASE_PATH"
npm install --unsafe-perm --omit=dev
popd

View File

@@ -15,7 +15,7 @@ copy-bin-script() {
local dest="lib/vscode-reh-web-linux-x64/bin/$script"
cp "lib/vscode/resources/server/bin/$script" "$dest"
sed -i.bak "s/@@VERSION@@/$(vscode_version)/g" "$dest"
sed -i.bak "s/@@COMMIT@@/$VSCODE_DISTRO_COMMIT/g" "$dest"
sed -i.bak "s/@@COMMIT@@/$BUILD_SOURCEVERSION/g" "$dest"
sed -i.bak "s/@@APPNAME@@/code-server/g" "$dest"
# Fix Node path on Darwin and Linux.
@@ -40,6 +40,16 @@ main() {
source ./ci/lib.sh
# Set the commit Code will embed into the product.json. We need to do this
# since Code tries to get the commit from the `.git` directory which will fail
# as it is a submodule.
#
# Also, we use code-server's commit rather than VS Code's otherwise it would
# not update when only our patch files change, and that will cause caching
# issues where the browser keeps using outdated code.
export BUILD_SOURCEVERSION
BUILD_SOURCEVERSION=$(git rev-parse HEAD)
pushd lib/vscode
if [[ ! ${VERSION-} ]]; then
@@ -48,14 +58,11 @@ main() {
exit 1
fi
# Set the commit Code will embed into the product.json. We need to do this
# since Code tries to get the commit from the `.git` directory which will fail
# as it is a submodule.
export VSCODE_DISTRO_COMMIT
VSCODE_DISTRO_COMMIT=$(git rev-parse HEAD)
# Add the date, our name, links, and enable telemetry (this just makes
# telemetry available; telemetry can still be disabled by flag or setting).
# Add the date, our name, links, enable telemetry (this just makes telemetry
# available; telemetry can still be disabled by flag or setting), and
# configure trusted extensions (since some, like github.copilot-chat, never
# ask to be trusted and this is the only way to get auth working).
#
# This needs to be done before building as Code will read this file and embed
# it into the client-side code.
git checkout product.json # Reset in case the script exited early.
@@ -89,6 +96,11 @@ main() {
"linkProtectionTrustedDomains": [
"https://open-vsx.org"
],
"trustedExtensionAuthAccess": [
"vscode.git", "vscode.github",
"github.vscode-pull-request-github",
"github.copilot", "github.copilot-chat"
],
"aiConfig": {
"ariaKey": "code-server"
}
@@ -109,6 +121,15 @@ EOF
popd
pushd lib/vscode-reh-web-linux-x64
# Make sure Code took the version we set in the environment variable. Not
# having a version will break display languages.
if ! jq -e .commit product.json; then
echo "'commit' is missing from product.json"
exit 1
fi
popd
# These provide a `code-server` command in the integrated terminal to open
# files in the current instance.
delete-bin-script remote-cli/code-server

View File

@@ -51,11 +51,19 @@ symlink_bin_script() {
cd "$oldpwd"
}
OS="$(os)"
command_exists() {
if [ ! "$1" ]; then return 1; fi
command -v "$@" > /dev/null
}
# This is due to an upstream issue with RHEL7/CentOS 7 comptability with node-argon2
# See: https://github.com/cdr/code-server/pull/3422#pullrequestreview-677765057
export npm_config_build_from_source=true
is_root() {
if command_exists id && [ "$(id -u)" = 0 ]; then
return 0
fi
return 1
}
OS="$(os)"
main() {
# Grabs the major version of node from $npm_config_user_agent which looks like
@@ -68,8 +76,8 @@ main() {
echo "USE AT YOUR OWN RISK!"
fi
if [ "$major_node_version" -ne "${FORCE_NODE_VERSION:-16}" ]; then
echo "ERROR: code-server currently requires node v16."
if [ "$major_node_version" -ne "${FORCE_NODE_VERSION:-20}" ]; then
echo "ERROR: code-server currently requires node v20."
if [ -n "$FORCE_NODE_VERSION" ]; then
echo "However, you have overrided the version check to use v$FORCE_NODE_VERSION."
fi
@@ -79,17 +87,20 @@ main() {
exit 1
fi
case "${npm_config_user_agent-}" in npm*)
# We are running under npm.
if [ "${npm_config_unsafe_perm-}" != "true" ]; then
echo "Please pass --unsafe-perm to npm to install code-server"
echo "Otherwise the postinstall script does not have permissions to run"
echo "See https://docs.npmjs.com/misc/config#unsafe-perm"
echo "See https://stackoverflow.com/questions/49084929/npm-sudo-global-installation-unsafe-perm"
exit 1
fi
;;
esac
# Under npm, if we are running as root, we need --unsafe-perm otherwise
# post-install scripts will not have sufficient permissions to do their thing.
if is_root; then
case "${npm_config_user_agent-}" in npm*)
if [ "${npm_config_unsafe_perm-}" != "true" ]; then
echo "Please pass --unsafe-perm to npm to install code-server"
echo "Otherwise post-install scripts will not have permissions to run"
echo "See https://docs.npmjs.com/misc/config#unsafe-perm"
echo "See https://stackoverflow.com/questions/49084929/npm-sudo-global-installation-unsafe-perm"
exit 1
fi
;;
esac
fi
if ! vscode_install; then
echo "You may not have the required dependencies to build the native modules."
@@ -113,29 +124,40 @@ install_with_yarn_or_npm() {
# HACK: NPM's use of semver doesn't like resolving some peerDependencies that vscode (upstream) brings in the form of pre-releases.
# The legacy behavior doesn't complain about pre-releases being used, falling back to that for now.
# See https://github.com//pull/5071
npm install --unsafe-perm --legacy-peer-deps --omit=dev
if ! npm install --unsafe-perm --legacy-peer-deps --omit=dev; then
return 1
fi
;;
yarn*)
yarn --production --frozen-lockfile --no-default-rc
if ! yarn --production --frozen-lockfile --no-default-rc; then
return 1
fi
;;
*)
echo "Could not determine which package manager is being used to install code-server"
exit 1
;;
esac
return 0
}
vscode_install() {
echo 'Installing Code dependencies...'
cd lib/vscode
install_with_yarn_or_npm
if ! install_with_yarn_or_npm; then
return 1
fi
symlink_asar
symlink_bin_script remote-cli code code-server
symlink_bin_script helpers browser browser .sh
cd extensions
install_with_yarn_or_npm
if ! install_with_yarn_or_npm; then
return 1
fi
return 0
}
main "$@"

View File

@@ -15,9 +15,9 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 3.5.1
version: 3.20.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
appVersion: 4.9.1
appVersion: 4.89.1

View File

@@ -20,6 +20,9 @@ spec:
labels:
app.kubernetes.io/name: {{ include "code-server.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- if .Values.podAnnotations }}
annotations: {{- toYaml .Values.podAnnotations | nindent 8 }}
{{- end }}
spec:
imagePullSecrets: {{- toYaml .Values.imagePullSecrets | nindent 8 }}
{{- if .Values.hostnameOverride }}
@@ -174,9 +177,12 @@ spec:
{{- if .existingClaim }}
persistentVolumeClaim:
claimName: {{ .existingClaim }}
{{- else }}
{{- else if .hostPath }}
hostPath:
path: {{ .hostPath }}
type: Directory
{{- else }}
emptyDir:
{{- toYaml .emptyDir | nindent 10 }}
{{- end }}
{{- end }}

View File

@@ -1,3 +1,4 @@
{{- if not .Values.existingSecret }}
apiVersion: v1
kind: Secret
metadata:
@@ -11,8 +12,9 @@ metadata:
app.kubernetes.io/managed-by: {{ .Release.Service }}
type: Opaque
data:
{{ if .Values.password }}
{{- if .Values.password }}
password: "{{ .Values.password | b64enc }}"
{{ else }}
{{- else }}
password: "{{ randAlphaNum 24 | b64enc }}"
{{ end }}
{{- end }}
{{- end }}

View File

@@ -6,7 +6,7 @@ replicaCount: 1
image:
repository: codercom/code-server
tag: '4.9.1'
tag: '4.89.1'
pullPolicy: Always
# Specifies one or more secrets to be used when pulling images from a
@@ -71,7 +71,7 @@ extraArgs: []
# Optional additional environment variables
extraVars: []
# - name: DISABLE_TELEMETRY
# value: true
# value: "true"
# - name: DOCKER_HOST
# value: "tcp://localhost:2375"
@@ -190,6 +190,7 @@ extraVolumeMounts: []
# readOnly: true
# existingClaim: volume-claim
# hostPath: ""
# emptyDir: {}
extraConfigmapMounts: []
# - name: certs-configmap

View File

@@ -1,6 +1,6 @@
# syntax=docker/dockerfile:experimental
ARG BASE=debian:11
ARG BASE=debian:12
FROM scratch AS packages
COPY release-packages/code-server*.deb /tmp/
@@ -10,18 +10,19 @@ RUN apt-get update \
&& apt-get install -y \
curl \
dumb-init \
zsh \
htop \
locales \
man \
nano \
git \
git-lfs \
procps \
openssh-client \
sudo \
vim.tiny \
htop \
locales \
lsb-release \
man-db \
nano \
openssh-client \
procps \
sudo \
vim-tiny \
wget \
zsh \
&& git lfs install \
&& rm -rf /var/lib/apt/lists/*
@@ -34,7 +35,7 @@ RUN adduser --gecos '' --disabled-password coder \
&& echo "coder ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/nopasswd
RUN ARCH="$(dpkg --print-architecture)" \
&& curl -fsSL "https://github.com/boxboat/fixuid/releases/download/v0.5/fixuid-0.5-linux-$ARCH.tar.gz" | tar -C /usr/local/bin -xzf - \
&& curl -fsSL "https://github.com/boxboat/fixuid/releases/download/v0.6.0/fixuid-0.6.0-linux-$ARCH.tar.gz" | tar -C /usr/local/bin -xzf - \
&& chown root:root /usr/local/bin/fixuid \
&& chmod 4755 /usr/local/bin/fixuid \
&& mkdir -p /etc/fixuid \

View File

@@ -0,0 +1,51 @@
# syntax=docker/dockerfile:experimental
ARG BASE=fedora:39
FROM scratch AS packages
COPY release-packages/code-server*.rpm /tmp/
FROM $BASE
RUN dnf update -y \
&& dnf install -y \
curl \
git \
git-lfs \
htop \
nano \
openssh-clients \
procps \
wget \
zsh \
dumb-init \
glibc-langpack-en \
&& rm -rf /var/cache/dnf
RUN git lfs install
ENV LANG=en_US.UTF-8
RUN echo 'LANG="en_US.UTF-8"' > /etc/locale.conf
RUN useradd -u 1000 coder && echo "coder ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/nopasswd
RUN ARCH="$(uname -m | sed 's/x86_64/amd64/g' | sed 's/aarch64/arm64/g')" \
&& curl -fsSL "https://github.com/boxboat/fixuid/releases/download/v0.6.0/fixuid-0.6.0-linux-$ARCH.tar.gz" | tar -C /usr/local/bin -xzf - \
&& chown root:root /usr/local/bin/fixuid \
&& chmod 4755 /usr/local/bin/fixuid \
&& mkdir -p /etc/fixuid \
&& printf "user: coder\ngroup: coder\n" > /etc/fixuid/config.yml
COPY ci/release-image/entrypoint.sh /usr/bin/entrypoint.sh
RUN --mount=from=packages,src=/tmp,dst=/tmp/packages rpm -i /tmp/packages/code-server*$(uname -m | sed 's/x86_64/amd64/g' | sed 's/aarch64/arm64/g').rpm
# Allow users to have scripts run on container startup to prepare workspace.
# https://github.com/coder/code-server/issues/5177
ENV ENTRYPOINTD=${HOME}/entrypoint.d
EXPOSE 8080
# This way, if someone sets $DOCKER_USER, docker-exec will still work as
# the uid will remain the same. note: only relevant if -u isn't passed to
# docker-run.
USER 1000
ENV USER=coder
WORKDIR /home/coder
ENTRYPOINT ["/usr/bin/entrypoint.sh", "--bind-addr", "0.0.0.0:8080", "."]

View File

@@ -0,0 +1,51 @@
# syntax=docker/dockerfile:experimental
ARG BASE=opensuse/tumbleweed
FROM scratch AS packages
COPY release-packages/code-server*.rpm /tmp/
FROM $BASE
RUN zypper dup -y \
&& zypper in -y \
curl \
git \
git-lfs \
htop \
nano \
openssh-clients \
procps \
wget \
zsh \
sudo \
catatonit \
&& rm -rf /var/cache/zypp /var/cache/zypper
RUN git lfs install
ENV LANG=en_US.UTF-8
RUN echo 'LANG="en_US.UTF-8"' > /etc/locale.conf
RUN useradd -u 1000 coder && echo "coder ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/nopasswd
RUN ARCH="$(uname -m | sed 's/x86_64/amd64/g' | sed 's/aarch64/arm64/g')" \
&& curl -fsSL "https://github.com/boxboat/fixuid/releases/download/v0.6.0/fixuid-0.6.0-linux-$ARCH.tar.gz" | tar -C /usr/local/bin -xzf - \
&& chown root:root /usr/local/bin/fixuid \
&& chmod 4755 /usr/local/bin/fixuid \
&& mkdir -p /etc/fixuid \
&& printf "user: coder\ngroup: coder\n" > /etc/fixuid/config.yml
COPY ci/release-image/entrypoint-catatonit.sh /usr/bin/entrypoint-catatonit.sh
RUN --mount=from=packages,src=/tmp,dst=/tmp/packages rpm -i /tmp/packages/code-server*$(uname -m | sed 's/x86_64/amd64/g' | sed 's/aarch64/arm64/g').rpm
# Allow users to have scripts run on container startup to prepare workspace.
# https://github.com/coder/code-server/issues/5177
ENV ENTRYPOINTD=${HOME}/entrypoint.d
EXPOSE 8080
# This way, if someone sets $DOCKER_USER, docker-exec will still work as
# the uid will remain the same. note: only relevant if -u isn't passed to
# docker-run.
USER 1000
ENV USER=coder
WORKDIR /home/coder
ENTRYPOINT ["/usr/bin/entrypoint-catatonit.sh", "--bind-addr", "0.0.0.0:8080", "."]

View File

@@ -16,8 +16,11 @@ variable "GITHUB_REGISTRY" {
group "default" {
targets = [
"code-server-debian-11",
"code-server-debian-12",
"code-server-ubuntu-focal",
"code-server-ubuntu-noble",
"code-server-fedora-39",
"code-server-opensuse-tumbleweed",
]
}
@@ -45,12 +48,12 @@ function "gen_tags_for_docker_and_ghcr" {
)
}
target "code-server-debian-11" {
target "code-server-debian-12" {
dockerfile = "ci/release-image/Dockerfile"
tags = concat(
gen_tags_for_docker_and_ghcr(""),
gen_tags_for_docker_and_ghcr("debian"),
gen_tags_for_docker_and_ghcr("bullseye"),
gen_tags_for_docker_and_ghcr("bookworm"),
)
platforms = ["linux/amd64", "linux/arm64"]
}
@@ -66,3 +69,38 @@ target "code-server-ubuntu-focal" {
}
platforms = ["linux/amd64", "linux/arm64"]
}
target "code-server-ubuntu-noble" {
dockerfile = "ci/release-image/Dockerfile"
tags = concat(
gen_tags_for_docker_and_ghcr("noble"),
)
args = {
BASE = "ubuntu:noble"
}
platforms = ["linux/amd64", "linux/arm64"]
}
target "code-server-fedora-39" {
dockerfile = "ci/release-image/Dockerfile.fedora"
tags = concat(
gen_tags_for_docker_and_ghcr("fedora"),
gen_tags_for_docker_and_ghcr("39"),
)
args = {
BASE = "fedora:39"
}
platforms = ["linux/amd64", "linux/arm64"]
}
target "code-server-opensuse-tumbleweed" {
dockerfile = "ci/release-image/Dockerfile.opensuse"
tags = concat(
gen_tags_for_docker_and_ghcr("opensuse"),
gen_tags_for_docker_and_ghcr("tumbleweed"),
)
args = {
BASE = "opensuse/tumbleweed"
}
platforms = ["linux/amd64", "linux/arm64"]
}

View File

@@ -0,0 +1,27 @@
#!/bin/sh
set -eu
# We do this first to ensure sudo works below when renaming the user.
# Otherwise the current container UID may not exist in the passwd database.
eval "$(fixuid -q)"
if [ "${DOCKER_USER-}" ]; then
USER="$DOCKER_USER"
if [ "$DOCKER_USER" != "$(whoami)" ]; then
echo "$DOCKER_USER ALL=(ALL) NOPASSWD:ALL" | sudo tee -a /etc/sudoers.d/nopasswd > /dev/null
# Unfortunately we cannot change $HOME as we cannot move any bind mounts
# nor can we bind mount $HOME into a new home as that requires a privileged container.
sudo usermod --login "$DOCKER_USER" coder
sudo groupmod -n "$DOCKER_USER" coder
sudo sed -i "/coder/d" /etc/sudoers.d/nopasswd
fi
fi
# Allow users to have scripts run on container startup to prepare workspace.
# https://github.com/coder/code-server/issues/5177
if [ -d "${ENTRYPOINTD}" ]; then
find "${ENTRYPOINTD}" -type f -executable -print -exec {} \;
fi
exec catatonit -- /usr/bin/code-server "$@"

View File

@@ -37,7 +37,7 @@ for [VS
Code](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#prerequisites).
Here is what is needed:
- `node` v16.x
- `node` v20.x
- `git` v2.x or greater
- [`git-lfs`](https://git-lfs.github.com)
- [`yarn`](https://classic.yarnpkg.com/en/)
@@ -63,7 +63,7 @@ Here is what is needed:
If you're developing code-server on Linux, make sure you have installed or install the following dependencies:
```shell
sudo apt-get install build-essential g++ libx11-dev libxkbfile-dev libsecret-1-dev python-is-python3
sudo apt-get install build-essential g++ libx11-dev libxkbfile-dev libsecret-1-dev libkrb5-dev python-is-python3
```
These are required by Code. See [their Wiki](https://github.com/microsoft/vscode/wiki/How-to-Contribute#prerequisites) for more information.
@@ -127,13 +127,13 @@ while quilt push; do quilt refresh; done
0. You can go through the patch stack with `quilt push` and `quilt pop`.
1. Create a new patch (`quilt new {name}.diff`) or use an existing patch.
2. Add the file(s) you are patching (`quilt add [-P patch] {file}`). A file
1. Add the file(s) you are patching (`quilt add [-P patch] {file}`). A file
**must** be added before you make changes to it.
3. Make your changes. Patches do not need to be independent of each other but
1. Make your changes. Patches do not need to be independent of each other but
each patch must result in a working code-server without any broken in-between
states otherwise they are difficult to test and modify.
4. Add your changes to the patch (`quilt refresh`)
5. Add a comment in the patch about the reason for the patch and how to
1. Add your changes to the patch (`quilt refresh`)
1. Add a comment in the patch about the reason for the patch and how to
reproduce the behavior it fixes or adds. Every patch should have an e2e test
as well.

View File

@@ -14,6 +14,7 @@
- [How do I install an extension manually?](#how-do-i-install-an-extension-manually)
- [How do I use my own extensions marketplace?](#how-do-i-use-my-own-extensions-marketplace)
- [Where are extensions stored?](#where-are-extensions-stored)
- [Where is VS Code configuration stored?](#where-is-vs-code-configuration-stored)
- [How can I reuse my VS Code configuration?](#how-can-i-reuse-my-vs-code-configuration)
- [How does code-server decide what workspace or folder to open?](#how-does-code-server-decide-what-workspace-or-folder-to-open)
- [How do I access my Documents/Downloads/Desktop folders in code-server on macOS?](#how-do-i-access-my-documentsdownloadsdesktop-folders-in-code-server-on-macos)
@@ -34,6 +35,7 @@
- [Are there community projects involving code-server?](#are-there-community-projects-involving-code-server)
- [How do I change the port?](#how-do-i-change-the-port)
- [How do I hide the coder/coder promotion in Help: Getting Started?](#how-do-i-hide-the-codercoder-promotion-in-help-getting-started)
- [How do I disable the proxy?](#how-do-i-disable-the-proxy)
- [How do I disable file download?](#how-do-i-disable-file-download)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
@@ -88,6 +90,12 @@ app (PWA):
1. Start the editor
2. Click the **plus** icon in the URL toolbar to install the PWA
If you use Firefox, you can use the appropriate extension to install PWA.
1. Go to the installation [website](https://addons.mozilla.org/en-US/firefox/addon/pwas-for-firefox/) of the add-on
2. Add the add-on to Firefox
3. Follow the os-specific instructions on how to install the runtime counterpart
For other browsers, you'll have to remap keybindings for shortcuts to work.
## Why can't code-server use Microsoft's extension marketplace?
@@ -169,10 +177,10 @@ If you own a marketplace that implements the VS Code Extension Gallery API, you
can point code-server to it by setting `$EXTENSIONS_GALLERY`.
This corresponds directly with the `extensionsGallery` entry in in VS Code's `product.json`.
For example, to use the legacy Coder extensions marketplace:
For example:
```bash
export EXTENSIONS_GALLERY='{"serviceUrl": "https://extensions.coder.com/api"}'
export EXTENSIONS_GALLERY='{"serviceUrl": "https://my-extensions/api"}'
```
Though you can technically use Microsoft's marketplace in this manner, we
@@ -185,10 +193,20 @@ docs](https://github.com/VSCodium/vscodium/blob/master/DOCS.md#extensions--marke
## Where are extensions stored?
Extensions are store, by default, to `~/.local/share/code-server/extensions`.
Extensions are stored in `~/.local/share/code-server/extensions` by default.
If you set the `XDG_DATA_HOME` environment variable, the data directory will be
`$XDG_DATA_HOME/code-server/extensions`. In general, we try to follow the XDG directory spec.
On Linux and macOS if you set the `XDG_DATA_HOME` environment variable, the
extensions directory will be `$XDG_DATA_HOME/code-server/extensions`. In
general, we try to follow the XDG directory spec.
## Where is VS Code configuration stored?
VS Code configuration such as settings and keybindings are stored in
`~/.local/share/code-server` by default.
On Linux and macOS if you set the `XDG_DATA_HOME` environment variable, the data
directory will be `$XDG_DATA_HOME/code-server`. In general, we try to follow the
XDG directory spec.
## How can I reuse my VS Code configuration?
@@ -338,6 +356,12 @@ hashed-password: "$argon2i$v=19$m=4096,t=3,p=1$wST5QhBgk2lu1ih4DMuxvg$LS1alrVdIW
The `hashed-password` field takes precedence over `password`.
If you're using Docker Compose file, in order to make this work, you need to change all the single $ to $$. For example:
```yaml
- HASHED_PASSWORD=$$argon2i$$v=19$$m=4096,t=3,p=1$$wST5QhBgk2lu1ih4DMuxvg$$LS1alrVdIWtvZHwnzCM1DUGg+5DTO3Dt1d5v9XtLws4
```
## Is multi-tenancy possible?
If you want to run multiple code-servers on shared infrastructure, we recommend
@@ -390,19 +414,13 @@ Theia doesn't allow you to reuse your existing VS Code config.
## What's the difference between code-server and OpenVSCode-Server?
code-server and OpenVSCode-Server both allow you to access VS Code via a
browser. The two projects also use their own [forks of VS Code](https://github.com/coder/vscode) to
leverage modern VS Code APIs and stay up to date with the upsteam version.
browser. OpenVSCode-Server is a direct fork of VS Code with changes comitted
directly while code-server pulls VS Code in via a submodule and makes changes
via patch files.
However, OpenVSCode-Server is scoped at only making VS Code available in the web browser.
code-server includes some other features:
- password auth
- proxy web ports
- certificate support
- plugin API
- settings sync (coming soon)
For more details, see [this discussion post](https://github.com/coder/code-server/discussions/4267#discussioncomment-1411583).
However, OpenVSCode-Server is scoped at only making VS Code available as-is in
the web browser. code-server contains additional changes to make the self-hosted
experience better (see the next section for details).
## What's the difference between code-server and GitHub Codespaces?
@@ -410,8 +428,24 @@ Both code-server and GitHub Codespaces allow you to access VS Code via a
browser. GitHub Codespaces, however, is a closed-source, paid service offered by
GitHub and Microsoft.
On the other hand, code-server is self-hosted, free, open-source, and
can be run on any machine with few limitations.
On the other hand, code-server is self-hosted, free, open-source, and can be run
on any machine with few limitations.
Specific changes include:
- Password authentication
- The ability to host at sub-paths
- Self-contained web views that do not call out to Microsoft's servers
- The ability to use your own marketplace and collect your own telemetry
- Built-in proxy for accessing ports on the remote machine integrated into
VS Code's ports panel
- Wrapper process that spawns VS Code on-demand and has a separate CLI
- Notification when updates are available
- [Some other things](https://github.com/coder/code-server/tree/main/patches)
Some of these changes appear very unlikely to ever be adopted by Microsoft.
Some may make their way upstream, further closing the gap, but at the moment it
looks like there will always be some subtle differences.
## Does code-server have any security login validation?
@@ -437,6 +471,19 @@ You can pass the flag `--disable-getting-started-override` to `code-server` or
you can set the environment variable `CS_DISABLE_GETTING_STARTED_OVERRIDE=1` or
`CS_DISABLE_GETTING_STARTED_OVERRIDE=true`.
## How do I disable the proxy?
You can pass the flag `--disable-proxy` to `code-server` or
you can set the environment variable `CS_DISABLE_PROXY=1` or
`CS_DISABLE_PROXY=true`.
Note, this option currently only disables the proxy routes to forwarded ports, including
the domain and path proxy routes over HTTP and WebSocket; however, it does not
disable the automatic port forwarding in the VS Code workbench itself. In other words,
user will still see the Ports tab and notifications, but will not be able to actually
use access the ports. It is recommended to set `remote.autoForwardPorts` to `false`
when using the option.
## How do I disable file download?
You can pass the flag `--disable-file-downloads` to `code-server`

View File

@@ -171,7 +171,7 @@ We publish to AUR as a package [here](https://aur.archlinux.org/packages/code-se
#### Docker
We publish code-server as a Docker image [here](https://registry.hub.docker.com/r/codercom/code-server), tagging it both with the version and latest.
We publish code-server as a Docker image [here](https://hub.docker.com/r/codercom/code-server), tagging it both with the version and latest.
This is currently automated with the release process.

View File

@@ -5,7 +5,8 @@
Run [VS Code](https://github.com/Microsoft/vscode) on any machine anywhere and
access it in the browser.
![Screenshot](./assets/screenshot.png)
![Screenshot](./assets/screenshot-1.png)
![Screenshot](./assets/screenshot-2.png)
## Highlights
@@ -72,7 +73,7 @@ details.
Interested in [working at Coder](https://coder.com/careers)? Check out [our open
positions](https://coder.com/careers#openings)!
## For Organizations
## For Teams
Want remote development for your organization or enterprise? Visit [our
website](https://coder.com) to learn more about Coder.
We develop [coder/coder](https://cdr.co/coder-github) to help teams to
adopt remote development.

View File

@@ -11,13 +11,21 @@ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
```
6. Exit the terminal using `exit` and then reopen the terminal
7. Install and use Node.js 16:
7. Install and use Node.js 20:
```shell
nvm install 16
nvm use 16
nvm install 18
nvm use 18
```
8. Install code-server globally on device with: `npm install --global code-server --unsafe-perm`
8. Install code-server globally on device with: `npm install --global code-server`
9. Run code-server with `code-server`
10. Access on localhost:8080 in your browser
# Running code-server using Nix-on-Droid
1. Install Nix-on-Droid from [F-Droid](https://f-droid.org/packages/com.termux.nix/)
2. Start app
3. Spawn a shell with code-server by running `nix-shell -p code-server`
4. Run code-server with `code-server`
5. Access on localhost:8080 in your browser

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 KiB

View File

@@ -33,5 +33,16 @@ resource "coder_app" "code-server" {
}
```
Or use our official [`code-server`](https://registry.coder.com/modules/code-server) module from the Coder [module registry](htpps://registry.coder.com/modules):
```terraform
module "code-server" {
source = "registry.coder.com/modules/code-server/coder"
version = "1.0.5"
agent_id = coder_agent.example.id
extensions = ["dracula-theme.theme-dracula", "ms-azuretools.vscode-docker"]
}
```
If you run into issues, ask for help on the `coder/coder` [Discussions
here](https://github.com/coder/coder/discussions).

View File

@@ -19,6 +19,7 @@
- [Proxying to create a React app](#proxying-to-create-a-react-app)
- [Proxying to a Vue app](#proxying-to-a-vue-app)
- [Proxying to an Angular app](#proxying-to-an-angular-app)
- [Proxying to a Svelte app](#proxying-to-a-svelte-app)
- [SSH into code-server on VS Code](#ssh-into-code-server-on-vs-code)
- [Option 1: cloudflared tunnel](#option-1-cloudflared-tunnel)
- [Option 2: ngrok tunnel](#option-2-ngrok-tunnel)
@@ -138,9 +139,9 @@ sudo apt install caddy
1. Replace `/etc/caddy/Caddyfile` using `sudo` so that the file looks like this:
```text
mydomain.com
reverse_proxy 127.0.0.1:8080
mydomain.com {
reverse_proxy 127.0.0.1:8080
}
```
If you want to serve code-server from a sub-path, you can do so as follows:
@@ -190,7 +191,7 @@ At this point, you should be able to access code-server via
location / {
proxy_pass http://localhost:8080/;
proxy_set_header Host $host;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
proxy_set_header Accept-Encoding gzip;
@@ -414,6 +415,27 @@ In order to use code-server's built-in proxy with Angular, you need to make the
For additional context, see [this GitHub Discussion](https://github.com/coder/code-server/discussions/5439#discussioncomment-3371983).
### Proxying to a Svelte app
In order to use code-server's built-in proxy with Svelte, you need to make the following changes in your app:
1. Add `svelte.config.js` if you don't already have one
2. Update the values to match this (you can use any free port):
```js
const config = {
kit: {
paths: {
base: "/absproxy/5173",
},
},
}
```
3. Access app at `<code-server-root>/absproxy/5173/` e.g. `http://localhost:8080/absproxy/5173/
For additional context, see [this Github Issue](https://github.com/sveltejs/kit/issues/2958)
## SSH into code-server on VS Code
[![SSH](https://img.shields.io/badge/SSH-363636?style=for-the-badge&logo=GNU+Bash&logoColor=ffffff)](https://ohmyz.sh/) [![Terminal](https://img.shields.io/badge/Terminal-2E2E2E?style=for-the-badge&logo=Windows+Terminal&logoColor=ffffff)](https://img.shields.io/badge/Terminal-2E2E2E?style=for-the-badge&logo=Windows+Terminal&logoColor=ffffff) [![Visual Studio Code](https://img.shields.io/badge/Visual_Studio_Code-007ACC?style=for-the-badge&logo=Visual+Studio+Code&logoColor=ffffff)](vscode:extension/ms-vscode-remote.remote-ssh)

View File

@@ -103,10 +103,9 @@ _exact_ same commands presented in the rest of this document.
We recommend installing with `npm` when:
1. You aren't using a machine with `amd64` or `arm64`.
1. You are installing code-server on Windows
1. You're on Linux with `glibc` < v2.17, `glibcxx` < v3.4.18 on `amd64`, `glibc`
< v2.23, or `glibcxx` < v3.4.21 on `arm64`.
1. You're running Alpine Linux or are using a non-glibc libc. See
2. You are installing code-server on Windows.
3. You're on Linux with `glibc` < v2.28 or `glibcxx` < v3.4.21.
4. You're running Alpine Linux or are using a non-glibc libc. See
[#1430](https://github.com/coder/code-server/issues/1430#issuecomment-629883198)
for more information.
@@ -123,8 +122,8 @@ node binary and node modules.
We create the standalone releases using the [npm package](#npm), and we
then create the remaining releases using the standalone version.
The only requirement to use the standalone release is `glibc` >= 2.17 and
`glibcxx` >= v3.4.18 on Linux (for macOS, there is no minimum system
The only requirement to use the standalone release is `glibc` >= 2.28 and
`glibcxx` >= v3.4.21 on Linux (for macOS, there is no minimum system
requirement).
To use a standalone release:
@@ -280,6 +279,7 @@ brew services start code-server
# outside the container.
mkdir -p ~/.config
docker run -it --name code-server -p 127.0.0.1:8080:8080 \
-v "$HOME/.local:/home/coder/.local" \
-v "$HOME/.config:/home/coder/.config" \
-v "$PWD:/home/coder/project" \
-u "$(id -u):$(id -g)" \

View File

@@ -30,7 +30,7 @@ includes installing instructions based on your operating system.
## Node.js version
We use the same major version of Node.js shipped with Code's remote, which is
currently `16.x`. VS Code also [lists Node.js
currently `20.x`. VS Code also [lists Node.js
requirements](https://github.com/microsoft/vscode/wiki/How-to-Contribute#prerequisites).
Using other versions of Node.js [may lead to unexpected
@@ -79,7 +79,7 @@ Proceed to [installing](#installing)
## FreeBSD
```sh
pkg install -y git python npm-node16 pkgconf
pkg install -y git python npm-node20 pkgconf
pkg install -y libinotify
```
@@ -92,12 +92,12 @@ Installing code-server requires all of the [prerequisites for VS Code developmen
Next, install code-server with:
```bash
npm install --global code-server --unsafe-perm
npm install --global code-server
code-server
# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml
```
A `postinstall.sh` script will attempt to run. Select your terminal (e.g., Git bash) as the default application for `.sh` files. If an additional dialog does not appear, run the install command again.
A `postinstall.sh` script will attempt to run. Select your terminal (e.g., Git bash) as the default shell for npm run-scripts. If an additional dialog does not appear, run the install command again.
If the `code-server` command is not found, you'll need to [add a directory to your PATH](https://www.architectryan.com/2018/03/17/add-to-the-path-on-windows-10/). To find the directory, use the following command:
@@ -112,7 +112,7 @@ For help and additional troubleshooting, see [#1397](https://github.com/coder/co
After adding the dependencies for your OS, install the code-server package globally:
```bash
npm install --global code-server --unsafe-perm
npm install --global code-server
code-server
# Now visit http://127.0.0.1:8080. Your password is in ~/.config/code-server/config.yaml
```
@@ -144,8 +144,8 @@ To debug installation issues, install with `npm`:
```shell
# Uninstall
npm uninstall --global --unsafe-perm code-server > /dev/null 2>&1
npm uninstall --global code-server > /dev/null 2>&1
# Install with logging
npm install --loglevel verbose --global --unsafe-perm code-server
npm install --loglevel verbose --global code-server
```

View File

@@ -22,7 +22,7 @@ The following steps walk you through setting up a VM running Debian using Google
Cloud (though you are welcome to use any machine or VM provider).
If you're [signing up with Google](https://console.cloud.google.com/getting-started) for the first time, you should get a 3-month trial with
$300 of credits.
\$300 of credits.
After you sign up and create a new Google Cloud Provider (GCP) project, create a
new Compute Engine VM instance:

View File

@@ -8,7 +8,9 @@
- [Upgrade](#upgrade)
- [Known Issues](#known-issues)
- [Git won't work in `/sdcard`](#git-wont-work-in-sdcard)
- [Many extensions including language packs fail to install](#many-extensions-including-language-packs-fail-to-install)
- [Extra](#extra)
- [Keyboard Shortcuts and Tab Key](#keyboard-shortcuts-and-tab-key)
- [Create a new user](#create-a-new-user)
- [Install Go](#install-go)
- [Install Python](#install-python)
@@ -55,7 +57,7 @@ npm config set python python3
node -v
```
you will get node version `v16.15.0`
you will get Node version `v20`
5. Now install code-server following our guide on [installing with npm](./npm.md)
@@ -68,7 +70,7 @@ code-server --auth none
7. If already installed then use the following command for upgradation.
```
npm update --global code-server --unsafe-perm
npm update --global code-server
```
## Upgrade
@@ -87,8 +89,50 @@ Potential Workaround :
1. Create a soft-link from the debian-fs to your folder in `/sdcard`
2. Use git from termux (preferred)
### Many extensions including language packs fail to install
Issue: Android is not seen as a Linux environment but as a separate, unsupported platform, so code-server only allows [Web Extensions](https://code.visualstudio.com/api/extension-guides/web-extensions), refusing to download extensions that run on the server.\
Fix: None\
Potential workarounds :
Either
- Manually download extensions as `.vsix` file and install them via `Extensions: Install from VSIX...` in the Command Palette.
- Use an override to pretend the platform is Linux:
Create a JS script that patches `process.platform`:
```js
// android-as-linux.js
Object.defineProperty(process, "platform", {
get() {
return "linux"
},
})
```
Then use Node's `--require` option to make sure it is loaded before `code-server` starts:
```sh
NODE_OPTIONS="--require /path/to/android-as-linux.js" code-server
```
⚠️ Note that Android and Linux are not 100% compatible, so use these workarounds at your own risk. Extensions that have native dependencies other than Node or that directly interact with the OS might cause issues.
## Extra
### Keyboard Shortcuts and Tab Key
In order to support the tab key and use keyboard shortcuts, add this to your
settings.json:
```json
{
"keyboard.dispatch": "keyCode"
}
```
### Create a new user
To create a new user follow these simple steps -

35
flake.lock generated
View File

@@ -1,12 +1,15 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1659877975,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
@@ -17,12 +20,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1660639432,
"narHash": "sha256-2WDiboOCfB0LhvnDVMXOAr8ZLDfm3WdO54CkoDPwN1A=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6c6409e965a6c883677be7b9d87a95fab6c3472e",
"type": "github"
"lastModified": 1716137900,
"narHash": "sha256-sowPU+tLQv8GlqtVtsXioTKeaQvlMz/pefcdwg8MvfM=",
"path": "/nix/store/r8nhgnkxacbnf4kv8kdi8b6ks3k9b16i-source",
"rev": "6c0b7a92c30122196a761b440ac0d46d3d9954f1",
"type": "path"
},
"original": {
"id": "nixpkgs",
@@ -34,6 +36,21 @@
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",

View File

@@ -7,16 +7,16 @@
flake-utils.lib.eachDefaultSystem
(system:
let pkgs = nixpkgs.legacyPackages.${system};
nodejs = pkgs.nodejs-16_x;
nodejs = pkgs.nodejs_20;
yarn' = pkgs.yarn.override { inherit nodejs; };
in {
devShells.default = pkgs.mkShell {
nativeBuildInputs = with pkgs; [
nodejs yarn' python 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 ]
buildInputs = with pkgs; (lib.optionals (!stdenv.isDarwin) [ libsecret libkrb5 ]
++ (with xorg; [ libX11 libxkbfile ])
++ lib.optionals stdenv.isDarwin (with pkgs.darwin.apple_sdk.frameworks; [
++ lib.optionals stdenv.isDarwin (with pkgs.darwin.apple_sdk.frameworks; [
AppKit Cocoa CoreServices Security xcbuild
]));
};

View File

@@ -46,7 +46,7 @@ Usage:
Sets the prefix used by standalone release archives. Defaults to ~/.local
The release is unarchived into ~/.local/lib/code-server-X.X.X
and the binary symlinked into ~/.local/bin/code-server
To install system wide pass ---prefix=/usr/local
To install system wide pass --prefix=/usr/local
--rsh <bin>
Specifies the remote shell for remote installation. Defaults to ssh.
@@ -441,7 +441,7 @@ install_npm() {
return
fi
echoerr "Please install npm to install code-server!"
echoerr "You will need at least node v12 and a few C dependencies."
echoerr "You will need at least node v20 and a few C dependencies."
echoerr "See the docs https://coder.com/docs/code-server/latest/install#npm"
exit 1

View File

@@ -38,77 +38,58 @@
},
"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",
"@types/node": "^16.0.0",
"@types/pem": "^1.9.5",
"@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": "20.x",
"@types/pem": "^1.14.1",
"@types/proxy-from-env": "^1.0.1",
"@types/safe-compare": "^1.1.0",
"@types/semver": "^7.1.0",
"@types/split2": "^3.2.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": "^4.6.2"
},
"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": "^16.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": "^7.0.0",
"@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.14.0",
"ts-node": "^10.9.1",
"typescript": "^5.2.2"
},
"dependencies": {
"@coder/logger": "^3.0.0",
"argon2": "0.30.3",
"@coder/logger": "^3.0.1",
"argon2": "^0.31.1",
"compression": "^1.7.4",
"cookie-parser": "^1.4.5",
"env-paths": "^2.2.0",
"express": "5.0.0-alpha.8",
"http-proxy": "^1.18.0",
"cookie-parser": "^1.4.6",
"env-paths": "^2.2.1",
"express": "5.0.0-beta.3",
"http-proxy": "^1.18.1",
"httpolyglot": "^0.1.2",
"i18next": "^22.4.6",
"js-yaml": "^4.0.0",
"i18next": "^23.5.1",
"js-yaml": "^4.1.0",
"limiter": "^2.1.0",
"pem": "^1.14.2",
"proxy-agent": "^5.0.0",
"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.12.1",
"rotating-file-stream": "^3.1.1",
"safe-buffer": "^5.2.1",
"safe-compare": "^1.1.4",
"semver": "^7.1.3",
"split2": "^4.0.0",
"ws": "^8.0.0",
"semver": "^7.5.4",
"ws": "^8.14.2",
"xdg-basedir": "^4.0.0"
},
"resolutions": {
"@types/node": "20.x"
},
"bin": {
"code-server": "out/node/entry.js"
},
@@ -122,7 +103,7 @@
"remote-development"
],
"engines": {
"node": "16"
"node": "20"
},
"jest": {
"transform": {

View File

@@ -10,7 +10,7 @@ Index: code-server/lib/vscode/src/vs/base/common/network.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/network.ts
+++ code-server/lib/vscode/src/vs/base/common/network.ts
@@ -166,7 +166,9 @@ class RemoteAuthoritiesImpl {
@@ -212,7 +212,9 @@ class RemoteAuthoritiesImpl {
return URI.from({
scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource,
authority: `${host}:${port}`,
@@ -99,26 +99,19 @@ Index: code-server/lib/vscode/src/vs/platform/remote/browser/browserSocketFactor
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/remote/browser/browserSocketFactory.ts
+++ code-server/lib/vscode/src/vs/platform/remote/browser/browserSocketFactory.ts
@@ -274,6 +274,7 @@ export class BrowserSocketFactory implem
connect(host: string, port: number, path: string, query: string, debugLabel: string, callback: IConnectCallback): void {
const webSocketSchema = (/^https:/.test(window.location.href) ? 'wss' : 'ws');
+ path = (window.location.pathname + "/" + path).replace(/\/\/+/g, "/")
const socket = this._webSocketFactory.create(`${webSocketSchema}://${(/:/.test(host) && !/\[/.test(host)) ? `[${host}]` : host}:${port}${path}?${query}&skipWebSocketFrames=false`, debugLabel);
const errorListener = socket.onError((err) => callback(err, undefined));
socket.onOpen(() => {
@@ -282,6 +283,3 @@ export class BrowserSocketFactory implem
});
}
}
-
-
-
@@ -281,6 +281,7 @@ export class BrowserSocketFactory implem
connect({ host, port }: WebSocketRemoteConnection, path: string, query: string, debugLabel: string): Promise<ISocket> {
return new Promise<ISocket>((resolve, reject) => {
const webSocketSchema = (/^https:/.test(mainWindow.location.href) ? 'wss' : 'ws');
+ path = (mainWindow.location.pathname + "/" + path).replace(/\/\/+/g, "/")
const socket = this._webSocketFactory.create(`${webSocketSchema}://${(/:/.test(host) && !/\[/.test(host)) ? `[${host}]` : host}:${port}${path}?${query}&skipWebSocketFrames=false`, debugLabel);
const errorListener = socket.onError(reject);
socket.onOpen(() => {
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -267,12 +267,11 @@ export class WebClientServer {
@@ -270,16 +270,15 @@ export class WebClientServer {
return void res.end();
}
@@ -127,33 +120,33 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
- return Array.isArray(val) ? val[0] : val;
- };
-
- const remoteAuthority = getFirstHeader('x-original-host') || getFirstHeader('x-forwarded-host') || req.headers.host;
const useTestResolver = (!this._environmentService.isBuilt && this._environmentService.args['use-test-resolver']);
+ // For now we are getting the remote authority from the client to avoid
+ // needing specific configuration for reverse proxies to work. Set this to
+ // something invalid to make sure we catch code that is using this value
+ // from the backend when it should not.
+ const remoteAuthority = 'remote';
const remoteAuthority = (
useTestResolver
? 'test+test'
- : (getFirstHeader('x-original-host') || getFirstHeader('x-forwarded-host') || req.headers.host)
+ : 'remote'
);
if (!remoteAuthority) {
return serveError(req, res, 400, `Bad request.`);
}
@@ -298,6 +297,8 @@ export class WebClientServer {
@@ -306,8 +305,12 @@ export class WebClientServer {
scopes: [['user:email'], ['repo']]
} : undefined;
+ const base = relativeRoot(getOriginalUrl(req))
+ const vscodeBase = relativePath(getOriginalUrl(req))
const workbenchWebConfiguration = {
remoteAuthority,
@@ -309,6 +310,7 @@ export class WebClientServer {
workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']),
productConfiguration: <Partial<IProductConfiguration>>{
codeServerVersion: this._productService.codeServerVersion,
+ rootEndpoint: base,
embedderIdentifier: 'server-distro',
extensionsGallery: this._webExtensionResourceUrlTemplate ? {
...this._productService.extensionsGallery,
@@ -326,8 +328,10 @@ export class WebClientServer {
+
const productConfiguration = {
codeServerVersion: this._productService.codeServerVersion,
+ rootEndpoint: base,
embedderIdentifier: 'server-distro',
extensionsGallery: this._webExtensionResourceUrlTemplate && this._productService.extensionsGallery ? {
...this._productService.extensionsGallery,
@@ -343,8 +346,10 @@ export class WebClientServer {
const values: { [key: string]: string } = {
WORKBENCH_WEB_CONFIGURATION: asJSON(workbenchWebConfiguration),
WORKBENCH_AUTH_SESSION: authSessionInfo ? asJSON(authSessionInfo) : '',
@@ -165,17 +158,17 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
+ VS_BASE: vscodeBase,
};
@@ -344,7 +348,7 @@ export class WebClientServer {
if (useTestResolver) {
@@ -371,7 +376,7 @@ export class WebClientServer {
'default-src \'self\';',
'img-src \'self\' https: data: blob:;',
'media-src \'self\';',
- `script-src 'self' 'unsafe-eval' ${this._getScriptCspHashes(data).join(' ')} 'sha256-fh3TwPMflhsEIpR8g1OYTIMVWhXTLcjQ9kh2tIpmv54=' http://${remoteAuthority};`, // the sha is the same as in src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
+ `script-src 'self' 'unsafe-eval' ${this._getScriptCspHashes(data).join(' ')} 'sha256-fh3TwPMflhsEIpR8g1OYTIMVWhXTLcjQ9kh2tIpmv54=';`, // the sha is the same as in src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
- `script-src 'self' 'unsafe-eval' ${this._getScriptCspHashes(data).join(' ')} '${webWorkerExtensionHostIframeScriptSHA}' ${useTestResolver ? '' : `http://${remoteAuthority}`};`, // the sha is the same as in src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
+ `script-src 'self' 'unsafe-eval' ${this._getScriptCspHashes(data).join(' ')} '${webWorkerExtensionHostIframeScriptSHA}' ${useTestResolver ? '' : ''};`, // the sha is the same as in src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
'child-src \'self\';',
`frame-src 'self' https://*.vscode-cdn.net data:;`,
'worker-src \'self\' data:;',
@@ -417,3 +421,70 @@ export class WebClientServer {
'worker-src \'self\' data: blob:;',
@@ -444,3 +449,70 @@ export class WebClientServer {
return void res.end(data);
}
}
@@ -250,7 +243,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/lib/vscode/src/vs/base/common/product.ts
@@ -32,6 +32,7 @@ export type ExtensionVirtualWorkspaceSup
@@ -56,6 +56,7 @@ export type ExtensionVirtualWorkspaceSup
export interface IProductConfiguration {
readonly codeServerVersion?: string
@@ -262,23 +255,45 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.ts
+++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
@@ -489,6 +489,7 @@ function doCreateUri(path: string, query
});
@@ -304,7 +304,8 @@ class LocalStorageURLCallbackProvider ex
this.startListening();
}
- return URI.parse(mainWindow.location.href).with({ path: this._callbackRoute, query: queryParams.join('&') });
+ const path = (mainWindow.location.pathname + "/" + this._callbackRoute).replace(/\/\/+/g, "/");
+ return URI.parse(mainWindow.location.href).with({ path: path, query: queryParams.join('&') });
}
+ path = (window.location.pathname + "/" + path).replace(/\/\/+/g, "/")
return URI.parse(window.location.href).with({ path, query });
private startListening(): void {
@@ -550,17 +551,6 @@ class WorkspaceProvider implements IWork
}
}
@@ -500,7 +501,7 @@ function doCreateUri(path: string, query
-function readCookie(name: string): string | undefined {
- const cookies = document.cookie.split('; ');
- for (const cookie of cookies) {
- if (cookie.startsWith(name + '=')) {
- return cookie.substring(name.length + 1);
- }
- }
-
- return undefined;
-}
-
(function () {
// Find config by checking for DOM
@@ -569,8 +559,8 @@ function readCookie(name: string): strin
if (!configElement || !configElementAttribute) {
throw new Error('Missing web configuration element');
}
- const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents; workspaceUri?: UriComponents; callbackRoute: string } = JSON.parse(configElementAttribute);
- const secretStorageKeyPath = readCookie('vscode-secret-key-path');
+ const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents; workspaceUri?: UriComponents; callbackRoute: string } = { ...JSON.parse(configElementAttribute), remoteAuthority: location.host }
+ const secretStorageKeyPath = (window.location.pathname + "/mint-key").replace(/\/\/+/g, "/");
const secretStorageCrypto = secretStorageKeyPath && ServerKeyedAESCrypto.supported()
? new ServerKeyedAESCrypto(secretStorageKeyPath) : new TransparentCrypto();
// Create workbench
create(document.body, {
Index: code-server/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts
@@ -288,13 +303,13 @@ Index: code-server/lib/vscode/src/vs/platform/extensionResourceLoader/common/ext
import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { getTelemetryLevel, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
-import { RemoteAuthorities } from 'vs/base/common/network';
import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts';
import { TargetPlatform } from 'vs/platform/extensions/common/extensions';
export const WEB_EXTENSION_RESOURCE_END_POINT = 'web-extension-resource';
@@ -75,7 +74,7 @@ export abstract class AbstractExtensionR
public getExtensionGalleryResourceURL(galleryExtension: { publisher: string; name: string; version: string }, path?: string): URI | undefined {
if (this._extensionGalleryResourceUrlTemplate) {
const uri = URI.parse(format2(this._extensionGalleryResourceUrlTemplate, { publisher: galleryExtension.publisher, name: galleryExtension.name, version: galleryExtension.version, path: 'extension' }));
const WEB_EXTENSION_RESOURCE_END_POINT_SEGMENT = '/web-extension-resource/';
@@ -99,7 +98,7 @@ export abstract class AbstractExtensionR
: version,
path: 'extension'
}));
- return this._isWebExtensionResourceEndPoint(uri) ? uri.with({ scheme: RemoteAuthorities.getPreferredWebSchema() }) : uri;
+ return this._isWebExtensionResourceEndPoint(uri) ? URI.joinPath(URI.parse(window.location.href), uri.path) : uri;
}

View File

@@ -17,7 +17,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTe
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
@@ -100,10 +100,14 @@ class RemoteTerminalBackend extends Base
@@ -106,10 +106,14 @@ class RemoteTerminalBackend extends Base
}
const reqId = e.reqId;
const commandId = e.commandId;

136
patches/clipboard.diff Normal file
View File

@@ -0,0 +1,136 @@
Index: code-server/lib/vscode/src/vs/workbench/api/browser/mainThreadCLICommands.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/api/browser/mainThreadCLICommands.ts
+++ code-server/lib/vscode/src/vs/workbench/api/browser/mainThreadCLICommands.ts
@@ -8,6 +8,7 @@ import { isWeb } from 'vs/base/common/pl
import { isString } from 'vs/base/common/types';
import { URI, UriComponents } from 'vs/base/common/uri';
import { localize } from 'vs/nls';
+import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
import { IExtensionGalleryService, IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionManagementCLI } from 'vs/platform/extensionManagement/common/extensionManagementCLI';
@@ -89,6 +90,11 @@ CommandsRegistry.registerCommand('_remot
return lines.join('\n');
});
+CommandsRegistry.registerCommand('_remoteCLI.setClipboard', function (accessor: ServicesAccessor, content: string) {
+ const clipboardService = accessor.get(IClipboardService);
+ clipboardService.writeText(content);
+})
+
class RemoteExtensionManagementCLI extends ExtensionManagementCLI {
private _location: string | undefined;
Index: code-server/lib/vscode/src/vs/workbench/api/node/extHostCLIServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/api/node/extHostCLIServer.ts
+++ code-server/lib/vscode/src/vs/workbench/api/node/extHostCLIServer.ts
@@ -43,7 +43,12 @@ export interface ExtensionManagementPipe
force?: boolean;
}
-export type PipeCommand = OpenCommandPipeArgs | StatusPipeArgs | OpenExternalCommandPipeArgs | ExtensionManagementPipeArgs;
+export interface ClipboardPipeArgs {
+ type: 'clipboard';
+ content: string;
+}
+
+export type PipeCommand = OpenCommandPipeArgs | StatusPipeArgs | OpenExternalCommandPipeArgs | ExtensionManagementPipeArgs | ClipboardPipeArgs;
export interface ICommandsExecuter {
executeCommand<T>(id: string, ...args: any[]): Promise<T>;
@@ -105,6 +110,9 @@ export class CLIServerBase {
case 'extensionManagement':
returnObj = await this.manageExtensions(data);
break;
+ case 'clipboard':
+ returnObj = await this.clipboard(data);
+ break;
default:
sendResponse(404, `Unknown message type: ${data.type}`);
break;
@@ -172,6 +180,10 @@ export class CLIServerBase {
return await this._commands.executeCommand<string | undefined>('_remoteCLI.getSystemStatus');
}
+ private async clipboard(data: ClipboardPipeArgs): Promise<undefined> {
+ return await this._commands.executeCommand('_remoteCLI.setClipboard', data.content);
+ }
+
dispose(): void {
this._server.close();
Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/browser/remoteTerminalBackend.ts
@@ -97,7 +97,7 @@ class RemoteTerminalBackend extends Base
}
});
- const allowedCommands = ['_remoteCLI.openExternal', '_remoteCLI.windowOpen', '_remoteCLI.getSystemStatus', '_remoteCLI.manageExtensions'];
+ const allowedCommands = ['_remoteCLI.openExternal', '_remoteCLI.windowOpen', '_remoteCLI.getSystemStatus', '_remoteCLI.manageExtensions', '_remoteCLI.setClipboard'];
this._remoteTerminalChannel.onExecuteCommand(async e => {
// Ensure this request for for this window
const pty = this._ptys.get(e.persistentProcessId);
Index: code-server/lib/vscode/src/vs/platform/environment/common/argv.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/environment/common/argv.ts
+++ code-server/lib/vscode/src/vs/platform/environment/common/argv.ts
@@ -119,6 +119,7 @@ export interface NativeParsedArgs {
sandbox?: boolean;
'enable-coi'?: boolean;
+ 'stdin-to-clipboard'?: boolean;
// chromium command line args: https://electronjs.org/docs/all#supported-chrome-command-line-switches
'no-proxy-server'?: boolean;
Index: code-server/lib/vscode/src/vs/platform/environment/node/argv.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/environment/node/argv.ts
+++ code-server/lib/vscode/src/vs/platform/environment/node/argv.ts
@@ -90,6 +90,7 @@ export const OPTIONS: OptionDescriptions
'user-data-dir': { type: 'string', cat: 'o', args: 'dir', description: localize('userDataDir', "Specifies the directory that user data is kept in. Can be used to open multiple distinct instances of Code.") },
'profile': { type: 'string', 'cat': 'o', args: 'profileName', description: localize('profileName', "Opens the provided folder or workspace with the given profile and associates the profile with the workspace. If the profile does not exist, a new empty one is created.") },
'help': { type: 'boolean', cat: 'o', alias: 'h', description: localize('help', "Print usage.") },
+ 'stdin-to-clipboard': { type: 'boolean', cat: 'o', alias: 'c', description: localize('clipboard', "copies the STDIN to the clipboard") },
'extensions-dir': { type: 'string', deprecates: ['extensionHomePath'], cat: 'e', args: 'dir', description: localize('extensionHomePath', "Set the root path for extensions.") },
'extensions-download-dir': { type: 'string' },
Index: code-server/lib/vscode/src/vs/server/node/server.cli.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/server.cli.ts
+++ code-server/lib/vscode/src/vs/server/node/server.cli.ts
@@ -76,6 +76,7 @@ const isSupportedForPipe = (optionId: ke
case 'verbose':
case 'remote':
case 'locate-shell-integration-path':
+ case 'stdin-to-clipboard':
return true;
default:
return false;
@@ -293,6 +294,23 @@ export async function main(desc: Product
}
}
} else {
+ if (parsedArgs['stdin-to-clipboard']) {
+ if(!hasStdinWithoutTty()) {
+ console.error("stdin has a tty.");
+ return;
+ }
+ const fs = require("fs");
+ const stdinBuffer = fs.readFileSync(0); // STDIN_FILENO = 0
+ const clipboardContent = stdinBuffer.toString();
+ sendToPipe({
+ type: 'clipboard',
+ content: clipboardContent
+ }, verbose).catch(e => {
+ console.error('Error when requesting status:', e);
+ });
+ return;
+ }
+
if (parsedArgs.status) {
sendToPipe({
type: 'status'

View File

@@ -7,7 +7,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts
@@ -243,6 +243,10 @@ export class Extension implements IExten
@@ -285,6 +285,10 @@ export class Extension implements IExten
if (this.type === ExtensionType.System && this.productService.quality === 'stable') {
return false;
}

View File

@@ -1,183 +0,0 @@
Add option to disable file downloads via CLI
This patch adds support for a new CLI flag called `--disable-file-downloads`
which allows a user to remove the "Download..." option that shows up when you
right-click files in Code. The default value for this is `false`.
To test this, start code-server with `--disable-file-downloads`, open editor,
right-click on a file (not a folder) and you should **not** see the
"Download..." option.
Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
@@ -266,6 +266,11 @@ export interface IWorkbenchConstructionO
*/
readonly userDataPath?: string
+ /**
+ * Whether the "Download..." option is enabled for files.
+ */
+ readonly isEnabledFileDownloads?: boolean
+
//#endregion
//#region Profile options
Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -32,6 +32,11 @@ export interface IBrowserWorkbenchEnviro
* Options used to configure the workbench.
*/
readonly options?: IWorkbenchConstructionOptions;
+
+ /**
+ * Enable downloading files via menu actions.
+ */
+ readonly isEnabledFileDownloads?: boolean;
}
export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvironmentService {
@@ -104,6 +109,13 @@ export class BrowserWorkbenchEnvironment
return this.options.userDataPath;
}
+ get isEnabledFileDownloads(): boolean {
+ if (typeof this.options.isEnabledFileDownloads === "undefined") {
+ throw new Error('isEnabledFileDownloads was not provided to the browser');
+ }
+ return this.options.isEnabledFileDownloads;
+ }
+
@memoize
get argvResource(): URI { return joinPath(this.userRoamingDataHome, 'argv.json'); }
Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
@@ -14,6 +14,7 @@ export const serverOptions: OptionDescri
/* ----- code-server ----- */
'disable-update-check': { type: 'boolean' },
'auth': { type: 'string' },
+ 'disable-file-downloads': { type: 'boolean' },
/* ----- server setup ----- */
@@ -94,6 +95,7 @@ export interface ServerParsedArgs {
/* ----- code-server ----- */
'disable-update-check'?: boolean;
'auth'?: string
+ 'disable-file-downloads'?: boolean;
/* ----- server setup ----- */
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -304,6 +304,7 @@ export class WebClientServer {
remoteAuthority,
webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
userDataPath: this._environmentService.userDataPath,
+ isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'],
_wrapWebWorkerExtHostInIframe,
developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, logLevel: this._logService.getLevel() },
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
@@ -7,12 +7,11 @@ import { Event } from 'vs/base/common/ev
import { Disposable } from 'vs/base/common/lifecycle';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from 'vs/platform/contextkey/common/contextkeys';
-import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext } from 'vs/workbench/common/contextkeys';
+import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, IsEnabledFileDownloads } from 'vs/workbench/common/contextkeys';
import { TEXT_DIFF_EDITOR_ID, EditorInputCapabilities, SIDE_BY_SIDE_EDITOR_ID, DEFAULT_EDITOR_ASSOCIATION } from 'vs/workbench/common/editor';
import { trackFocus, addDisposableListener, EventType } from 'vs/base/browser/dom';
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
-import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { WorkbenchState, IWorkspaceContextService, isTemporaryWorkspace } from 'vs/platform/workspace/common/workspace';
import { IWorkbenchLayoutService, Parts, positionToString } from 'vs/workbench/services/layout/browser/layoutService';
@@ -25,6 +24,7 @@ import { IPaneCompositePartService } fro
import { Schemas } from 'vs/base/common/network';
import { WebFileSystemAccess } from 'vs/platform/files/browser/webFileSystemAccess';
import { IProductService } from 'vs/platform/product/common/productService';
+import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
export class WorkbenchContextKeysHandler extends Disposable {
private inputFocusedContext: IContextKey<boolean>;
@@ -77,7 +77,7 @@ export class WorkbenchContextKeysHandler
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IConfigurationService private readonly configurationService: IConfigurationService,
- @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
+ @IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService,
@IProductService private readonly productService: IProductService,
@IEditorService private readonly editorService: IEditorService,
@IEditorResolverService private readonly editorResolverService: IEditorResolverService,
@@ -202,6 +202,9 @@ export class WorkbenchContextKeysHandler
this.auxiliaryBarVisibleContext = AuxiliaryBarVisibleContext.bindTo(this.contextKeyService);
this.auxiliaryBarVisibleContext.set(this.layoutService.isVisible(Parts.AUXILIARYBAR_PART));
+ // code-server
+ IsEnabledFileDownloads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileDownloads ?? true)
+
this.registerListeners();
}
Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts
@@ -20,7 +20,7 @@ import { CLOSE_SAVED_EDITORS_COMMAND_ID,
import { AutoSaveAfterShortDelayContext } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { WorkbenchListDoubleSelection } from 'vs/platform/list/browser/listService';
import { Schemas } from 'vs/base/common/network';
-import { DirtyWorkingCopiesContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, ActiveEditorAvailableEditorIdsContext } from 'vs/workbench/common/contextkeys';
+import { DirtyWorkingCopiesContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, ActiveEditorAvailableEditorIdsContext, IsEnabledFileDownloads } from 'vs/workbench/common/contextkeys';
import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { ThemeIcon } from 'vs/base/common/themables';
@@ -484,13 +484,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo
id: DOWNLOAD_COMMAND_ID,
title: DOWNLOAD_LABEL
},
- when: ContextKeyExpr.or(
- // native: for any remote resource
- ContextKeyExpr.and(IsWebContext.toNegated(), ResourceContextKey.Scheme.notEqualsTo(Schemas.file)),
- // web: for any files
- ContextKeyExpr.and(IsWebContext, ExplorerFolderContext.toNegated(), ExplorerRootContext.toNegated()),
- // web: for any folders if file system API support is provided
- ContextKeyExpr.and(IsWebContext, HasWebFileSystemAccess)
+ when: ContextKeyExpr.and(
+ IsEnabledFileDownloads,
+ ContextKeyExpr.or(
+ // native: for any remote resource
+ ContextKeyExpr.and(IsWebContext.toNegated(), ResourceContextKey.Scheme.notEqualsTo(Schemas.file)),
+ // web: for any files
+ ContextKeyExpr.and(IsWebContext, ExplorerFolderContext.toNegated(), ExplorerRootContext.toNegated()),
+ // web: for any folders if file system API support is provided
+ ContextKeyExpr.and(IsWebContext, HasWebFileSystemAccess)
+ )
)
}));
Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
@@ -32,6 +32,8 @@ export const IsFullscreenContext = new R
export const HasWebFileSystemAccess = new RawContextKey<boolean>('hasWebFileSystemAccess', false, true); // Support for FileSystemAccess web APIs (https://wicg.github.io/file-system-access)
+export const IsEnabledFileDownloads = new RawContextKey<boolean>('isEnabledFileDownloads', true, true);
+
//#endregion

View File

@@ -14,20 +14,31 @@ We can remove this once upstream supports all language packs.
one but is worse because it does not handle non-existent or empty files.
7. Replace some caching and Node requires because code-server does not restart
when changing the language unlike native Code.
8. Make language extensions installable like normal rather than using the
special set/clear language actions.
Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/serverServices.ts
+++ code-server/lib/vscode/src/vs/server/node/serverServices.ts
@@ -220,6 +220,9 @@ export async function setupServerService
@@ -11,7 +11,7 @@ import * as path from 'vs/base/common/pa
import { IURITransformer } from 'vs/base/common/uriIpc';
import { getMachineId, getSqmMachineId, getdevDeviceId } from 'vs/base/node/id';
import { Promises } from 'vs/base/node/pfs';
-import { ClientConnectionEvent, IMessagePassingProtocol, IPCServer, StaticRouter } from 'vs/base/parts/ipc/common/ipc';
+import { ClientConnectionEvent, IMessagePassingProtocol, IPCServer, ProxyChannel, StaticRouter } from 'vs/base/parts/ipc/common/ipc';
import { ProtocolConstants } from 'vs/base/parts/ipc/common/ipc.net';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ConfigurationService } from 'vs/platform/configuration/common/configurationService';
@@ -238,6 +238,9 @@ export async function setupServerService
const channel = new ExtensionManagementChannel(extensionManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority));
socketServer.registerChannel('extensions', channel);
+ const languagePackChannel = ProxyChannel.fromService<RemoteAgentConnectionContext>(accessor.get(ILanguagePackService));
+ const languagePackChannel = ProxyChannel.fromService<RemoteAgentConnectionContext>(accessor.get(ILanguagePackService), disposables);
+ socketServer.registerChannel('languagePacks', languagePackChannel);
+
const encryptionChannel = ProxyChannel.fromService<RemoteAgentConnectionContext>(accessor.get(IEncryptionMainService));
socketServer.registerChannel('encryption', encryptionChannel);
// clean up extensions folder
remoteExtensionsScanner.whenExtensionsReady().then(() => extensionManagementService.cleanUp());
Index: code-server/lib/vscode/src/vs/base/common/platform.ts
===================================================================
@@ -42,7 +53,7 @@ Index: code-server/lib/vscode/src/vs/base/common/platform.ts
export const LANGUAGE_DEFAULT = 'en';
let _isWindows = false;
@@ -86,17 +84,19 @@ if (typeof navigator === 'object' && !is
@@ -112,17 +110,21 @@ else if (typeof navigator === 'object' &
_isMobile = _userAgent?.indexOf('Mobi') >= 0;
_isWeb = true;
@@ -56,21 +67,23 @@ Index: code-server/lib/vscode/src/vs/base/common/platform.ts
-
- _locale = configuredLocale || LANGUAGE_DEFAULT;
+ _locale = LANGUAGE_DEFAULT;
_language = _locale;
_platformLocale = navigator.language;
+ const el = typeof document !== 'undefined' && document.getElementById('vscode-remote-nls-configuration');
+ const rawNlsConfig = el && el.getAttribute('data-settings');
+ if (rawNlsConfig) {
+ try {
+ const nlsConfig: NLSConfig = JSON.parse(rawNlsConfig);
+ const resolved = nlsConfig.availableLanguages['*'];
+ _locale = nlsConfig.locale;
+ _platformLocale = nlsConfig.osLocale;
+ _language = resolved ? resolved : LANGUAGE_DEFAULT;
+ _translationsConfigFile = nlsConfig._translationsConfigFile;
+ _language = nlsConfig.availableLanguages['*'] || LANGUAGE_DEFAULT;
+ } catch (error) { /* Oh well. */ }
+ }
}
// Native environment
// Unknown environment
Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html
===================================================================
--- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.html
@@ -85,10 +98,10 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html
<!-- Workbench Icon/Manifest/CSS -->
<link rel="icon" href="{{BASE}}/_static/src/browser/media/favicon-dark-support.svg" />
<link rel="alternate icon" href="{{BASE}}/_static/src/browser/media/favicon.ico" type="image/x-icon" />
@@ -46,15 +49,26 @@
// Set up nls if the user is not using the default language (English)
const nlsConfig = {};
const locale = window.localStorage.getItem('vscode.nls.locale') || navigator.language;
@@ -48,15 +51,27 @@
// Normalize locale to lowercase because translationServiceUrl is case-sensitive.
// ref: https://github.com/microsoft/vscode/issues/187795
const locale = localStorage.getItem('vscode.nls.locale') || navigator.language.toLowerCase();
- if (!locale.startsWith('en')) {
- nlsConfig['vs/nls'] = {
- availableLanguages: {
@@ -97,7 +110,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html
- translationServiceUrl: '{{WORKBENCH_NLS_BASE_URL}}'
- };
- }
-
+ try {
+ nlsConfig['vs/nls'] = JSON.parse(document.getElementById("vscode-remote-nls-configuration").getAttribute("data-settings"))
+ if (nlsConfig['vs/nls']._resolvedLanguagePackCoreLocation) {
@@ -125,7 +138,7 @@ Index: code-server/lib/vscode/src/vs/platform/environment/common/environmentServ
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/environment/common/environmentService.ts
+++ code-server/lib/vscode/src/vs/platform/environment/common/environmentService.ts
@@ -107,7 +107,7 @@ export abstract class AbstractNativeEnvi
@@ -101,7 +101,7 @@ export abstract class AbstractNativeEnvi
return URI.file(join(vscodePortable, 'argv.json'));
}
@@ -138,7 +151,7 @@ Index: code-server/lib/vscode/src/vs/server/node/remoteLanguagePacks.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/remoteLanguagePacks.ts
+++ code-server/lib/vscode/src/vs/server/node/remoteLanguagePacks.ts
@@ -30,6 +30,12 @@ export function getNLSConfiguration(lang
@@ -32,6 +32,12 @@ export function getNLSConfiguration(lang
if (InternalNLSConfiguration.is(value)) {
value._languagePackSupport = true;
}
@@ -151,7 +164,7 @@ Index: code-server/lib/vscode/src/vs/server/node/remoteLanguagePacks.ts
return value;
});
_cache.set(key, result);
@@ -44,3 +50,43 @@ export namespace InternalNLSConfiguratio
@@ -46,3 +52,43 @@ export namespace InternalNLSConfiguratio
return candidate && typeof candidate._languagePackId === 'string';
}
}
@@ -199,47 +212,47 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -26,6 +26,7 @@ import { URI } from 'vs/base/common/uri'
@@ -27,6 +27,7 @@ import { URI } from 'vs/base/common/uri'
import { streamToBuffer } from 'vs/base/common/buffer';
import { IProductConfiguration } from 'vs/base/common/product';
import { isString } from 'vs/base/common/types';
+import { getLocaleFromConfig, getNLSConfiguration } from 'vs/server/node/remoteLanguagePacks';
import { CharCode } from 'vs/base/common/charCode';
import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts';
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
@@ -299,6 +300,8 @@ export class WebClientServer {
@@ -348,6 +349,8 @@ export class WebClientServer {
callbackRoute: this._callbackRoute
};
const base = relativeRoot(getOriginalUrl(req))
const vscodeBase = relativePath(getOriginalUrl(req))
+ const locale = this._environmentService.args.locale || await getLocaleFromConfig(this._environmentService.argvResource.fsPath);
+ const nlsConfiguration = await getNLSConfiguration(locale, this._environmentService.userDataPath)
const workbenchWebConfiguration = {
remoteAuthority,
@@ -336,6 +339,7 @@ export class WebClientServer {
const nlsBaseUrl = this._productService.extensionsGallery?.nlsBaseUrl;
const values: { [key: string]: string } = {
WORKBENCH_WEB_CONFIGURATION: asJSON(workbenchWebConfiguration),
@@ -356,6 +359,7 @@ export class WebClientServer {
WORKBENCH_NLS_BASE_URL: vscodeBase + (nlsBaseUrl ? `${nlsBaseUrl}${!nlsBaseUrl.endsWith('/') ? '/' : ''}${this._productService.commit}/${this._productService.version}/` : ''),
BASE: base,
VS_BASE: vscodeBase,
+ NLS_CONFIGURATION: asJSON(nlsConfiguration),
};
if (useTestResolver) {
Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
@@ -15,6 +15,7 @@ export const serverOptions: OptionDescri
'disable-update-check': { type: 'boolean' },
@@ -18,6 +18,7 @@ export const serverOptions: OptionDescri
'auth': { type: 'string' },
'disable-file-downloads': { type: 'boolean' },
'disable-file-uploads': { type: 'boolean' },
+ 'locale': { type: 'string' },
/* ----- server setup ----- */
@@ -96,6 +97,7 @@ export interface ServerParsedArgs {
'disable-update-check'?: boolean;
'auth'?: string
@@ -103,6 +104,7 @@ export interface ServerParsedArgs {
'auth'?: string;
'disable-file-downloads'?: boolean;
'disable-file-uploads'?: boolean;
+ 'locale'?: string
/* ----- server setup ----- */
@@ -248,9 +261,18 @@ Index: code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/workbench.web.main.ts
+++ code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts
@@ -119,8 +119,9 @@ import 'vs/workbench/contrib/logs/browse
// Explorer
import 'vs/workbench/contrib/files/browser/files.web.contribution';
@@ -52,7 +52,7 @@ import 'vs/workbench/services/dialogs/br
import 'vs/workbench/services/host/browser/browserHostService';
import 'vs/workbench/services/lifecycle/browser/lifecycleService';
import 'vs/workbench/services/clipboard/browser/clipboardService';
-import 'vs/workbench/services/localization/browser/localeService';
+import 'vs/workbench/services/localization/electron-sandbox/localeService';
import 'vs/workbench/services/path/browser/pathService';
import 'vs/workbench/services/themes/browser/browserHostColorSchemeService';
import 'vs/workbench/services/encryption/browser/encryptionService';
@@ -118,8 +118,9 @@ registerSingleton(ILanguagePackService,
// Logs
import 'vs/workbench/contrib/logs/browser/logs.contribution';
-// Localization
-import 'vs/workbench/contrib/localization/browser/localization.contribution';
@@ -264,9 +286,9 @@ Index: code-server/lib/vscode/src/vs/platform/languagePacks/browser/languagePack
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/languagePacks/browser/languagePacks.ts
+++ code-server/lib/vscode/src/vs/platform/languagePacks/browser/languagePacks.ts
@@ -6,18 +6,24 @@
@@ -5,18 +5,24 @@
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { Language } from 'vs/base/common/platform';
import { URI } from 'vs/base/common/uri';
+import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc';
import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
@@ -289,8 +311,8 @@ Index: code-server/lib/vscode/src/vs/platform/languagePacks/browser/languagePack
+ this.languagePackService = ProxyChannel.toService<ILanguagePackService>(remoteAgentService.getConnection()!.getChannel('languagePacks'))
}
async getBuiltInExtensionTranslationsUri(id: string): Promise<URI | undefined> {
@@ -73,6 +79,6 @@ export class WebLanguagePacksService ext
async getBuiltInExtensionTranslationsUri(id: string, language: string): Promise<URI | undefined> {
@@ -72,6 +78,6 @@ export class WebLanguagePacksService ext
// Web doesn't have a concept of language packs, so we just return an empty array
getInstalledLanguages(): Promise<ILanguagePackItem[]> {
@@ -298,11 +320,11 @@ Index: code-server/lib/vscode/src/vs/platform/languagePacks/browser/languagePack
+ return this.languagePackService.getInstalledLanguages()
}
}
Index: code-server/lib/vscode/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts
Index: code-server/lib/vscode/src/vs/workbench/services/localization/electron-sandbox/localeService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/localization/electron-sandbox/localeService.ts
@@ -41,7 +41,8 @@ export class NativeLocaleService impleme
--- code-server.orig/lib/vscode/src/vs/workbench/services/localization/electron-sandbox/localeService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/localization/electron-sandbox/localeService.ts
@@ -51,7 +51,8 @@ class NativeLocaleService implements ILo
@IProductService private readonly productService: IProductService
) { }
@@ -312,7 +334,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/localization/electron-san
try {
const content = await this.textFileService.read(this.environmentService.argvResource, { encoding: 'utf8' });
@@ -68,9 +69,6 @@ export class NativeLocaleService impleme
@@ -78,9 +79,6 @@ class NativeLocaleService implements ILo
}
private async writeLocaleValue(locale: string | undefined): Promise<boolean> {
@@ -322,3 +344,70 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/localization/electron-san
await this.jsonEditingService.write(this.environmentService.argvResource, [{ path: ['locale'], value: locale }], true);
return true;
}
Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts
@@ -341,9 +341,6 @@ export class InstallAction extends Exten
if (this.extension.isBuiltin) {
return;
}
- if (this.extensionsWorkbenchService.canSetLanguage(this.extension)) {
- return;
- }
if (this.extension.state === ExtensionState.Uninstalled && await this.extensionsWorkbenchService.canInstall(this.extension)) {
this.enabled = this.options.installPreReleaseVersion ? this.extension.hasPreReleaseVersion : this.extension.hasReleaseVersion;
this.updateLabel();
@@ -614,7 +611,7 @@ export abstract class InstallInOtherServ
}
if (isLanguagePackExtension(this.extension.local.manifest)) {
- return true;
+ return false;
}
// Prefers to run on UI
@@ -1848,17 +1845,6 @@ export class SetLanguageAction extends E
update(): void {
this.enabled = false;
this.class = SetLanguageAction.DisabledClass;
- if (!this.extension) {
- return;
- }
- if (!this.extensionsWorkbenchService.canSetLanguage(this.extension)) {
- return;
- }
- if (this.extension.gallery && language === getLocale(this.extension.gallery)) {
- return;
- }
- this.enabled = true;
- this.class = SetLanguageAction.EnabledClass;
}
override async run(): Promise<any> {
@@ -1875,7 +1861,6 @@ export class ClearLanguageAction extends
private static readonly DisabledClass = `${ClearLanguageAction.EnabledClass} disabled`;
constructor(
- @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
@ILocaleService private readonly localeService: ILocaleService,
) {
super(ClearLanguageAction.ID, ClearLanguageAction.TITLE.value, ClearLanguageAction.DisabledClass, false);
@@ -1885,17 +1870,6 @@ export class ClearLanguageAction extends
update(): void {
this.enabled = false;
this.class = ClearLanguageAction.DisabledClass;
- if (!this.extension) {
- return;
- }
- if (!this.extensionsWorkbenchService.canSetLanguage(this.extension)) {
- return;
- }
- if (this.extension.gallery && language !== getLocale(this.extension.gallery)) {
- return;
- }
- this.enabled = true;
- this.class = ClearLanguageAction.EnabledClass;
}
override async run(): Promise<any> {

View File

@@ -0,0 +1,357 @@
Add option to disable file downloads and uploads via cli
This patch adds support for a new CLI flag called `--disable-file-downloads`
which allows a user to remove the "Download..." option that shows up when you
right-click files in Code. It also disables the "Show Local" button on the dialog
for Save, Save-As and Save Workspace. The default value for this is `false`.
This patch also add support for a new CLI flag called `--disable-file-uploads`
which disables the drag to upload functionality and the "Upload..." option when you
right-click folders in Code. It also disables the "Show Local" button on the dialog
for opening a file. The default value for this is `false`.
This patch also adds trace log statements for when a file is read and written to disk.
To test disabling downloads, start code-server with `--disable-file-downloads`, open editor,
right-click on a file (not a folder) and you should **not** see the
"Download..." option. When saving a file or workspace, the "Show Local" button
should **not** appear on the dialog that comes on screen.
To test disabling uploads, start code-server with `--disable-file-uploads`, open editor,
right-click on a folder (not a file) and you should **not** see the
"Upload..." option. If you drag a file into the file navigator, the file should **not** upload
and appear in the file navigator. When opening a file, the "Show Local" button
should **not** appear on the dialog that comes on screen.
Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
@@ -303,6 +303,16 @@ export interface IWorkbenchConstructionO
*/
readonly userDataPath?: string
+ /**
+ * Whether the "Download..." option is enabled for files.
+ */
+ readonly isEnabledFileDownloads?: boolean
+
+ /**
+ * Whether the "Upload..." button is enabled.
+ */
+ readonly isEnabledFileUploads?: boolean
+
//#endregion
//#region Profile options
Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -34,6 +34,16 @@ export interface IBrowserWorkbenchEnviro
readonly options?: IWorkbenchConstructionOptions;
/**
+ * Enable downloading files via menu actions.
+ */
+ readonly isEnabledFileDownloads?: boolean;
+
+ /**
+ * Enable uploading files via menu actions.
+ */
+ readonly isEnabledFileUploads?: boolean;
+
+ /**
* Gets whether a resolver extension is expected for the environment.
*/
readonly expectsResolverExtension: boolean;
@@ -111,6 +121,20 @@ export class BrowserWorkbenchEnvironment
return this.options.userDataPath;
}
+ get isEnabledFileDownloads(): boolean {
+ if (typeof this.options.isEnabledFileDownloads === "undefined") {
+ throw new Error('isEnabledFileDownloads was not provided to the browser');
+ }
+ return this.options.isEnabledFileDownloads;
+ }
+
+ get isEnabledFileUploads(): boolean {
+ if (typeof this.options.isEnabledFileUploads === "undefined") {
+ throw new Error('isEnabledFileUploads was not provided to the browser');
+ }
+ return this.options.isEnabledFileUploads;
+ }
+
@memoize
get argvResource(): URI { return joinPath(this.userRoamingDataHome, 'argv.json'); }
Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
@@ -16,6 +16,8 @@ export const serverOptions: OptionDescri
/* ----- code-server ----- */
'disable-update-check': { type: 'boolean' },
'auth': { type: 'string' },
+ 'disable-file-downloads': { type: 'boolean' },
+ 'disable-file-uploads': { type: 'boolean' },
/* ----- server setup ----- */
@@ -99,6 +101,8 @@ export interface ServerParsedArgs {
/* ----- code-server ----- */
'disable-update-check'?: boolean;
'auth'?: string;
+ 'disable-file-downloads'?: boolean;
+ 'disable-file-uploads'?: boolean;
/* ----- server setup ----- */
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -334,6 +334,8 @@ export class WebClientServer {
serverBasePath: this._basePath,
webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
userDataPath: this._environmentService.userDataPath,
+ isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'],
+ isEnabledFileUploads: !this._environmentService.args['disable-file-uploads'],
_wrapWebWorkerExtHostInIframe,
developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, logLevel: this._logService.getLevel() },
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
@@ -7,11 +7,11 @@ import { Event } from 'vs/base/common/ev
import { Disposable } from 'vs/base/common/lifecycle';
import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from 'vs/platform/contextkey/common/contextkey';
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from 'vs/platform/contextkey/common/contextkeys';
-import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext } from 'vs/workbench/common/contextkeys';
+import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, IsEnabledFileDownloads, IsEnabledFileUploads } from 'vs/workbench/common/contextkeys';
import { trackFocus, addDisposableListener, EventType, onDidRegisterWindow, getActiveWindow } from 'vs/base/browser/dom';
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
-import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
+import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
import { WorkbenchState, IWorkspaceContextService, isTemporaryWorkspace } from 'vs/platform/workspace/common/workspace';
import { IWorkbenchLayoutService, Parts, positionToString } from 'vs/workbench/services/layout/browser/layoutService';
import { getRemoteName } from 'vs/platform/remote/common/remoteHosts';
@@ -70,7 +70,7 @@ export class WorkbenchContextKeysHandler
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IConfigurationService private readonly configurationService: IConfigurationService,
- @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
+ @IBrowserWorkbenchEnvironmentService private readonly environmentService: IBrowserWorkbenchEnvironmentService,
@IProductService private readonly productService: IProductService,
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
@IEditorService private readonly editorService: IEditorService,
@@ -197,6 +197,10 @@ export class WorkbenchContextKeysHandler
this.auxiliaryBarVisibleContext = AuxiliaryBarVisibleContext.bindTo(this.contextKeyService);
this.auxiliaryBarVisibleContext.set(this.layoutService.isVisible(Parts.AUXILIARYBAR_PART));
+ // code-server
+ IsEnabledFileDownloads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileDownloads ?? true)
+ IsEnabledFileUploads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileUploads ?? true)
+
this.registerListeners();
}
Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts
@@ -20,7 +20,7 @@ import { CLOSE_SAVED_EDITORS_COMMAND_ID,
import { AutoSaveAfterShortDelayContext } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { WorkbenchListDoubleSelection } from 'vs/platform/list/browser/listService';
import { Schemas } from 'vs/base/common/network';
-import { DirtyWorkingCopiesContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, ActiveEditorAvailableEditorIdsContext, MultipleEditorsSelectedInGroupContext, TwoEditorsSelectedInGroupContext } from 'vs/workbench/common/contextkeys';
+import { DirtyWorkingCopiesContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, WorkbenchStateContext, WorkspaceFolderCountContext, SidebarFocusContext, ActiveEditorCanRevertContext, ActiveEditorContext, ResourceContextKey, ActiveEditorAvailableEditorIdsContext, MultipleEditorsSelectedInGroupContext, TwoEditorsSelectedInGroupContext, IsEnabledFileDownloads, IsEnabledFileUploads } from 'vs/workbench/common/contextkeys';
import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { ThemeIcon } from 'vs/base/common/themables';
@@ -561,13 +561,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo
id: DOWNLOAD_COMMAND_ID,
title: DOWNLOAD_LABEL
},
- when: ContextKeyExpr.or(
- // native: for any remote resource
- ContextKeyExpr.and(IsWebContext.toNegated(), ResourceContextKey.Scheme.notEqualsTo(Schemas.file)),
- // web: for any files
- ContextKeyExpr.and(IsWebContext, ExplorerFolderContext.toNegated(), ExplorerRootContext.toNegated()),
- // web: for any folders if file system API support is provided
- ContextKeyExpr.and(IsWebContext, HasWebFileSystemAccess)
+ when: ContextKeyExpr.and(
+ IsEnabledFileDownloads,
+ ContextKeyExpr.or(
+ // native: for any remote resource
+ ContextKeyExpr.and(IsWebContext.toNegated(), ResourceContextKey.Scheme.notEqualsTo(Schemas.file)),
+ // web: for any files
+ ContextKeyExpr.and(IsWebContext, ExplorerFolderContext.toNegated(), ExplorerRootContext.toNegated()),
+ // web: for any folders if file system API support is provided
+ ContextKeyExpr.and(IsWebContext, HasWebFileSystemAccess)
+ )
)
}));
@@ -579,6 +582,7 @@ MenuRegistry.appendMenuItem(MenuId.Explo
title: UPLOAD_LABEL,
},
when: ContextKeyExpr.and(
+ IsEnabledFileUploads,
// only in web
IsWebContext,
// only on folders
Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
@@ -40,6 +40,9 @@ export const HasWebFileSystemAccess = ne
export const EmbedderIdentifierContext = new RawContextKey<string | undefined>('embedderIdentifier', undefined, localize('embedderIdentifier', 'The identifier of the embedder according to the product service, if one is defined'));
+export const IsEnabledFileDownloads = new RawContextKey<boolean>('isEnabledFileDownloads', true, true);
+export const IsEnabledFileUploads = new RawContextKey<boolean>('isEnabledFileUploads', true, true);
+
//#endregion
Index: code-server/lib/vscode/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts
+++ code-server/lib/vscode/src/vs/workbench/services/dialogs/browser/simpleFileDialog.ts
@@ -18,7 +18,7 @@ import { IModelService } from 'vs/editor
import { ILanguageService } from 'vs/editor/common/languages/language';
import { getIconClasses } from 'vs/editor/common/services/getIconClasses';
import { Schemas } from 'vs/base/common/network';
-import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
+import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IContextKeyService, IContextKey, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { equalsIgnoreCase, format, startsWithIgnoreCase } from 'vs/base/common/strings';
@@ -143,7 +143,7 @@ export class SimpleFileDialog implements
@IFileDialogService private readonly fileDialogService: IFileDialogService,
@IModelService private readonly modelService: IModelService,
@ILanguageService private readonly languageService: ILanguageService,
- @IWorkbenchEnvironmentService protected readonly environmentService: IWorkbenchEnvironmentService,
+ @IBrowserWorkbenchEnvironmentService protected readonly environmentService: IBrowserWorkbenchEnvironmentService,
@IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService,
@IPathService protected readonly pathService: IPathService,
@IKeybindingService private readonly keybindingService: IKeybindingService,
@@ -286,20 +286,22 @@ export class SimpleFileDialog implements
this.filePickBox.sortByLabel = false;
this.filePickBox.ignoreFocusOut = true;
this.filePickBox.ok = true;
- if ((this.scheme !== Schemas.file) && this.options && this.options.availableFileSystems && (this.options.availableFileSystems.length > 1) && (this.options.availableFileSystems.indexOf(Schemas.file) > -1)) {
- this.filePickBox.customButton = true;
- this.filePickBox.customLabel = nls.localize('remoteFileDialog.local', 'Show Local');
- let action;
- if (isSave) {
- action = SaveLocalFileCommand;
- } else {
- action = this.allowFileSelection ? (this.allowFolderSelection ? OpenLocalFileFolderCommand : OpenLocalFileCommand) : OpenLocalFolderCommand;
- }
- const keybinding = this.keybindingService.lookupKeybinding(action.ID);
- if (keybinding) {
- const label = keybinding.getLabel();
- if (label) {
- this.filePickBox.customHover = format('{0} ({1})', action.LABEL, label);
+ if ((isSave && this.environmentService.isEnabledFileDownloads) || (!isSave && this.environmentService.isEnabledFileUploads)) {
+ if ((this.scheme !== Schemas.file) && this.options && this.options.availableFileSystems && (this.options.availableFileSystems.length > 1) && (this.options.availableFileSystems.indexOf(Schemas.file) > -1)) {
+ this.filePickBox.customButton = true;
+ this.filePickBox.customLabel = nls.localize('remoteFileDialog.local', 'Show Local');
+ let action;
+ if (isSave) {
+ action = SaveLocalFileCommand;
+ } else {
+ action = this.allowFileSelection ? (this.allowFolderSelection ? OpenLocalFileFolderCommand : OpenLocalFileCommand) : OpenLocalFolderCommand;
+ }
+ const keybinding = this.keybindingService.lookupKeybinding(action.ID);
+ if (keybinding) {
+ const label = keybinding.getLabel();
+ if (label) {
+ this.filePickBox.customHover = format('{0} ({1})', action.LABEL, label);
+ }
}
}
}
Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts
@@ -65,6 +65,7 @@ import { timeout } from 'vs/base/common/
import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { mainWindow } from 'vs/base/browser/window';
import { IExplorerFileContribution, explorerFileContribRegistry } from 'vs/workbench/contrib/files/browser/explorerFileContrib';
+import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
export class ExplorerDelegate implements IListVirtualDelegate<ExplorerItem> {
@@ -1001,7 +1002,8 @@ export class FileDragAndDrop implements
@IConfigurationService private configurationService: IConfigurationService,
@IInstantiationService private instantiationService: IInstantiationService,
@IWorkspaceEditingService private workspaceEditingService: IWorkspaceEditingService,
- @IUriIdentityService private readonly uriIdentityService: IUriIdentityService
+ @IUriIdentityService private readonly uriIdentityService: IUriIdentityService,
+ @IBrowserWorkbenchEnvironmentService protected readonly environmentService: IBrowserWorkbenchEnvironmentService
) {
const updateDropEnablement = (e: IConfigurationChangeEvent | undefined) => {
if (!e || e.affectsConfiguration('explorer.enableDragAndDrop')) {
@@ -1226,15 +1228,17 @@ export class FileDragAndDrop implements
// External file DND (Import/Upload file)
if (data instanceof NativeDragAndDropData) {
- // Use local file import when supported
- if (!isWeb || (isTemporaryWorkspace(this.contextService.getWorkspace()) && WebFileSystemAccess.supported(mainWindow))) {
- const fileImport = this.instantiationService.createInstance(ExternalFileImport);
- await fileImport.import(resolvedTarget, originalEvent, mainWindow);
- }
- // Otherwise fallback to browser based file upload
- else {
- const browserUpload = this.instantiationService.createInstance(BrowserFileUpload);
- await browserUpload.upload(target, originalEvent);
+ if (this.environmentService.isEnabledFileUploads) {
+ // Use local file import when supported
+ if (!isWeb || (isTemporaryWorkspace(this.contextService.getWorkspace()) && WebFileSystemAccess.supported(mainWindow))) {
+ const fileImport = this.instantiationService.createInstance(ExternalFileImport);
+ await fileImport.import(resolvedTarget, originalEvent, mainWindow);
+ }
+ // Otherwise fallback to browser based file upload
+ else {
+ const browserUpload = this.instantiationService.createInstance(BrowserFileUpload);
+ await browserUpload.upload(target, originalEvent);
+ }
}
}
Index: code-server/lib/vscode/src/vs/platform/files/node/diskFileSystemProviderServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/files/node/diskFileSystemProviderServer.ts
+++ code-server/lib/vscode/src/vs/platform/files/node/diskFileSystemProviderServer.ts
@@ -92,6 +92,7 @@ export abstract class AbstractDiskFileSy
private async readFile(uriTransformer: IURITransformer, _resource: UriComponents, opts?: IFileAtomicReadOptions): Promise<VSBuffer> {
const resource = this.transformIncoming(uriTransformer, _resource, true);
+ this.logService.trace(`File action: readFile ${resource.path}`);
const buffer = await this.provider.readFile(resource, opts);
return VSBuffer.wrap(buffer);
@@ -110,6 +111,7 @@ export abstract class AbstractDiskFileSy
}
});
+ this.logService.trace(`File action: readFileStream ${resource.path}`);
const fileStream = this.provider.readFileStream(resource, opts, cts.token);
listenStream(fileStream, {
onData: chunk => emitter.fire(VSBuffer.wrap(chunk)),
@@ -130,7 +132,7 @@ export abstract class AbstractDiskFileSy
private writeFile(uriTransformer: IURITransformer, _resource: UriComponents, content: VSBuffer, opts: IFileWriteOptions): Promise<void> {
const resource = this.transformIncoming(uriTransformer, _resource);
-
+ this.logService.trace(`File action: writeFile ${resource.path}`);
return this.provider.writeFile(resource, content.buffer, opts);
}

View File

@@ -10,16 +10,25 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts
@@ -60,7 +60,7 @@ import { GettingStartedIndexList } from
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { $, Dimension, addDisposableListener, append, clearNode, reset } from 'vs/base/browser/dom';
+import { $, Dimension, addDisposableListener, append, clearNode, reset, prepend } from 'vs/base/browser/dom';
import { renderFormattedText } from 'vs/base/browser/formattedTextRenderer';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { getTelemetryLevel } from 'vs/platform/telemetry/common/telemetryUtils';
import { Button } from 'vs/base/browser/ui/button/button';
@@ -54,7 +54,7 @@ import { IRecentFolder, IRecentWorkspace
import { OpenRecentAction } from 'vs/workbench/browser/actions/windowActions';
import { OpenFileFolderAction, OpenFolderAction, OpenFolderViaWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions';
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
-import { WorkbenchStateContext } from 'vs/workbench/common/contextkeys';
+import { IsEnabledCoderGettingStarted, WorkbenchStateContext } from 'vs/workbench/common/contextkeys';
import { OpenFolderViaWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions';
import { OpenRecentAction } from 'vs/workbench/browser/actions/windowActions';
import { Toggle } from 'vs/base/browser/ui/toggle/toggle';
@@ -759,6 +759,72 @@ export class GettingStartedPage extends
import { IEditorOpenContext, IEditorSerializer } from 'vs/workbench/common/editor';
import { IWebviewElement, IWebviewService } from 'vs/workbench/contrib/webview/browser/webview';
import 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedColors';
@@ -816,6 +816,72 @@ export class GettingStartedPage extends
$('p.subtitle.description', {}, localize({ key: 'gettingStarted.editingEvolved', comment: ['Shown as subtitle on the Welcome page.'] }, "Editing evolved"))
);
@@ -87,38 +96,21 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
+ ),
+ ),
+ );
+ }
+ }
+
const leftColumn = $('.categories-column.categories-column-left', {},);
const rightColumn = $('.categories-column.categories-column-right', {},);
@@ -776,13 +842,23 @@ export class GettingStartedPage extends
const layoutLists = () => {
if (gettingStartedList.itemCount) {
this.container.classList.remove('noWalkthroughs');
- reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
- reset(rightColumn, gettingStartedList.getDomElement());
+ if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) {
+ reset(leftColumn, startList.getDomElement(), recentList.getDomElement(), gettingStartedList.getDomElement());
+ reset(rightColumn, gettingStartedCoder);
+ } else {
+ reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
+ reset(rightColumn, gettingStartedList.getDomElement());
+ }
+
@@ -887,6 +953,9 @@ export class GettingStartedPage extends
recentList.setLimit(5);
reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
}
else {
this.container.classList.add('noWalkthroughs');
- reset(leftColumn, startList.getDomElement());
+ if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) {
+ reset(leftColumn, startList.getDomElement(), gettingStartedCoder);
+ } else {
+ reset(leftColumn, startList.getDomElement());
+ }
reset(rightColumn, recentList.getDomElement());
recentList.setLimit(10);
}
+ if (this.contextService.contextMatchesRules(IsEnabledCoderGettingStarted)) {
+ prepend(rightColumn, gettingStartedCoder)
+ }
};
gettingStartedList.onDidChange(layoutLists);
Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css
@@ -131,21 +123,21 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/welcomeGettingStarted/bro
+ margin-bottom: 0.2em;
+}
+
+.monaco-workbench .part.editor>.content .gettingStartedContainer .coder-coder {
+.monaco-workbench .part.editor > .content .gettingStartedContainer .coder-coder {
+ font-size: 1em;
+ margin-top: 0.2em;
+}
+
.monaco-workbench.hc-black .part.editor>.content .gettingStartedContainer .subtitle,
.monaco-workbench.hc-light .part.editor>.content .gettingStartedContainer .subtitle {
.monaco-workbench.hc-black .part.editor > .content .gettingStartedContainer .subtitle,
.monaco-workbench.hc-light .part.editor > .content .gettingStartedContainer .subtitle {
font-weight: 200;
Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
@@ -271,6 +271,11 @@ export interface IWorkbenchConstructionO
@@ -313,6 +313,11 @@ export interface IWorkbenchConstructionO
*/
readonly isEnabledFileDownloads?: boolean
readonly isEnabledFileUploads?: boolean
+ /**
+ * Whether to use Coder's custom Getting Started text.
@@ -159,20 +151,20 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -37,6 +37,11 @@ export interface IBrowserWorkbenchEnviro
* Enable downloading files via menu actions.
*/
readonly isEnabledFileDownloads?: boolean;
+
+ /**
@@ -44,6 +44,11 @@ export interface IBrowserWorkbenchEnviro
readonly isEnabledFileUploads?: boolean;
/**
+ * Enable Coder's custom getting started text.
+ */
+ readonly isEnabledCoderGettingStarted?: boolean;
}
export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvironmentService {
@@ -116,6 +121,13 @@ export class BrowserWorkbenchEnvironment
return this.options.isEnabledFileDownloads;
+
+ /**
* Gets whether a resolver extension is expected for the environment.
*/
readonly expectsResolverExtension: boolean;
@@ -135,6 +140,13 @@ export class BrowserWorkbenchEnvironment
return this.options.isEnabledFileUploads;
}
+ get isEnabledCoderGettingStarted(): boolean {
@@ -189,19 +181,19 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
@@ -16,6 +16,7 @@ export const serverOptions: OptionDescri
'auth': { type: 'string' },
@@ -19,6 +19,7 @@ export const serverOptions: OptionDescri
'disable-file-downloads': { type: 'boolean' },
'disable-file-uploads': { type: 'boolean' },
'locale': { type: 'string' },
+ 'disable-getting-started-override': { type: 'boolean' },
/* ----- server setup ----- */
@@ -98,6 +99,7 @@ export interface ServerParsedArgs {
'auth'?: string
@@ -105,6 +106,7 @@ export interface ServerParsedArgs {
'disable-file-downloads'?: boolean;
'disable-file-uploads'?: boolean;
'locale'?: string
+ 'disable-getting-started-override'?: boolean;
+ 'disable-getting-started-override'?: boolean,
/* ----- server setup ----- */
@@ -209,10 +201,10 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -308,6 +308,7 @@ export class WebClientServer {
webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
@@ -339,6 +339,7 @@ export class WebClientServer {
userDataPath: this._environmentService.userDataPath,
isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'],
isEnabledFileUploads: !this._environmentService.args['disable-file-uploads'],
+ isEnabledCoderGettingStarted: !this._environmentService.args['disable-getting-started-override'],
_wrapWebWorkerExtHostInIframe,
developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, logLevel: this._logService.getLevel() },
@@ -223,17 +215,17 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
@@ -7,7 +7,7 @@ import { Event } from 'vs/base/common/ev
import { Disposable } from 'vs/base/common/lifecycle';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IContextKeyService, IContextKey, setConstant as setConstantContextKey } from 'vs/platform/contextkey/common/contextkey';
import { InputFocusedContext, IsMacContext, IsLinuxContext, IsWindowsContext, IsWebContext, IsMacNativeContext, IsDevelopmentContext, IsIOSContext, ProductQualityContext, IsMobileContext } from 'vs/platform/contextkey/common/contextkeys';
-import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, IsEnabledFileDownloads } from 'vs/workbench/common/contextkeys';
+import { SplitEditorsVertically, InEditorZenModeContext, ActiveEditorCanRevertContext, ActiveEditorGroupLockedContext, ActiveEditorCanSplitInGroupContext, SideBySideEditorActiveContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, ActiveEditorContext, EditorsVisibleContext, TextCompareEditorVisibleContext, TextCompareEditorActiveContext, ActiveEditorGroupEmptyContext, MultipleEditorGroupsContext, EditorTabsVisibleContext, IsCenteredLayoutContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorReadonlyContext, EditorAreaVisibleContext, ActiveEditorAvailableEditorIdsContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, IsEnabledFileDownloads, IsEnabledCoderGettingStarted } from 'vs/workbench/common/contextkeys';
import { TEXT_DIFF_EDITOR_ID, EditorInputCapabilities, SIDE_BY_SIDE_EDITOR_ID, DEFAULT_EDITOR_ASSOCIATION } from 'vs/workbench/common/editor';
import { trackFocus, addDisposableListener, EventType } from 'vs/base/browser/dom';
-import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, IsEnabledFileDownloads, IsEnabledFileUploads } from 'vs/workbench/common/contextkeys';
+import { SplitEditorsVertically, InEditorZenModeContext, AuxiliaryBarVisibleContext, SideBarVisibleContext, PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext, EmbedderIdentifierContext, EditorTabsVisibleContext, IsMainEditorCenteredLayoutContext, MainEditorAreaVisibleContext, DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, EnterMultiRootWorkspaceSupportContext, HasWebFileSystemAccess, IsMainWindowFullscreenContext, OpenFolderWorkspaceSupportContext, RemoteNameContext, VirtualWorkspaceContext, WorkbenchStateContext, WorkspaceFolderCountContext, PanelPositionContext, TemporaryWorkspaceContext, TitleBarVisibleContext, TitleBarStyleContext, IsAuxiliaryWindowFocusedContext, ActiveEditorGroupEmptyContext, ActiveEditorGroupIndexContext, ActiveEditorGroupLastContext, ActiveEditorGroupLockedContext, MultipleEditorGroupsContext, EditorsVisibleContext, IsEnabledFileDownloads, IsEnabledFileUploads, IsEnabledCoderGettingStarted, } from 'vs/workbench/common/contextkeys';
import { trackFocus, addDisposableListener, EventType, onDidRegisterWindow, getActiveWindow } from 'vs/base/browser/dom';
import { preferredSideBySideGroupDirection, GroupDirection, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
@@ -204,6 +204,7 @@ export class WorkbenchContextKeysHandler
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@@ -200,6 +200,7 @@ export class WorkbenchContextKeysHandler
// code-server
IsEnabledFileDownloads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileDownloads ?? true)
IsEnabledFileUploads.bindTo(this.contextKeyService).set(this.environmentService.isEnabledFileUploads ?? true)
+ IsEnabledCoderGettingStarted.bindTo(this.contextKeyService).set(this.environmentService.isEnabledCoderGettingStarted ?? true)
this.registerListeners();
@@ -242,10 +234,10 @@ Index: code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/common/contextkeys.ts
+++ code-server/lib/vscode/src/vs/workbench/common/contextkeys.ts
@@ -33,6 +33,7 @@ export const IsFullscreenContext = new R
export const HasWebFileSystemAccess = new RawContextKey<boolean>('hasWebFileSystemAccess', false, true); // Support for FileSystemAccess web APIs (https://wicg.github.io/file-system-access)
@@ -42,6 +42,7 @@ export const EmbedderIdentifierContext =
export const IsEnabledFileDownloads = new RawContextKey<boolean>('isEnabledFileDownloads', true, true);
export const IsEnabledFileUploads = new RawContextKey<boolean>('isEnabledFileUploads', true, true);
+export const IsEnabledCoderGettingStarted = new RawContextKey<boolean>('isEnabledCoderGettingStarted', true, true);
//#endregion

View File

@@ -1,106 +0,0 @@
Add the ability to provide a GitHub token
To test install the GitHub PR extension and start code-server with GITHUB_TOKEN
or set github-auth in the config file. The extension should be authenticated.
Index: code-server/lib/vscode/src/vs/platform/credentials/node/credentialsMainService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/credentials/node/credentialsMainService.ts
+++ code-server/lib/vscode/src/vs/platform/credentials/node/credentialsMainService.ts
@@ -5,9 +5,18 @@
import { InMemoryCredentialsProvider } from 'vs/platform/credentials/common/credentials';
import { ILogService } from 'vs/platform/log/common/log';
-import { INativeEnvironmentService } from 'vs/platform/environment/common/environment';
+import { IServerEnvironmentService } from 'vs/server/node/serverEnvironmentService';
import { IProductService } from 'vs/platform/product/common/productService';
import { BaseCredentialsMainService, KeytarModule } from 'vs/platform/credentials/common/credentialsMainService';
+import { generateUuid } from 'vs/base/common/uuid';
+import { equals as arrayEquals } from 'vs/base/common/arrays';
+
+interface IToken {
+ accessToken: string
+ account?: { label: string }
+ id: string
+ scopes: string[]
+}
export class CredentialsWebMainService extends BaseCredentialsMainService {
// Since we fallback to the in-memory credentials provider, we do not need to surface any Keytar load errors
@@ -16,10 +25,15 @@ export class CredentialsWebMainService e
constructor(
@ILogService logService: ILogService,
- @INativeEnvironmentService private readonly environmentMainService: INativeEnvironmentService,
+ @IServerEnvironmentService private readonly environmentMainService: IServerEnvironmentService,
@IProductService private readonly productService: IProductService,
) {
super(logService);
+ if (this.environmentMainService.args["github-auth"]) {
+ this.storeGitHubToken(this.environmentMainService.args["github-auth"]).catch((error) => {
+ this.logService.error('Failed to store provided GitHub token', error)
+ })
+ }
}
// If the credentials service is running on the server, we add a suffix -server to differentiate from the location that the
@@ -48,4 +62,59 @@ export class CredentialsWebMainService e
}
return this._keytarCache;
}
+
+ private async storeGitHubToken(githubToken: string): Promise<void> {
+ const extensionId = 'vscode.github-authentication';
+ const service = `${await this.getSecretStoragePrefix()}${extensionId}`;
+ const account = 'github.auth';
+ const scopes = [['read:user', 'user:email', 'repo']]
+
+ // Oddly the scopes need to match exactly so we cannot just have one token
+ // with all the scopes, instead we have to duplicate the token for each
+ // expected set of scopes.
+ const tokens: IToken[] = scopes.map((scopes) => ({
+ id: generateUuid(),
+ scopes: scopes.sort(), // Sort for comparing later.
+ accessToken: githubToken,
+ }));
+
+ const raw = await this.getPassword(service, account)
+
+ let existing: {
+ content: IToken[]
+ } | undefined;
+
+ if (raw) {
+ try {
+ const json = JSON.parse(raw);
+ json.content = JSON.parse(json.content);
+ existing = json;
+ } catch (error) {
+ this.logService.error('Failed to parse existing GitHub credentials', error)
+ }
+ }
+
+ // Keep tokens for account and scope combinations we do not have in case
+ // there is an extension that uses scopes we have not accounted for (in
+ // these cases the user will need to manually authenticate the extension
+ // through the UI) or the user has tokens for other accounts.
+ if (existing?.content) {
+ existing.content = existing.content.filter((existingToken) => {
+ const scopes = existingToken.scopes.sort();
+ return !(tokens.find((token) => {
+ return arrayEquals(scopes, token.scopes)
+ && token.account?.label === existingToken.account?.label;
+ }))
+ })
+ }
+
+ return this.setPassword(service, account, JSON.stringify({
+ extensionId,
+ ...(existing || {}),
+ content: JSON.stringify([
+ ...tokens,
+ ...(existing?.content || []),
+ ])
+ }));
+ }
}

View File

@@ -95,7 +95,7 @@ Index: code-server/lib/vscode/src/vs/base/common/processes.ts
--- code-server.orig/lib/vscode/src/vs/base/common/processes.ts
+++ code-server/lib/vscode/src/vs/base/common/processes.ts
@@ -111,6 +111,8 @@ export function sanitizeProcessEnvironme
/^VSCODE_(?!(PORTABLE|SHELL_LOGIN)).+$/,
/^VSCODE_(?!(PORTABLE|SHELL_LOGIN|ENV_REPLACE|ENV_APPEND|ENV_PREPEND)).+$/,
/^SNAP(|_.*)$/,
/^GDK_PIXBUF_.+$/,
+ /^CODE_SERVER_.+$/,
@@ -107,7 +107,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandl
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts
@@ -145,8 +145,11 @@ export class BrowserDialogHandler implem
@@ -77,8 +77,11 @@ export class BrowserDialogHandler extend
async about(): Promise<void> {
const detailString = (useAgo: boolean): string => {
@@ -176,15 +176,15 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.main.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.main.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/web.main.ts
@@ -69,6 +69,7 @@ import { IndexedDB } from 'vs/base/brows
import { BrowserCredentialsService } from 'vs/workbench/services/credentials/browser/credentialsService';
import { IWorkspace } from 'vs/workbench/services/host/browser/browserHostService';
@@ -64,6 +64,7 @@ import { IOpenerService } from 'vs/platf
import { mixin, safeStringify } from 'vs/base/common/objects';
import { IndexedDB } from 'vs/base/browser/indexedDB';
import { WebFileSystemAccess } from 'vs/platform/files/browser/webFileSystemAccess';
+import { CodeServerClient } from 'vs/workbench/browser/client';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IProgressService } from 'vs/platform/progress/common/progress';
import { DelayedLogChannel } from 'vs/workbench/services/output/common/delayedLogChannel';
@@ -119,6 +120,9 @@ export class BrowserMain extends Disposa
@@ -131,6 +132,9 @@ export class BrowserMain extends Disposa
// Startup
const instantiationService = workbench.startup();
@@ -198,7 +198,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/lib/vscode/src/vs/base/common/product.ts
@@ -31,6 +31,8 @@ export type ExtensionVirtualWorkspaceSup
@@ -55,6 +55,8 @@ export type ExtensionVirtualWorkspaceSup
};
export interface IProductConfiguration {
@@ -264,11 +264,11 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -308,6 +308,7 @@ export class WebClientServer {
folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']),
workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']),
productConfiguration: <Partial<IProductConfiguration>>{
+ codeServerVersion: this._productService.codeServerVersion,
embedderIdentifier: 'server-distro',
extensionsGallery: this._webExtensionResourceUrlTemplate ? {
...this._productService.extensionsGallery,
@@ -307,6 +307,7 @@ export class WebClientServer {
} : undefined;
const productConfiguration = {
+ codeServerVersion: this._productService.codeServerVersion,
embedderIdentifier: 'server-distro',
extensionsGallery: this._webExtensionResourceUrlTemplate && this._productService.extensionsGallery ? {
...this._productService.extensionsGallery,

15
patches/keepalive.diff Normal file
View File

@@ -0,0 +1,15 @@
This can be removed after upgrading to Node >= 19 as keepAlive is defaulted to
true after 19.
Index: code-server/lib/vscode/src/vs/platform/request/node/proxy.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/request/node/proxy.ts
+++ code-server/lib/vscode/src/vs/platform/request/node/proxy.ts
@@ -42,6 +42,7 @@ export async function getProxyAgent(rawR
port: (proxyEndpoint.port ? +proxyEndpoint.port : 0) || (proxyEndpoint.protocol === 'https' ? 443 : 80),
auth: proxyEndpoint.auth,
rejectUnauthorized: isBoolean(options.strictSSL) ? options.strictSSL : true,
+ keepAlive: true,
};
return requestURL.protocol === 'http:'

View File

@@ -1,28 +1,26 @@
Make storage local to the remote server
This solves two problems:
1. Extensions running in the browser (like Vim) might use these paths
directly instead of using the file service and most likely can't write
to `/User` on disk.
2. Settings will be stored in the file system instead of in browser
storage. Using browser storage makes sharing or seeding settings
between browsers difficult. We may want to revisit this once/if we get
settings sync.
This makes user settings will be stored in the file system instead of in browser
storage. Using browser storage makes sharing or seeding settings between
browsers difficult and remote settings is not a sufficient replacement because
some settings are only allowed to be set on the user level.
Unfortunately this does not affect state which uses a separate method with
IndexedDB and does not appear nearly as easy to redirect to disk.
To test install the Vim extension and make sure something that uses file storage
works (history recall for example) and change settings from the UI and on disk
while making sure they appear on the other side.
To test change settings from the UI and on disk while making sure they appear on
the other side.
This patch also resolves a bug where a global value for workspace initialization
is used in a non async-safe way.
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -303,6 +303,7 @@ export class WebClientServer {
const workbenchWebConfiguration = {
@@ -329,6 +329,7 @@ export class WebClientServer {
remoteAuthority,
serverBasePath: this._basePath,
webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
+ userDataPath: this._environmentService.userDataPath,
_wrapWebWorkerExtHostInIframe,
@@ -32,7 +30,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts
+++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts
@@ -261,6 +261,11 @@ export interface IWorkbenchConstructionO
@@ -298,6 +298,11 @@ export interface IWorkbenchConstructionO
*/
readonly configurationDefaults?: Record<string, any>;
@@ -48,7 +46,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -95,7 +95,14 @@ export class BrowserWorkbenchEnvironment
@@ -102,7 +102,14 @@ export class BrowserWorkbenchEnvironment
get logFile(): URI { return joinPath(this.windowLogsPath, 'window.log'); }
@memoize
@@ -64,3 +62,33 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
@memoize
get argvResource(): URI { return joinPath(this.userRoamingDataHome, 'argv.json'); }
Index: code-server/lib/vscode/src/vs/workbench/services/configuration/browser/configurationService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/configuration/browser/configurationService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/configuration/browser/configurationService.ts
@@ -145,8 +145,10 @@ export class WorkspaceService extends Di
this.workspaceConfiguration = this._register(new WorkspaceConfiguration(configurationCache, fileService, uriIdentityService, logService));
this._register(this.workspaceConfiguration.onDidUpdateConfiguration(fromCache => {
this.onWorkspaceConfigurationChanged(fromCache).then(() => {
- this.workspace.initialized = this.workspaceConfiguration.initialized;
- this.checkAndMarkWorkspaceComplete(fromCache);
+ if (this.workspace) { // The workspace may not have been created yet.
+ this.workspace.initialized = this.workspaceConfiguration.initialized;
+ this.checkAndMarkWorkspaceComplete(fromCache);
+ }
});
}));
@@ -552,6 +554,12 @@ export class WorkspaceService extends Di
previousFolders = this.workspace.folders;
this.workspace.update(workspace);
} else {
+ // It is possible for the configuration to become initialized in between
+ // when the workspace was created and this function was called, so check
+ // the configuration again now.
+ if (!workspace.initialized && this.workspaceConfiguration.initialized) {
+ workspace.initialized = true;
+ }
this.workspace = workspace;
}

View File

@@ -8,7 +8,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/lib/vscode/src/vs/base/common/product.ts
@@ -34,6 +34,7 @@ export interface IProductConfiguration {
@@ -58,6 +58,7 @@ export interface IProductConfiguration {
readonly codeServerVersion?: string
readonly rootEndpoint?: string
readonly updateEndpoint?: string
@@ -20,7 +20,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
@@ -13,6 +13,7 @@ import { IEnvironmentService, INativeEnv
@@ -15,6 +15,7 @@ import { URI } from 'vs/base/common/uri'
export const serverOptions: OptionDescriptions<Required<ServerParsedArgs>> = {
/* ----- code-server ----- */
'disable-update-check': { type: 'boolean' },
@@ -28,11 +28,11 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
/* ----- server setup ----- */
@@ -92,6 +93,7 @@ export const serverOptions: OptionDescri
@@ -97,6 +98,7 @@ export const serverOptions: OptionDescri
export interface ServerParsedArgs {
/* ----- code-server ----- */
'disable-update-check'?: boolean;
+ 'auth'?: string
+ 'auth'?: string;
/* ----- server setup ----- */
@@ -40,14 +40,14 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -313,6 +313,7 @@ export class WebClientServer {
codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: base,
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
+ logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined,
embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery,
},
@@ -312,6 +312,7 @@ export class WebClientServer {
codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: base,
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
+ logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined,
embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery,
} satisfies Partial<IProductConfiguration>;
Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/browser/client.ts

View File

@@ -12,7 +12,7 @@ in-between and has web extensions install directly from the marketplace.
This can be tested by setting EXTENSIONS_GALLERY set to:
'{"serviceUrl": "https://extensions.coder.com/api"}'
'{"serviceUrl": "https://my-extensions/api"}'
Index: code-server/lib/vscode/src/vs/platform/product/common/product.ts
@@ -40,8 +40,8 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -111,7 +111,7 @@ export class WebClientServer {
const serverRootPath = getRemoteServerRootPath(_productService);
@@ -114,7 +114,7 @@ export class WebClientServer {
this._staticRoute = `${serverRootPath}/static`;
this._callbackRoute = `${serverRootPath}/callback`;
- this._webExtensionRoute = `${serverRootPath}/web-extension-resource`;
@@ -50,39 +50,50 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
/**
@@ -312,14 +312,7 @@ export class WebClientServer {
codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: base,
embedderIdentifier: 'server-distro',
- extensionsGallery: this._webExtensionResourceUrlTemplate ? {
- ...this._productService.extensionsGallery,
- 'resourceUrlTemplate': this._webExtensionResourceUrlTemplate.with({
- scheme: 'http',
- authority: remoteAuthority,
- path: `${this._webExtensionRoute}/${this._webExtensionResourceUrlTemplate.authority}${this._webExtensionResourceUrlTemplate.path}`
- }).toString(true)
- } : undefined
+ extensionsGallery: this._productService.extensionsGallery,
},
callbackRoute: this._callbackRoute
};
codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: base,
embedderIdentifier: 'server-distro',
- extensionsGallery: this._webExtensionResourceUrlTemplate && this._productService.extensionsGallery ? {
- ...this._productService.extensionsGallery,
- resourceUrlTemplate: this._webExtensionResourceUrlTemplate.with({
- scheme: 'http',
- authority: remoteAuthority,
- path: `${this._webExtensionRoute}/${this._webExtensionResourceUrlTemplate.authority}${this._webExtensionResourceUrlTemplate.path}`
- }).toString(true)
- } : undefined
+ extensionsGallery: this._productService.extensionsGallery,
} satisfies Partial<IProductConfiguration>;
if (!this._environmentService.isBuilt) {
Index: code-server/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts
+++ code-server/lib/vscode/src/vs/platform/extensionResourceLoader/common/extensionResourceLoader.ts
@@ -16,7 +16,6 @@ import { getServiceMachineId } from 'vs/
import { IStorageService } from 'vs/platform/storage/common/storage';
import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { getTelemetryLevel, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
-import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts';
@@ -140,9 +140,9 @@ export abstract class AbstractExtensionR
}
export const WEB_EXTENSION_RESOURCE_END_POINT = 'web-extension-resource';
protected _isWebExtensionResourceEndPoint(uri: URI): boolean {
- const uriPath = uri.path, serverRootPath = RemoteAuthorities.getServerRootPath();
- // test if the path starts with the server root path followed by the web extension resource end point segment
- return uriPath.startsWith(serverRootPath) && uriPath.startsWith(WEB_EXTENSION_RESOURCE_END_POINT_SEGMENT, serverRootPath.length);
+ const uriPath = uri.path;
+ // test if the path starts with the web extension resource end point segment
+ return uriPath.startsWith(WEB_EXTENSION_RESOURCE_END_POINT_SEGMENT);
}
}
Index: code-server/lib/vscode/src/vs/platform/extensionManagement/node/extensionDownloader.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/extensionManagement/node/extensionDownloader.ts
+++ code-server/lib/vscode/src/vs/platform/extensionManagement/node/extensionDownloader.ts
@@ -114,7 +114,10 @@ export class ExtensionsDownloader extend
return false;
}
+ return false
+ // @ts-expect-error
const value = this.configurationService.getValue('extensions.verifySignature');
+ // @ts-expect-error
return isBoolean(value) ? value : true;
}
@@ -60,7 +59,7 @@ export abstract class AbstractExtensionR
private readonly _environmentService: IEnvironmentService,
private readonly _configurationService: IConfigurationService,
) {
- this._webExtensionResourceEndPoint = `${getRemoteServerRootPath(_productService)}/${WEB_EXTENSION_RESOURCE_END_POINT}/`;
+ this._webExtensionResourceEndPoint = `/${WEB_EXTENSION_RESOURCE_END_POINT}/`;
if (_productService.extensionsGallery) {
this._extensionGalleryResourceUrlTemplate = _productService.extensionsGallery.resourceUrlTemplate;
this._extensionGalleryAuthority = this._extensionGalleryResourceUrlTemplate ? this._getExtensionGalleryAuthority(URI.parse(this._extensionGalleryResourceUrlTemplate)) : undefined;

View File

@@ -6,24 +6,11 @@ https://github.com/microsoft/vscode-extension-samples/tree/ddae6c0c9ff203b4ed6f6
We also override isProposedApiEnabled in case an extension does not declare the
APIs it needs correctly (the Jupyter extension had this issue).
Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/abstractExtensionService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/common/abstractExtensionService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/extensions/common/abstractExtensionService.ts
@@ -1486,7 +1486,7 @@ class ProposedApiController {
this._envEnabledExtensions = new Set((_environmentService.extensionEnabledProposedApi ?? []).map(id => ExtensionIdentifier.toKey(id)));
- this._envEnablesProposedApiForAll =
+ this._envEnablesProposedApiForAll = true ||
!_environmentService.isBuilt || // always allow proposed API when running out of sources
(_environmentService.isExtensionDevelopment && productService.quality !== 'stable') || // do not allow proposed API against stable builds when developing an extension
(this._envEnabledExtensions.size === 0 && Array.isArray(_environmentService.extensionEnabledProposedApi)); // always allow proposed API if --enable-proposed-api is provided without extension ID
Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts
+++ code-server/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts
@@ -364,10 +364,7 @@ function extensionDescriptionArrayToMap(
@@ -312,10 +312,7 @@ function extensionDescriptionArrayToMap(
}
export function isProposedApiEnabled(extension: IExtensionDescription, proposal: ApiProposalName): boolean {
@@ -35,3 +22,16 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/extens
}
export function checkProposedApiEnabled(extension: IExtensionDescription, proposal: ApiProposalName): void {
Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/extensionsProposedApi.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/common/extensionsProposedApi.ts
+++ code-server/lib/vscode/src/vs/workbench/services/extensions/common/extensionsProposedApi.ts
@@ -24,7 +24,7 @@ export class ExtensionsProposedApi {
this._envEnabledExtensions = new Set((_environmentService.extensionEnabledProposedApi ?? []).map(id => ExtensionIdentifier.toKey(id)));
- this._envEnablesProposedApiForAll =
+ this._envEnablesProposedApiForAll = true ||
!_environmentService.isBuilt || // always allow proposed API when running out of sources
(_environmentService.isExtensionDevelopment && productService.quality !== 'stable') || // do not allow proposed API against stable builds when developing an extension
(this._envEnabledExtensions.size === 0 && Array.isArray(_environmentService.extensionEnabledProposedApi)); // always allow proposed API if --enable-proposed-api is provided without extension ID

View File

@@ -30,7 +30,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/lib/vscode/src/vs/base/common/product.ts
@@ -35,6 +35,7 @@ export interface IProductConfiguration {
@@ -59,6 +59,7 @@ export interface IProductConfiguration {
readonly rootEndpoint?: string
readonly updateEndpoint?: string
readonly logoutEndpoint?: string
@@ -42,57 +42,48 @@ Index: code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityReso
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts
+++ code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts
@@ -11,7 +11,7 @@ import { StopWatch } from 'vs/base/commo
import { URI } from 'vs/base/common/uri';
import { ILogService } from 'vs/platform/log/common/log';
import { IProductService } from 'vs/platform/product/common/productService';
-import { IRemoteAuthorityResolverService, IRemoteConnectionData, ResolvedAuthority, ResolverResult, getRemoteAuthorityPrefix } from 'vs/platform/remote/common/remoteAuthorityResolver';
+import { IRemoteAuthorityResolverService, IRemoteConnectionData, ResolvedAuthority, ResolvedOptions, ResolverResult, getRemoteAuthorityPrefix } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { getRemoteServerRootPath, parseAuthorityWithOptionalPort } from 'vs/platform/remote/common/remoteHosts';
export class RemoteAuthorityResolverService extends Disposable implements IRemoteAuthorityResolverService {
@@ -29,7 +29,7 @@ export class RemoteAuthorityResolverServ
constructor(
@@ -35,7 +35,7 @@ export class RemoteAuthorityResolverServ
connectionToken: Promise<string> | string | undefined,
resourceUriProvider: ((uri: URI) => URI) | undefined,
serverBasePath: string | undefined,
- @IProductService productService: IProductService,
+ @IProductService private readonly productService: IProductService,
@ILogService private readonly _logService: ILogService,
) {
super();
@@ -75,9 +75,14 @@ export class RemoteAuthorityResolverServ
@@ -86,9 +86,14 @@ export class RemoteAuthorityResolverServ
const connectionToken = await Promise.resolve(this._connectionTokens.get(authority) || this._connectionToken);
performance.mark(`code/didResolveConnectionToken/${authorityPrefix}`);
this._logService.info(`Resolved connection token (${authorityPrefix}) after ${sw.elapsed()} ms`);
+ let options: ResolvedOptions | undefined;
+ if (this.productService.proxyEndpointTemplate) {
+ const proxyUrl = new URL(this.productService.proxyEndpointTemplate, window.location.href);
+ const proxyUrl = new URL(this.productService.proxyEndpointTemplate, mainWindow.location.href);
+ options = { extensionHostEnv: { VSCODE_PROXY_URI: decodeURIComponent(proxyUrl.toString()) }}
+ }
const defaultPort = (/^https:/.test(window.location.href) ? 443 : 80);
const defaultPort = (/^https:/.test(mainWindow.location.href) ? 443 : 80);
const { host, port } = parseAuthorityWithOptionalPort(authority, defaultPort);
- const result: ResolverResult = { authority: { authority, host: host, port: port, connectionToken } };
+ const result: ResolverResult = { authority: { authority, host: host, port: port, connectionToken }, options };
RemoteAuthorities.set(authority, result.authority.host, result.authority.port);
- const result: ResolverResult = { authority: { authority, connectTo: new WebSocketRemoteConnection(host, port), connectionToken } };
+ const result: ResolverResult = { authority: { authority, connectTo: new WebSocketRemoteConnection(host, port), connectionToken }, options };
RemoteAuthorities.set(authority, host, port);
this._cache.set(authority, result);
this._onDidChangeConnectionData.fire();
Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -314,6 +314,7 @@ export class WebClientServer {
rootEndpoint: base,
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined,
+ proxyEndpointTemplate: process.env.VSCODE_PROXY_URI ?? base + '/proxy/{{port}}/',
embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery,
},
@@ -313,6 +313,7 @@ export class WebClientServer {
rootEndpoint: base,
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined,
+ proxyEndpointTemplate: process.env.VSCODE_PROXY_URI ?? base + '/proxy/{{port}}/',
embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery,
} satisfies Partial<IProductConfiguration>;
Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts
@@ -383,7 +383,7 @@ export async function createTerminalEnvi
@@ -291,7 +291,7 @@ export async function createTerminalEnvi
// Sanitize the environment, removing any undesirable VS Code and Electron environment
// variables
@@ -105,33 +96,32 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.ts
+++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
@@ -21,6 +21,7 @@ import type { ICredentialsProvider } fro
import type { IURLCallbackProvider } from 'vs/workbench/services/url/browser/urlService';
import type { IWorkbenchConstructionOptions } from 'vs/workbench/browser/web.api';
import type { IWorkspace, IWorkspaceProvider } from 'vs/workbench/services/host/browser/browserHostService';
@@ -19,6 +19,7 @@ import { ISecretStorageProvider } from '
import { isFolderToOpen, isWorkspaceToOpen } from 'vs/platform/window/common/window';
import type { IWorkbenchConstructionOptions, IWorkspace, IWorkspaceProvider } from 'vs/workbench/browser/web.api';
import { AuthenticationSessionInfo } from 'vs/workbench/services/authentication/browser/authenticationService';
+import { extractLocalHostUriMetaDataForPortMapping, TunnelOptions, TunnelCreationOptions } from 'vs/platform/tunnel/common/tunnel';
import type { IURLCallbackProvider } from 'vs/workbench/services/url/browser/urlService';
import { create } from 'vs/workbench/workbench.web.main';
interface ICredential {
service: string;
@@ -511,6 +512,38 @@ function doCreateUri(path: string, query
} : undefined,
@@ -571,6 +572,39 @@ class WorkspaceProvider implements IWork
settingsSyncOptions: config.settingsSyncOptions ? { enabled: config.settingsSyncOptions.enabled, } : undefined,
workspaceProvider: WorkspaceProvider.create(config),
urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute),
- credentialsProvider: config.remoteAuthority ? undefined : new LocalStorageCredentialsProvider() // with a remote, we don't use a local credentials provider
+ credentialsProvider: config.remoteAuthority ? undefined : new LocalStorageCredentialsProvider(), // with a remote, we don't use a local credentials provider
+ resolveExternalUri: (uri: URI): Promise<URI> => {
+ let resolvedUri = uri
+ const localhostMatch = extractLocalHostUriMetaDataForPortMapping(resolvedUri)
+
+ if (localhostMatch && resolvedUri.authority !== location.host) {
+ if (config.productConfiguration && config.productConfiguration.proxyEndpointTemplate) {
+ resolvedUri = URI.parse(new URL(config.productConfiguration.proxyEndpointTemplate.replace('{{port}}', localhostMatch.port.toString()), window.location.href).toString())
+ const renderedTemplate = config.productConfiguration.proxyEndpointTemplate
+ .replace('{{port}}', localhostMatch.port.toString())
+ .replace('{{host}}', window.location.host)
+ resolvedUri = URI.parse(new URL(renderedTemplate, window.location.href).toString())
+ } else {
+ throw new Error(`Failed to resolve external URI: ${uri.toString()}. Could not determine base url because productConfiguration missing.`)
+ }
+ }
+
+ // If not localhost, return unmodified
+ // If not localhost, return unmodified.
+ return Promise.resolve(resolvedUri)
+ },
+ tunnelProvider: {
@@ -150,19 +140,20 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts
+ }
+ })
+ }
+ }
});
})();
+ },
secretStorageProvider: config.remoteAuthority && !secretStorageKeyPath
? undefined /* with a remote without embedder-preferred storage, store on the remote */
: new LocalStorageSecretStorageProvider(secretStorageCrypto),
Index: code-server/lib/vscode/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts
+++ code-server/lib/vscode/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts
@@ -73,7 +73,7 @@ export class ForwardedPortsView extends
this.contextKeyListener = undefined;
}
@@ -77,7 +77,7 @@ export class ForwardedPortsView extends
private async enableForwardedPortsView() {
this.contextKeyListener.clear();
- const viewEnabled: boolean = !!forwardedPortsViewEnabled.getValue(this.contextKeyService);
+ const viewEnabled: boolean = true;
if (this.environmentService.remoteAuthority && viewEnabled) {
if (viewEnabled) {
const viewContainer = await this.getViewContainer();

68
patches/safari.diff Normal file
View File

@@ -0,0 +1,68 @@
Revert back to es2020
es2022 outputs static blocks when using static properties that are not
compatible with Safari, or at least not older versions of Safari.
Index: code-server/lib/vscode/src/tsconfig.base.json
===================================================================
--- code-server.orig/lib/vscode/src/tsconfig.base.json
+++ code-server/lib/vscode/src/tsconfig.base.json
@@ -17,9 +17,30 @@
"./vs/*"
]
},
- "target": "es2022",
- "useDefineForClassFields": false,
+ "target": "es2020",
"lib": [
+ "ES2016",
+ "ES2017.Object",
+ "ES2017.String",
+ "ES2017.Intl",
+ "ES2017.TypedArrays",
+ "ES2018.AsyncIterable",
+ "ES2018.AsyncGenerator",
+ "ES2018.Promise",
+ "ES2018.Regexp",
+ "ES2018.Intl",
+ "ES2019.Array",
+ "ES2019.Object",
+ "ES2019.String",
+ "ES2019.Symbol",
+ "ES2020.BigInt",
+ "ES2020.Promise",
+ "ES2020.String",
+ "ES2020.Symbol.WellKnown",
+ "ES2020.Intl",
+ "ES2021.Promise",
+ "ES2021.String",
+ "ES2021.WeakRef",
"ES2022",
"DOM",
"DOM.Iterable",
Index: code-server/lib/vscode/build/lib/tsb/transpiler.js
===================================================================
--- code-server.orig/lib/vscode/build/lib/tsb/transpiler.js
+++ code-server/lib/vscode/build/lib/tsb/transpiler.js
@@ -293,7 +293,7 @@ class SwcTranspiler {
tsx: false,
decorators: true
},
- target: 'es2022',
+ target: 'es2020',
loose: false,
minify: {
compress: false,
Index: code-server/lib/vscode/build/lib/tsb/transpiler.ts
===================================================================
--- code-server.orig/lib/vscode/build/lib/tsb/transpiler.ts
+++ code-server/lib/vscode/build/lib/tsb/transpiler.ts
@@ -376,7 +376,7 @@ export class SwcTranspiler implements IT
tsx: false,
decorators: true
},
- target: 'es2022',
+ target: 'es2020',
loose: false,
minify: {
compress: false,

View File

@@ -9,13 +9,15 @@ update-check.diff
logout.diff
store-socket.diff
proxy-uri.diff
github-auth.diff
unique-db.diff
local-storage.diff
service-worker.diff
sourcemaps.diff
disable-downloads.diff
external-file-actions.diff
telemetry.diff
display-language.diff
cli-window-open.diff
getting-started.diff
safari.diff
keepalive.diff
clipboard.diff

View File

@@ -6,7 +6,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/lib/vscode/src/vs/base/common/product.ts
@@ -36,6 +36,10 @@ export interface IProductConfiguration {
@@ -60,6 +60,10 @@ export interface IProductConfiguration {
readonly updateEndpoint?: string
readonly logoutEndpoint?: string
readonly proxyEndpointTemplate?: string
@@ -54,14 +54,14 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -316,6 +316,10 @@ export class WebClientServer {
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined,
proxyEndpointTemplate: process.env.VSCODE_PROXY_URI ?? base + '/proxy/{{port}}/',
+ serviceWorker: {
+ scope: vscodeBase + '/',
+ path: base + '/_static/out/browser/serviceWorker.js',
+ },
embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery,
},
@@ -314,6 +314,10 @@ export class WebClientServer {
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined,
proxyEndpointTemplate: process.env.VSCODE_PROXY_URI ?? base + '/proxy/{{port}}/',
+ serviceWorker: {
+ scope: vscodeBase + '/',
+ path: base + '/_static/out/browser/serviceWorker.js',
+ },
embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery,
} satisfies Partial<IProductConfiguration>;

View File

@@ -10,7 +10,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js
===================================================================
--- code-server.orig/lib/vscode/build/gulpfile.reh.js
+++ code-server/lib/vscode/build/gulpfile.reh.js
@@ -192,8 +192,7 @@ function packageTask(type, platform, arc
@@ -236,8 +236,7 @@ function packageTask(type, platform, arc
const src = gulp.src(sourceFolderName + '/**', { base: '.' })
.pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); }))
@@ -20,7 +20,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js
const workspaceExtensionPoints = ['debuggers', 'jsonValidation'];
const isUIExtension = (manifest) => {
@@ -232,9 +231,9 @@ function packageTask(type, platform, arc
@@ -276,9 +275,9 @@ function packageTask(type, platform, arc
.map(name => `.build/extensions/${name}/**`);
const extensions = gulp.src(extensionPaths, { base: '.build', dot: true });
@@ -32,7 +32,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js
let version = packageJson.version;
const quality = product.quality;
@@ -389,7 +388,7 @@ function tweakProductForServerWeb(produc
@@ -439,7 +438,7 @@ function tweakProductForServerWeb(produc
const minifyTask = task.define(`minify-vscode-${type}`, task.series(
optimizeTask,
util.rimraf(`out-vscode-${type}-min`),

View File

@@ -1,4 +1,4 @@
Store a static reference to the IPC socket
Store the IPC socket with workspace metadata.
This lets us use it to open files inside code-server from outside of
code-server.
@@ -9,29 +9,121 @@ To test this:
It should open in your existing code-server instance.
When the extension host is terminated, the socket is unregistered.
Index: code-server/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.ts
+++ code-server/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.ts
@@ -2,7 +2,9 @@
@@ -2,7 +2,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-
+import { promises as fs } from 'fs';
+import * as os from 'os'
+import * as path from 'vs/base/common/path';
+import * as _http from 'http';
import * as performance from 'vs/base/common/performance';
import { createApiFactoryAndRegisterActors } from 'vs/workbench/api/common/extHost.api.impl';
import { RequireInterceptor } from 'vs/workbench/api/common/extHostRequireInterceptor';
@@ -72,6 +74,10 @@ export class ExtHostExtensionService ext
if (this._initData.remote.isRemote && this._initData.remote.authority) {
const cliServer = this._instaService.createInstance(CLIServer);
process.env['VSCODE_IPC_HOOK_CLI'] = cliServer.ipcHandlePath;
+
+ fs.writeFile(path.join(os.tmpdir(), 'vscode-ipc'), cliServer.ipcHandlePath).catch((error) => {
+ this._logService.error(error);
+ });
}
@@ -17,6 +17,7 @@ import { ExtensionRuntime } from 'vs/wor
import { CLIServer } from 'vs/workbench/api/node/extHostCLIServer';
import { realpathSync } from 'vs/base/node/extpath';
import { ExtHostConsoleForwarder } from 'vs/workbench/api/node/extHostConsoleForwarder';
+import { IExtHostWorkspace } from '../common/extHostWorkspace';
import { ExtHostDiskFileSystemProvider } from 'vs/workbench/api/node/extHostDiskFileSystemProvider';
// Module loading tricks
class NodeModuleRequireInterceptor extends RequireInterceptor {
@@ -83,6 +84,52 @@ export class ExtHostExtensionService ext
await interceptor.install();
performance.mark('code/extHost/didInitAPI');
+ (async () => {
+ const socketPath = process.env['VSCODE_IPC_HOOK_CLI'];
+ const codeServerSocketPath = process.env['CODE_SERVER_SESSION_SOCKET']
+ if (!socketPath || !codeServerSocketPath) {
+ return;
+ }
+ const workspace = this._instaService.invokeFunction((accessor) => {
+ const workspaceService = accessor.get(IExtHostWorkspace);
+ return workspaceService.workspace;
+ });
+ const entry = {
+ workspace,
+ socketPath
+ };
+ const message = JSON.stringify({entry});
+ await new Promise<void>((resolve, reject) => {
+ const opts: _http.RequestOptions = {
+ path: '/add-session',
+ socketPath: codeServerSocketPath,
+ method: 'POST',
+ headers: {
+ 'content-type': 'application/json',
+ }
+ };
+ const req = _http.request(opts, (res) => {
+ res.on('error', reject);
+ res.on('end', () => {
+ try {
+ if (res.statusCode === 200) {
+ resolve();
+ } else {
+ reject(new Error('Unexpected status code: ' + res.statusCode));
+ }
+ } catch (e: unknown) {
+ reject(e);
+ }
+ });
+ });
+ req.on('error', reject);
+ req.write(message);
+ req.end();
+ });
+ })().catch(error => {
+ this._logService.error(error);
+ });
+
// Do this when extension service exists, but extensions are not being activated yet.
const configProvider = await this._extHostConfiguration.getConfigProvider();
await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._logService, this._mainThreadTelemetryProxy, this._initData);
Index: code-server/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts
+++ code-server/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts
@@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
+import * as _http from 'http';
import * as nativeWatchdog from 'native-watchdog';
import * as net from 'net';
import * as minimist from 'minimist';
@@ -418,7 +419,28 @@ async function startExtensionHostProcess
);
// rewrite onTerminate-function to be a proper shutdown
- onTerminate = (reason: string) => extensionHostMain.terminate(reason);
+ onTerminate = (reason: string) => {
+ extensionHostMain.terminate(reason);
+
+ const socketPath = process.env['VSCODE_IPC_HOOK_CLI'];
+ const codeServerSocketPath = process.env['CODE_SERVER_SESSION_SOCKET']
+ if (!socketPath || !codeServerSocketPath) {
+ return;
+ }
+ const message = JSON.stringify({socketPath});
+ const opts: _http.RequestOptions = {
+ path: '/delete-session',
+ socketPath: codeServerSocketPath,
+ method: 'POST',
+ headers: {
+ 'content-type': 'application/json',
+ 'accept': 'application/json'
+ }
+ };
+ const req = _http.request(opts);
+ req.write(message);
+ req.end();
+ };
}
startExtensionHostProcess().catch((err) => console.log(err));

View File

@@ -12,42 +12,55 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/serverServices.ts
+++ code-server/lib/vscode/src/vs/server/node/serverServices.ts
@@ -70,6 +70,7 @@ import { IExtensionsScannerService } fro
@@ -65,6 +65,7 @@ import { IExtensionsScannerService } fro
import { ExtensionsScannerService } from 'vs/server/node/extensionsScannerService';
import { IExtensionsProfileScannerService } from 'vs/platform/extensionManagement/common/extensionsProfileScannerService';
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
+import { TelemetryClient } from "vs/server/node/telemetryClient";
+import { TelemetryClient } from 'vs/server/node/telemetryClient';
import { NullPolicyService } from 'vs/platform/policy/common/policy';
import { OneDataSystemAppender } from 'vs/platform/telemetry/node/1dsAppender';
import { LoggerService } from 'vs/platform/log/node/loggerService';
@@ -142,10 +143,13 @@ export async function setupServerService
const machineId = await getMachineId();
@@ -147,11 +148,23 @@ export async function setupServerService
const requestService = new RequestService(configurationService, environmentService, logService, loggerService);
services.set(IRequestService, requestService);
+ let isContainer = undefined;
+ try {
+ await Promises.stat('/run/.containerenv');
+ isContainer = true;
+ } catch (error) { /* Does not exist, probably. */ }
+ if (!isContainer) {
+ try {
+ const content = await Promises.readFile('/proc/self/cgroup', 'utf8')
+ isContainer = content.includes('docker');
+ } catch (error) { /* Permission denied, probably. */ }
+ }
+
let oneDsAppender: ITelemetryAppender = NullAppender;
const isInternal = isInternalTelemetry(productService, configurationService);
if (supportsTelemetry(productService, environmentService)) {
- if (productService.aiConfig && productService.aiConfig.ariaKey) {
+ const telemetryEndpoint = process.env.CS_TELEMETRY_URL || "https://v1.telemetry.coder.com/track";
+ if (telemetryEndpoint) {
+ oneDsAppender = new OneDataSystemAppender(false, eventPrefix, null, () => new TelemetryClient(telemetryEndpoint));
+ } else if (productService.aiConfig && productService.aiConfig.ariaKey) {
oneDsAppender = new OneDataSystemAppender(isInternal, eventPrefix, null, productService.aiConfig.ariaKey);
- disposables.add(toDisposable(() => oneDsAppender?.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
- if (!isLoggingOnly(productService, environmentService) && productService.aiConfig?.ariaKey) {
- oneDsAppender = new OneDataSystemAppender(requestService, isInternal, eventPrefix, null, productService.aiConfig.ariaKey);
+ if (!isLoggingOnly(productService, environmentService) && productService.telemetryEndpoint) {
+ oneDsAppender = new OneDataSystemAppender(requestService, isInternal, eventPrefix, null, () => new TelemetryClient(productService.telemetryEndpoint!, machineId, isContainer));
disposables.add(toDisposable(() => oneDsAppender?.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
}
+ disposables.add(toDisposable(() => oneDsAppender?.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
const config: ITelemetryServiceConfig = {
appenders: [oneDsAppender],
Index: code-server/lib/vscode/src/vs/server/node/telemetryClient.ts
===================================================================
--- /dev/null
+++ code-server/lib/vscode/src/vs/server/node/telemetryClient.ts
@@ -0,0 +1,49 @@
@@ -0,0 +1,55 @@
+import { AppInsightsCore, IExtendedTelemetryItem, ITelemetryItem } from '@microsoft/1ds-core-js';
+import * as https from 'https';
+import * as http from 'http';
+import * as os from 'os';
+
+export class TelemetryClient extends AppInsightsCore {
+ public constructor(private readonly endpoint: string) {
+ public constructor(
+ private readonly endpoint: string,
+ private readonly machineId: string,
+ private readonly isContainer: Boolean | undefined) {
+ super();
+ }
+
@@ -77,6 +90,9 @@ Index: code-server/lib/vscode/src/vs/server/node/telemetryClient.ts
+ options.properties['common.arch'] = os.arch();
+ } catch (error) {}
+
+ options.properties['common.remoteMachineId'] = this.machineId;
+ options.properties['common.isContainer'] = this.isContainer;
+
+ try {
+ const request = (/^http:/.test(this.endpoint) ? http : https).request(this.endpoint, {
+ method: 'POST',
@@ -94,11 +110,38 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -321,6 +321,7 @@ export class WebClientServer {
scope: vscodeBase + '/',
path: base + '/_static/out/browser/serviceWorker.js',
},
+ enableTelemetry: this._productService.enableTelemetry,
embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery,
@@ -318,6 +318,8 @@ export class WebClientServer {
scope: vscodeBase + '/',
path: base + '/_static/out/browser/serviceWorker.js',
},
+ enableTelemetry: this._productService.enableTelemetry,
+ telemetryEndpoint: this._productService.telemetryEndpoint,
embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery,
} satisfies Partial<IProductConfiguration>;
Index: code-server/lib/vscode/src/vs/base/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/lib/vscode/src/vs/base/common/product.ts
@@ -64,6 +64,7 @@ export interface IProductConfiguration {
readonly path: string;
readonly scope: string;
}
+ readonly telemetryEndpoint?: string
readonly version: string;
readonly date?: string;
Index: code-server/lib/vscode/src/vs/platform/product/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/platform/product/common/product.ts
+++ code-server/lib/vscode/src/vs/platform/product/common/product.ts
@@ -55,7 +55,8 @@ else if (globalThis._VSCODE_PRODUCT_JSON
resourceUrlTemplate: "https://open-vsx.org/vscode/asset/{publisher}/{name}/{version}/Microsoft.VisualStudio.Code.WebResources/{path}",
controlUrl: "",
recommendationsUrl: "",
- })
+ }),
+ telemetryEndpoint: env.CS_TELEMETRY_URL || product.telemetryEndpoint || "https://v1.telemetry.coder.com/track",
});
}

View File

@@ -13,7 +13,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/storage/browser/storageS
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/storage/browser/storageService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/storage/browser/storageService.ts
@@ -17,6 +17,7 @@ import { AbstractStorageService, isProfi
@@ -18,6 +18,7 @@ import { AbstractStorageService, isProfi
import { isUserDataProfile, IUserDataProfile } from 'vs/platform/userDataProfile/common/userDataProfile';
import { IAnyWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace';
import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
@@ -21,7 +21,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/storage/browser/storageS
export class BrowserStorageService extends AbstractStorageService {
@@ -297,7 +298,11 @@ export class IndexedDBStorageDatabase ex
@@ -298,7 +299,11 @@ export class IndexedDBStorageDatabase ex
}
static async createWorkspaceStorage(workspaceId: string, logService: ILogService): Promise<IIndexedDBStorageDatabase> {

View File

@@ -93,7 +93,7 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/base/common/product.ts
+++ code-server/lib/vscode/src/vs/base/common/product.ts
@@ -33,6 +33,7 @@ export type ExtensionVirtualWorkspaceSup
@@ -57,6 +57,7 @@ export type ExtensionVirtualWorkspaceSup
export interface IProductConfiguration {
readonly codeServerVersion?: string
readonly rootEndpoint?: string
@@ -105,20 +105,20 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -312,6 +312,7 @@ export class WebClientServer {
productConfiguration: <Partial<IProductConfiguration>>{
codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: base,
+ updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery,
},
@@ -311,6 +311,7 @@ export class WebClientServer {
const productConfiguration = {
codeServerVersion: this._productService.codeServerVersion,
rootEndpoint: base,
+ updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
embedderIdentifier: 'server-distro',
extensionsGallery: this._productService.extensionsGallery,
} satisfies Partial<IProductConfiguration>;
Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
@@ -11,6 +11,8 @@ import { refineServiceDecorator } from '
import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment';
@@ -13,6 +13,8 @@ import { memoize } from 'vs/base/common/
import { URI } from 'vs/base/common/uri';
export const serverOptions: OptionDescriptions<Required<ServerParsedArgs>> = {
+ /* ----- code-server ----- */
@@ -126,7 +126,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
/* ----- server setup ----- */
@@ -88,6 +90,8 @@ export const serverOptions: OptionDescri
@@ -93,6 +95,8 @@ export const serverOptions: OptionDescri
};
export interface ServerParsedArgs {

View File

@@ -41,7 +41,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
+++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -224,7 +224,7 @@ export class BrowserWorkbenchEnvironment
@@ -225,7 +225,7 @@ export class BrowserWorkbenchEnvironment
@memoize
get webviewExternalEndpoint(): string {
@@ -54,23 +54,14 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
@@ -302,6 +302,7 @@ export class WebClientServer {
@@ -325,6 +325,7 @@ export class WebClientServer {
const workbenchWebConfiguration = {
remoteAuthority,
serverBasePath: this._basePath,
+ webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre',
_wrapWebWorkerExtHostInIframe,
developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, logLevel: this._logService.getLevel() },
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
@@ -344,7 +345,7 @@ export class WebClientServer {
`script-src 'self' 'unsafe-eval' ${this._getScriptCspHashes(data).join(' ')} 'sha256-fh3TwPMflhsEIpR8g1OYTIMVWhXTLcjQ9kh2tIpmv54=';`, // the sha is the same as in src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html
'child-src \'self\';',
`frame-src 'self' https://*.vscode-cdn.net data:;`,
- 'worker-src \'self\' data:;',
+ 'worker-src \'self\' data: blob:;',
'style-src \'self\' \'unsafe-inline\';',
'connect-src \'self\' ws: wss: https:;',
'font-src \'self\' blob:;',
Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html
@@ -79,12 +70,12 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy"
- content="default-src 'none'; script-src 'sha256-RaCvj6SRgHm+2C3LKzSAamDwa3Bp4u4iQ1Y2Sm+97tE=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
+ content="default-src 'none'; script-src 'sha256-mi72idjvdhsPSBMKFqU82FG/kZVJjKR0TfHLE13gB+w=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
- content="default-src 'none'; script-src 'sha256-bQPwjO6bLiyf6v9eDVtAI67LrfonA1w49aFkRXBy4/g=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
+ content="default-src 'none'; script-src 'sha256-R3BsSkqy7qFbvWSmwr7WqT1eg6Sq4zSe0uIlrUQ4EKE=' 'self'; frame-src 'self'; style-src 'unsafe-inline';">
<!-- Disable pinch zooming -->
<meta name="viewport"
@@ -325,6 +325,12 @@
@@ -344,6 +344,12 @@
const hostname = location.hostname;
@@ -101,7 +92,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html
+++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html
@@ -324,6 +324,12 @@
@@ -343,6 +343,12 @@
const hostname = location.hostname;
@@ -122,8 +113,8 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/worker/webWor
<meta http-equiv="Content-Security-Policy" content="
default-src 'none';
child-src 'self' data: blob:;
- script-src 'self' 'unsafe-eval' 'sha256-/r7rqQ+yrxt57sxLuQ6AMYcy/lUpvAIzHjIJt/OeLWU=' https:;
+ script-src 'self' 'unsafe-eval' 'sha256-TkIM/TmudlFEe0ZRp0ptvN54LClwk30Rql4ZPE0hm/I=' https:;
- script-src 'self' 'unsafe-eval' 'sha256-75NYUUvf+5++1WbfCZOV3PSWxBhONpaxwx+mkOFRv/Y=' https:;
+ script-src 'self' 'unsafe-eval' 'sha256-c7vPrYRaSLDtFSrI4CuHYgBQ3a4c4x2LSm/LefSZADQ=' https:;
connect-src 'self' https: wss: http://localhost:* http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:*;"/>
</head>
<body>

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />

View File

@@ -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%;
}

View File

@@ -1,4 +1,4 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />

View File

@@ -4,6 +4,7 @@ export enum HttpCode {
NotFound = 404,
BadRequest = 400,
Unauthorized = 401,
Forbidden = 403,
LargePayload = 413,
ServerError = 500,
}
@@ -13,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
}

View File

@@ -9,9 +9,11 @@ import * as util from "../common/util"
import { DefaultedArgs } from "./cli"
import { disposer } from "./http"
import { isNodeJSErrnoException } from "./util"
import { EditorSessionManager, makeEditorSessionManagerServer } from "./vscodeSocket"
import { handleUpgrade } from "./wsRouter"
type ListenOptions = Pick<DefaultedArgs, "socket-mode" | "socket" | "port" | "host">
type SocketOptions = { socket: string; "socket-mode"?: string }
type ListenOptions = DefaultedArgs | SocketOptions
export interface App extends Disposable {
/** Handles regular HTTP requests. */
@@ -20,12 +22,18 @@ export interface App extends Disposable {
wsRouter: Express
/** The underlying HTTP server. */
server: http.Server
/** Handles requests to the editor session management API. */
editorSessionManagerServer: http.Server
}
export const listen = async (server: http.Server, { host, port, socket, "socket-mode": mode }: ListenOptions) => {
if (socket) {
const isSocketOpts = (opts: ListenOptions): opts is SocketOptions => {
return !!(opts as SocketOptions).socket || !(opts as DefaultedArgs).host
}
export const listen = async (server: http.Server, opts: ListenOptions) => {
if (isSocketOpts(opts)) {
try {
await fs.unlink(socket)
await fs.unlink(opts.socket)
} catch (error: any) {
handleArgsSocketCatchError(error)
}
@@ -38,18 +46,20 @@ export const listen = async (server: http.Server, { host, port, socket, "socket-
server.on("error", (err) => util.logError(logger, "http server error", err))
resolve()
}
if (socket) {
server.listen(socket, onListen)
if (isSocketOpts(opts)) {
server.listen(opts.socket, onListen)
} else {
// [] is the correct format when using :: but Node errors with them.
server.listen(port, host.replace(/^\[|\]$/g, ""), onListen)
server.listen(opts.port, opts.host.replace(/^\[|\]$/g, ""), onListen)
}
})
// NOTE@jsjoeio: we need to chmod after the server is finished
// listening. Otherwise, the socket may not have been created yet.
if (socket && mode) {
await fs.chmod(socket, mode)
if (isSocketOpts(opts)) {
if (opts["socket-mode"]) {
await fs.chmod(opts.socket, opts["socket-mode"])
}
}
}
@@ -70,14 +80,22 @@ export const createApp = async (args: DefaultedArgs): Promise<App> => {
)
: http.createServer(router)
const dispose = disposer(server)
const disposeServer = disposer(server)
await listen(server, args)
const wsRouter = express()
handleUpgrade(wsRouter, server)
return { router, wsRouter, server, dispose }
const editorSessionManager = new EditorSessionManager()
const editorSessionManagerServer = await makeEditorSessionManagerServer(args["session-socket"], editorSessionManager)
const disposeEditorSessionManagerServer = disposer(editorSessionManagerServer)
const dispose = async () => {
await Promise.all([disposeServer(), disposeEditorSessionManagerServer()])
}
return { router, wsRouter, server, dispose, editorSessionManagerServer }
}
/**

View File

@@ -1,11 +1,9 @@
import { field, Level, logger } from "@coder/logger"
import { promises as fs } from "fs"
import { load } from "js-yaml"
import * as os from "os"
import * as path from "path"
import { canConnect, generateCertificate, generatePassword, humanPath, paths, isNodeJSErrnoException } from "./util"
const DEFAULT_SOCKET_PATH = path.join(os.tmpdir(), "vscode-ipc")
import { generateCertificate, generatePassword, paths, splitOnFirstEquals } from "./util"
import { EditorSessionManagerClient } from "./vscodeSocket"
export enum Feature {
// No current experimental features!
@@ -50,8 +48,11 @@ export interface UserProvidedCodeArgs {
"github-auth"?: string
"disable-update-check"?: boolean
"disable-file-downloads"?: boolean
"disable-file-uploads"?: boolean
"disable-workspace-trust"?: boolean
"disable-getting-started-override"?: boolean
"disable-proxy"?: boolean
"session-socket"?: string
}
/**
@@ -79,6 +80,7 @@ export interface UserProvidedArgs extends UserProvidedCodeArgs {
"bind-addr"?: string
socket?: string
"socket-mode"?: string
"trusted-origins"?: string[]
version?: boolean
"proxy-domain"?: string[]
"reuse-window"?: boolean
@@ -161,11 +163,18 @@ export const options: Options<Required<UserProvidedArgs>> = {
"Disable update check. Without this flag, code-server checks every 6 hours against the latest github release and \n" +
"then notifies you once every week that a new release is available.",
},
"session-socket": {
type: "string",
},
"disable-file-downloads": {
type: "boolean",
description:
"Disable file downloads from Code. This can also be set with CS_DISABLE_FILE_DOWNLOADS set to 'true' or '1'.",
},
"disable-file-uploads": {
type: "boolean",
description: "Disable file uploads.",
},
"disable-workspace-trust": {
type: "boolean",
description: "Disable Workspace Trust feature. This switch only affects the current session.",
@@ -174,6 +183,10 @@ export const options: Options<Required<UserProvidedArgs>> = {
type: "boolean",
description: "Disable the coder/coder override in the Help: Getting Started page.",
},
"disable-proxy": {
type: "boolean",
description: "Disable domain and path proxy routes.",
},
// --enable can be used to enable experimental features. These features
// provide no guarantees.
enable: { type: "string[]" },
@@ -205,6 +218,11 @@ export const options: Options<Required<UserProvidedArgs>> = {
socket: { type: "string", path: true, description: "Path to a socket (bind-addr will be ignored)." },
"socket-mode": { type: "string", description: "File mode of the socket." },
"trusted-origins": {
type: "string[]",
description:
"Disables authenticate origin check for trusted origin. Useful if not able to access reverse proxy configuration.",
},
version: { type: "boolean", short: "v", description: "Display version information." },
_: { type: "string[]" },
@@ -292,19 +310,6 @@ export const optionDescriptions = (opts: Partial<Options<Required<UserProvidedAr
})
}
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
// We use the ? to say the the substr after the = is optional
const split = str.split(/=(.+)?/, 2)
return split
}
/**
* Parse arguments into UserProvidedArgs. This should not go beyond checking
* that arguments are valid types and have values when required.
@@ -438,19 +443,23 @@ export const parse = (
throw new Error("--cert-key is missing")
}
logger.debug(() => [
`parsed ${opts?.configFile ? "config" : "command line"}`,
field("args", {
...args,
password: args.password ? "<redacted>" : undefined,
"hashed-password": args["hashed-password"] ? "<redacted>" : undefined,
"github-auth": args["github-auth"] ? "<redacted>" : undefined,
}),
])
logger.debug(() => [`parsed ${opts?.configFile ? "config" : "command line"}`, field("args", redactArgs(args))])
return args
}
/**
* Redact sensitive information from arguments for logging.
*/
export const redactArgs = (args: UserProvidedArgs): UserProvidedArgs => {
return {
...args,
password: args.password ? "<redacted>" : undefined,
"hashed-password": args["hashed-password"] ? "<redacted>" : undefined,
"github-auth": args["github-auth"] ? "<redacted>" : undefined,
}
}
/**
* User-provided arguments with defaults. The distinction between user-provided
* args and defaulted args exists so we can tell the difference between end
@@ -469,6 +478,7 @@ export interface DefaultedArgs extends ConfigArgs {
usingEnvHashedPassword: boolean
"extensions-dir": string
"user-data-dir": string
"session-socket": string
/* Positional arguments. */
_: string[]
}
@@ -489,6 +499,11 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
args["extensions-dir"] = path.join(args["user-data-dir"], "extensions")
}
if (!args["session-socket"]) {
args["session-socket"] = path.join(args["user-data-dir"], "code-server-ipc.sock")
}
process.env.CODE_SERVER_SESSION_SOCKET = args["session-socket"]
// --verbose takes priority over --log and --log takes priority over the
// environment variable.
if (args.verbose) {
@@ -558,6 +573,10 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
args["disable-getting-started-override"] = true
}
if (process.env.CS_DISABLE_PROXY?.match(/^(1|true)$/)) {
args["disable-proxy"] = true
}
const usingEnvHashedPassword = !!process.env.HASHED_PASSWORD
if (process.env.HASHED_PASSWORD) {
args["hashed-password"] = process.env.HASHED_PASSWORD
@@ -575,12 +594,25 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
// Filter duplicate proxy domains and remove any leading `*.`.
const proxyDomains = new Set((args["proxy-domain"] || []).map((d) => d.replace(/^\*\./, "")))
args["proxy-domain"] = Array.from(proxyDomains)
const finalProxies = []
if (typeof args._ === "undefined") {
args._ = []
for (const proxyDomain of proxyDomains) {
if (!proxyDomain.includes("{{port}}")) {
finalProxies.push("{{port}}." + proxyDomain)
} else {
finalProxies.push(proxyDomain)
}
}
// all proxies are of format anyprefix-{{port}}-anysuffix.{{host}}, where {{host}} is optional
// e.g. code-8080.domain.tld would match for code-{{port}}.domain.tld and code-{{port}}.{{host}}
if (finalProxies.length > 0 && !process.env.VSCODE_PROXY_URI) {
process.env.VSCODE_PROXY_URI = `//${finalProxies[0]}`
}
args["proxy-domain"] = finalProxies
args._ = getResolvedPathsFromArgs(args)
return {
...args,
usingEnvPassword,
@@ -588,6 +620,10 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
} as DefaultedArgs // TODO: Technically no guarantee this is fulfilled.
}
export function getResolvedPathsFromArgs(args: UserProvidedArgs): string[] {
return (args._ ?? []).map((p) => path.resolve(p))
}
/**
* Helper function to return the default config file.
*
@@ -631,7 +667,7 @@ export async function readConfigFile(configPath?: string): Promise<ConfigArgs> {
await fs.writeFile(configPath, defaultConfigFile(generatedPassword), {
flag: "wx", // wx means to fail if the path exists.
})
logger.info(`Wrote default config file to ${humanPath(os.homedir(), configPath)}`)
logger.info(`Wrote default config file to ${configPath}`)
} catch (error: any) {
// EEXIST is fine; we don't want to overwrite existing configurations.
if (error.code !== "EEXIST") {
@@ -701,6 +737,9 @@ export function bindAddrFromArgs(addr: Addr, args: UserProvidedArgs): Addr {
if (args["bind-addr"]) {
addr = parseBindAddr(args["bind-addr"])
}
if (process.env.CODE_SERVER_HOST) {
addr.host = process.env.CODE_SERVER_HOST
}
if (args.host) {
addr.host = args.host
}
@@ -727,47 +766,38 @@ function bindAddrFromAllSources(...argsConfig: UserProvidedArgs[]): Addr {
return addr
}
/**
* Reads the socketPath based on path passed in.
*
* The one usually passed in is the DEFAULT_SOCKET_PATH.
*
* If it can't read the path, it throws an error and returns undefined.
*/
export async function readSocketPath(path: string): Promise<string | undefined> {
try {
return await fs.readFile(path, "utf8")
} catch (error) {
// If it doesn't exist, we don't care.
// But if it fails for some reason, we should throw.
// We want to surface that to the user.
if (!isNodeJSErrnoException(error) || error.code !== "ENOENT") {
throw error
}
}
return undefined
}
/**
* Determine if it looks like the user is trying to open a file or folder in an
* existing instance. The arguments here should be the arguments the user
* explicitly passed on the command line, *NOT DEFAULTS* or the configuration.
*/
export const shouldOpenInExistingInstance = async (args: UserProvidedArgs): Promise<string | undefined> => {
export const shouldOpenInExistingInstance = async (
args: UserProvidedArgs,
sessionSocket: string,
): Promise<string | undefined> => {
// Always use the existing instance if we're running from VS Code's terminal.
if (process.env.VSCODE_IPC_HOOK_CLI) {
logger.debug("Found VSCODE_IPC_HOOK_CLI")
return process.env.VSCODE_IPC_HOOK_CLI
}
const paths = getResolvedPathsFromArgs(args)
const client = new EditorSessionManagerClient(sessionSocket)
// If these flags are set then assume the user is trying to open in an
// existing instance since these flags have no effect otherwise.
// existing instance since these flags have no effect otherwise. That means
// if there is no existing instance we should error rather than falling back
// to spawning code-server normally.
const openInFlagCount = ["reuse-window", "new-window"].reduce((prev, cur) => {
return args[cur as keyof UserProvidedArgs] ? prev + 1 : prev
}, 0)
if (openInFlagCount > 0) {
logger.debug("Found --reuse-window or --new-window")
return readSocketPath(DEFAULT_SOCKET_PATH)
const socketPath = await client.getConnectedSocketPath(paths[0])
if (!socketPath) {
throw new Error(`No opened code-server instances found to handle ${paths[0]}`)
}
return socketPath
}
// It's possible the user is trying to spawn another instance of code-server.
@@ -775,9 +805,13 @@ export const shouldOpenInExistingInstance = async (args: UserProvidedArgs): Prom
// code-server is invoked exactly like this: `code-server my-file`).
// 2. That a file or directory was passed.
// 3. That the socket is active.
// 4. That an instance exists to handle the path (implied by #3).
if (Object.keys(args).length === 1 && typeof args._ !== "undefined" && args._.length > 0) {
const socketPath = await readSocketPath(DEFAULT_SOCKET_PATH)
if (socketPath && (await canConnect(socketPath))) {
if (!(await client.canConnect())) {
return undefined
}
const socketPath = await client.getConnectedSocketPath(paths[0])
if (socketPath) {
logger.debug("Found existing code-server socket")
return socketPath
}
@@ -799,8 +833,8 @@ export interface CodeArgs extends UserProvidedCodeArgs {
version: boolean
"without-connection-token"?: boolean
"without-browser-env-var"?: boolean
compatibility: string
log: string[] | undefined
compatibility?: string
log?: string[]
}
/**
@@ -809,15 +843,12 @@ export interface CodeArgs extends UserProvidedCodeArgs {
export type SpawnCodeCli = (args: CodeArgs) => Promise<void>
/**
* Convert our arguments to VS Code server arguments.
* Convert our arguments to equivalent VS Code server arguments.
* Does not add any extra arguments.
*/
export const toCodeArgs = async (args: DefaultedArgs): Promise<CodeArgs> => {
return {
...args,
"accept-server-license-terms": true,
// This seems to be used to make the connection token flags optional (when
// set to 1.63) but we have always included them.
compatibility: "1.64",
/** Type casting. */
help: !!args.help,
version: !!args.version,

View File

@@ -51,7 +51,7 @@ async function entry(): Promise<void> {
return runCodeCli(args)
}
const socketPath = await shouldOpenInExistingInstance(cliArgs)
const socketPath = await shouldOpenInExistingInstance(cliArgs, args["session-socket"])
if (socketPath) {
logger.debug("Trying to open in existing instance")
return openInExistingInstance(args, socketPath)

View File

@@ -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)
}
@@ -28,7 +31,7 @@ export class Heart {
return
}
logger.trace("heartbeat")
logger.debug("heartbeat")
this.lastHeartbeat = Date.now()
if (typeof this.heartbeatTimer !== "undefined") {
clearTimeout(this.heartbeatTimer)

View File

@@ -12,7 +12,15 @@ import { version as codeServerVersion } from "./constants"
import { Heart } from "./heart"
import { CoderSettings, SettingsProvider } from "./settings"
import { UpdateProvider } from "./update"
import { getPasswordMethod, IsCookieValidArgs, isCookieValid, sanitizeString, escapeHtml, escapeJSON } from "./util"
import {
getPasswordMethod,
IsCookieValidArgs,
isCookieValid,
sanitizeString,
escapeHtml,
escapeJSON,
splitOnFirstEquals,
} from "./util"
/**
* Base options included on every page.
@@ -67,6 +75,25 @@ export const replaceTemplates = <T extends object>(
.replace("{{OPTIONS}}", () => escapeJSON(serverOptions))
}
/**
* Throw an error if proxy is not enabled. Call `next` if provided.
*/
export const ensureProxyEnabled = (req: express.Request, _?: express.Response, next?: express.NextFunction): void => {
if (!proxyEnabled(req)) {
throw new HttpError("Forbidden", HttpCode.Forbidden)
}
if (next) {
next()
}
}
/**
* Return true if proxy is enabled.
*/
export const proxyEnabled = (req: express.Request): boolean => {
return !req.args["disable-proxy"]
}
/**
* Throw an error if not authorized. Call `next` if provided.
*/
@@ -292,8 +319,8 @@ export const getCookieOptions = (req: express.Request): express.CookieOptions =>
// URL of that page) and the relative path to the root as given to it by the
// backend. Using these two we can determine the true absolute root.
const url = new URL(
req.query.base || req.body.base || "/",
req.query.href || req.body.href || "http://" + (req.headers.host || "localhost"),
req.query.base || req.body?.base || "/",
req.query.href || req.body?.href || "http://" + (req.headers.host || "localhost"),
)
return {
domain: getCookieDomain(url.host, req.args["proxy-domain"]),
@@ -308,3 +335,91 @@ export const getCookieOptions = (req: express.Request): express.CookieOptions =>
export const self = (req: express.Request): string => {
return normalize(`${req.baseUrl}${req.originalUrl.endsWith("/") ? "/" : ""}`, true)
}
function getFirstHeader(req: http.IncomingMessage, headerName: string): string | undefined {
const val = req.headers[headerName]
return Array.isArray(val) ? val[0] : val
}
/**
* Throw a forbidden error if origin checks fail. Call `next` if provided.
*/
export function ensureOrigin(req: express.Request, _?: express.Response, next?: express.NextFunction): void {
try {
authenticateOrigin(req)
if (next) {
next()
}
} catch (error) {
logger.debug(`${error instanceof Error ? error.message : error}; blocking request to ${req.originalUrl}`)
throw new HttpError("Forbidden", HttpCode.Forbidden)
}
}
/**
* Authenticate the request origin against the host. Throw if invalid.
*/
export function authenticateOrigin(req: express.Request): void {
// A missing origin probably means the source is non-browser. Not sure we
// have a use case for this but let it through.
const originRaw = getFirstHeader(req, "origin")
if (!originRaw) {
return
}
let origin: string
try {
origin = new URL(originRaw).host.trim().toLowerCase()
} catch (error) {
throw new Error(`unable to parse malformed origin "${originRaw}"`)
}
const trustedOrigins = req.args["trusted-origins"] || []
if (trustedOrigins.includes(origin) || trustedOrigins.includes("*")) {
return
}
const host = getHost(req)
if (typeof host === "undefined") {
// A missing host likely means the reverse proxy has not been configured to
// forward the host which means we cannot perform the check. Emit an error
// so an admin can fix the issue.
logger.error("No host headers found")
logger.error("Are you behind a reverse proxy that does not forward the host?")
throw new Error("no host headers found")
}
if (host !== origin) {
throw new Error(`host "${host}" does not match origin "${origin}"`)
}
}
/**
* Get the host from headers. It will be trimmed and lowercased.
*/
export function getHost(req: express.Request): string | undefined {
// Honor Forwarded if present.
const forwardedRaw = getFirstHeader(req, "forwarded")
if (forwardedRaw) {
const parts = forwardedRaw.split(/[;,]/)
for (let i = 0; i < parts.length; ++i) {
const [key, value] = splitOnFirstEquals(parts[i])
if (key.trim().toLowerCase() === "host" && value) {
return value.trim().toLowerCase()
}
}
}
// Honor X-Forwarded-Host if present. Some reverse proxies will set multiple
// comma-separated hosts.
const xHost = getFirstHeader(req, "x-forwarded-host")
if (xHost) {
const firstXHost = xHost.split(",")[0]
if (firstXHost) {
return firstXHost.trim().toLowerCase()
}
}
const host = getFirstHeader(req, "host")
return host ? host.trim().toLowerCase() : undefined
}

View File

@@ -1,5 +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 ur from "./locales/ur.json"
import * as zhCn from "./locales/zh-cn.json"
init({
@@ -15,6 +18,15 @@ init({
"zh-cn": {
translation: zhCn,
},
th: {
translation: th,
},
ja: {
translation: ja,
},
ur: {
translation: ur,
},
},
})

View File

@@ -0,0 +1,13 @@
{
"LOGIN_TITLE": "{{app}} ログイン",
"LOGIN_BELOW": "以下によりログインしてください。",
"WELCOME": "ようこそ {{app}} へ!",
"LOGIN_PASSWORD": "パスワードは設定ファイル( {{configFile}} )を確認してください。",
"LOGIN_USING_ENV_PASSWORD": "パスワードは環境変数 $PASSWORD で設定されています。",
"LOGIN_USING_HASHED_PASSWORD": "パスワードは環境変数 $HASHED_PASSWORD で設定されています。",
"SUBMIT": "実行",
"PASSWORD_PLACEHOLDER": "パスワード",
"LOGIN_RATE_LIMIT": "ログイン制限を超えました!",
"MISS_PASSWORD": "パスワードを入力してください。",
"INCORRECT_PASSWORD": "パスワードが間違っています。"
}

View File

@@ -0,0 +1,13 @@
{
"LOGIN_TITLE": "เข้าสู่ระบบ {{app}}",
"LOGIN_BELOW": "กรุณาเข้าสู่ระบบด้านล่าง",
"WELCOME": "ยินดีต้อนรับสู่ {{app}}",
"LOGIN_PASSWORD": "ตรวจสอบไฟล์กำหนดค่าที่ {{configFile}} เพื่อดูรหัสผ่าน",
"LOGIN_USING_ENV_PASSWORD": "รหัสผ่านถูกกำหนดเป็น $PASSWORD",
"LOGIN_USING_HASHED_PASSWORD": "รรหัสผ่านถูกกำหนดเป็น $HASHED_PASSWORD",
"SUBMIT": "ส่ง",
"PASSWORD_PLACEHOLDER": "รหัสผ่าน",
"LOGIN_RATE_LIMIT": "ถึงขีดจำกัดอัตราการเข้าสู่ระบบ!",
"MISS_PASSWORD": "รหัสผ่านหายไป",
"INCORRECT_PASSWORD": "รหัสผ่านไม่ถูกต้อง"
}

View File

@@ -0,0 +1,13 @@
{
"LOGIN_TITLE": "{{app}} لاگ ان کریں",
"LOGIN_BELOW": "براہ کرم نیچے لاگ ان کریں۔",
"WELCOME": "میں خوش آمدید {{app}}",
"LOGIN_PASSWORD": "پاس ورڈ کے لیے {{configFile}} پر کنفگ فائل چیک کریں۔",
"LOGIN_USING_ENV_PASSWORD": "پاس ورڈ $PASSWORD سے سیٹ کیا گیا تھا۔",
"LOGIN_USING_HASHED_PASSWORD": "پاس ورڈ $HASHED_PASSWORD سے سیٹ کیا گیا تھا۔",
"SUBMIT": "جمع کرائیں",
"PASSWORD_PLACEHOLDER": "پاس ورڈ",
"LOGIN_RATE_LIMIT": "لاگ ان کی شرح محدود!",
"MISS_PASSWORD": "پاس ورڈ غائب ہے۔",
"INCORRECT_PASSWORD": "غلط پاس ورڈ"
}

View File

@@ -1,14 +1,12 @@
import { field, logger } from "@coder/logger"
import http from "http"
import * as os from "os"
import path from "path"
import { Disposable } from "../common/emitter"
import { plural } from "../common/util"
import { createApp, ensureAddress } from "./app"
import { AuthType, DefaultedArgs, Feature, SpawnCodeCli, toCodeArgs, UserProvidedArgs } from "./cli"
import { commit, version } from "./constants"
import { register } from "./routes"
import { humanPath, isDirectory, loadAMDModule, open } from "./util"
import { isDirectory, loadAMDModule, open } from "./util"
/**
* Return true if the user passed an extension-related VS Code flag.
@@ -54,11 +52,17 @@ export const runCodeCli = async (args: DefaultedArgs): Promise<void> => {
try {
await spawnCli(await toCodeArgs(args))
// Rather than have the caller handle errors and exit, spawnCli will exit
// itself. Additionally, it does this on a timeout set to 0. So, try
// waiting for VS Code to exit before giving up and doing it ourselves.
await new Promise((r) => setTimeout(r, 1000))
logger.warn("Code never exited")
process.exit(0)
} catch (error: any) {
// spawnCli catches all errors, but just in case that changes.
logger.error("Got error from Code", error)
process.exit(1)
}
process.exit(0)
}
export const openInExistingInstance = async (args: DefaultedArgs, socketPath: string): Promise<void> => {
@@ -70,9 +74,8 @@ export const openInExistingInstance = async (args: DefaultedArgs, socketPath: st
forceNewWindow: args["new-window"],
gotoLineMode: true,
}
const paths = args._ || []
for (let i = 0; i < paths.length; i++) {
const fp = path.resolve(paths[i])
for (let i = 0; i < args._.length; i++) {
const fp = args._[i]
if (await isDirectory(fp)) {
pipeArgs.folderURIs.push(fp)
} else {
@@ -111,8 +114,8 @@ export const runCodeServer = async (
): Promise<{ dispose: Disposable["dispose"]; server: http.Server }> => {
logger.info(`code-server ${version} ${commit}`)
logger.info(`Using user-data-dir ${humanPath(os.homedir(), args["user-data-dir"])}`)
logger.trace(`Using extensions-dir ${humanPath(os.homedir(), args["extensions-dir"])}`)
logger.info(`Using user-data-dir ${args["user-data-dir"]}`)
logger.debug(`Using extensions-dir ${args["extensions-dir"]}`)
if (args.auth === AuthType.Password && !args.password && !args["hashed-password"]) {
throw new Error(
@@ -125,9 +128,8 @@ export const runCodeServer = async (
const serverAddress = ensureAddress(app.server, protocol)
const disposeRoutes = await register(app, args)
logger.info(`Using config file ${humanPath(os.homedir(), args.config)}`)
logger.info(`Using config file ${args.config}`)
logger.info(`${protocol.toUpperCase()} server listening on ${serverAddress.toString()}`)
if (args.auth === AuthType.Password) {
logger.info(" - Authentication is enabled")
if (args.usingEnvPassword) {
@@ -135,21 +137,31 @@ export const runCodeServer = async (
} else if (args.usingEnvHashedPassword) {
logger.info(" - Using password from $HASHED_PASSWORD")
} else {
logger.info(` - Using password from ${humanPath(os.homedir(), args.config)}`)
logger.info(` - Using password from ${args.config}`)
}
} else {
logger.info(" - Authentication is disabled")
}
if (args.cert) {
logger.info(` - Using certificate for HTTPS: ${humanPath(os.homedir(), args.cert.value)}`)
logger.info(` - Using certificate for HTTPS: ${args.cert.value}`)
} else {
logger.info(" - Not serving HTTPS")
}
if (args["proxy-domain"].length > 0) {
if (args["disable-proxy"]) {
logger.info(" - Proxy disabled")
} else if (args["proxy-domain"].length > 0) {
logger.info(` - ${plural(args["proxy-domain"].length, "Proxying the following domain")}:`)
args["proxy-domain"].forEach((domain) => logger.info(` - *.${domain}`))
args["proxy-domain"].forEach((domain) => logger.info(` - ${domain}`))
}
if (process.env.VSCODE_PROXY_URI) {
logger.info(`Using proxy URI in PORTS tab: ${process.env.VSCODE_PROXY_URI}`)
}
const sessionServerAddress = app.editorSessionManagerServer.address()
if (sessionServerAddress) {
logger.info(`Session server listening on ${sessionServerAddress.toString()}`)
}
if (args.enable && args.enable.length > 0) {

View File

@@ -3,9 +3,19 @@ import { HttpCode } from "../common/http"
export const proxy = proxyServer.createProxyServer({})
// The error handler catches when the proxy fails to connect (for example when
// there is nothing running on the target port).
proxy.on("error", (error, _, res) => {
res.writeHead(HttpCode.ServerError)
res.end(error.message)
// This could be for either a web socket or a regular request. Despite what
// the types say, writeHead() will not exist on web socket requests (nor will
// status() from Express). But writing out the code manually does not work
// for regular requests thus the branching behavior.
if (typeof res.writeHead !== "undefined") {
res.writeHead(HttpCode.ServerError)
res.end(error.message)
} else {
res.end(`HTTP/1.1 ${HttpCode.ServerError} ${error.message}\r\n\r\n`)
}
})
// Intercept the response to rewrite absolute redirects against the base path.

View File

@@ -1,42 +1,66 @@
import { Request, Router } from "express"
import { HttpCode, HttpError } from "../../common/http"
import { authenticated, ensureAuthenticated, redirect, self } from "../http"
import { getHost, ensureProxyEnabled, authenticated, ensureAuthenticated, ensureOrigin, redirect, self } from "../http"
import { proxy } from "../proxy"
import { Router as WsRouter } from "../wsRouter"
export const router = Router()
const proxyDomainToRegex = (matchString: string): RegExp => {
const escapedMatchString = matchString.replace(/[.*+?^$()|[\]\\]/g, "\\$&")
// Replace {{port}} with a regex group to capture the port
// Replace {{host}} with .+ to allow any host match (so rely on DNS record here)
let regexString = escapedMatchString.replace("{{port}}", "(\\d+)")
regexString = regexString.replace("{{host}}", ".+")
regexString = regexString.replace(/[{}]/g, "\\$&") //replace any '{}' that might be left
return new RegExp("^" + regexString + "$")
}
let proxyRegexes: RegExp[] = []
const proxyDomainsToRegex = (proxyDomains: string[]): RegExp[] => {
if (proxyDomains.length !== proxyRegexes.length) {
proxyRegexes = proxyDomains.map(proxyDomainToRegex)
}
return proxyRegexes
}
/**
* Return the port if the request should be proxied. Anything that ends in a
* proxy domain and has a *single* subdomain should be proxied. Anything else
* should return `undefined` and will be handled as normal.
* Return the port if the request should be proxied.
*
* The proxy-domain should be of format anyprefix-{{port}}-anysuffix.{{host}}, where {{host}} is optional
* e.g. code-8080.domain.tld would match for code-{{port}}.domain.tld and code-{{port}}.{{host}}.
*
* For example if `coder.com` is specified `8080.coder.com` will be proxied
* but `8080.test.coder.com` and `test.8080.coder.com` will not.
*/
const maybeProxy = (req: Request): string | undefined => {
// Split into parts.
const host = req.headers.host || ""
const idx = host.indexOf(":")
const domain = idx !== -1 ? host.substring(0, idx) : host
const parts = domain.split(".")
// There must be an exact match.
const port = parts.shift()
const proxyDomain = parts.join(".")
if (!port || !req.args["proxy-domain"].includes(proxyDomain)) {
const reqDomain = getHost(req)
if (reqDomain === undefined) {
return undefined
}
return port
const regexs = proxyDomainsToRegex(req.args["proxy-domain"])
for (const regex of regexs) {
const match = reqDomain.match(regex)
if (match) {
return match[1] // match[1] contains the port
}
}
return undefined
}
router.all("*", async (req, res, next) => {
router.all(/.*/, async (req, res, next) => {
const port = maybeProxy(req)
if (!port) {
return next()
}
ensureProxyEnabled(req)
// Must be authenticated to use the proxy.
const isAuthenticated = await authenticated(req)
if (!isAuthenticated) {
@@ -73,15 +97,15 @@ router.all("*", async (req, res, next) => {
export const wsRouter = WsRouter()
wsRouter.ws("*", async (req, _, next) => {
wsRouter.ws(/.*/, async (req, _, next) => {
const port = maybeProxy(req)
if (!port) {
return next()
}
// Must be authenticated to use the proxy.
ensureProxyEnabled(req)
ensureOrigin(req)
await ensureAuthenticated(req)
proxy.ws(req, req.ws, req.head, {
ignorePath: true,
target: `http://0.0.0.0:${port}${req.originalUrl}`,

View File

@@ -62,6 +62,16 @@ export const errorHandler: express.ErrorRequestHandler = async (err, req, res, n
}
export const wsErrorHandler: express.ErrorRequestHandler = async (err, req, res, next) => {
logger.error(`${err.message} ${err.stack}`)
;(req as WebsocketRequest).ws.end()
let statusCode = 500
if (errorHasStatusCode(err)) {
statusCode = err.statusCode
} else if (errorHasCode(err) && notFoundCodes.includes(err.code)) {
statusCode = HttpCode.NotFound
}
if (statusCode >= 500) {
logger.error(`${err.message} ${err.stack}`)
} else {
logger.debug(`${err.message} ${err.stack}`)
}
;(req as WebsocketRequest).ws.end(`HTTP/1.1 ${statusCode} ${err.message}\r\n\r\n`)
}

View File

@@ -25,7 +25,7 @@ import * as login from "./login"
import * as logout from "./logout"
import * as pathProxy from "./pathProxy"
import * as update from "./update"
import { CodeServerRouteWrapper } from "./vscode"
import * as vscode from "./vscode"
/**
* Register all routes and middleware.
@@ -109,21 +109,21 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
app.router.use("/", domainProxy.router)
app.wsRouter.use("/", domainProxy.wsRouter.router)
app.router.all("/proxy/(:port)(/*)?", async (req, res) => {
app.router.all("/proxy/:port/:path(.*)?", async (req, res) => {
await pathProxy.proxy(req, res)
})
app.wsRouter.get("/proxy/(:port)(/*)?", async (req) => {
app.wsRouter.get("/proxy/:port/:path(.*)?", async (req) => {
await pathProxy.wsProxy(req as pluginapi.WebsocketRequest)
})
// These two routes pass through the path directly.
// So the proxied app must be aware it is running
// under /absproxy/<someport>/
app.router.all("/absproxy/(:port)(/*)?", async (req, res) => {
app.router.all("/absproxy/:port/:path(.*)?", async (req, res) => {
await pathProxy.proxy(req, res, {
passthroughPath: true,
})
})
app.wsRouter.get("/absproxy/(:port)(/*)?", async (req) => {
app.wsRouter.get("/absproxy/:port/:path(.*)?", async (req) => {
await pathProxy.wsProxy(req as pluginapi.WebsocketRequest, {
passthroughPath: true,
})
@@ -170,12 +170,10 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
app.router.use("/update", update.router)
const vsServerRouteHandler = new CodeServerRouteWrapper()
// Note that the root route is replaced in Coder Enterprise by the plugin API.
for (const routePrefix of ["/vscode", "/"]) {
app.router.use(routePrefix, vsServerRouteHandler.router)
app.wsRouter.use(routePrefix, vsServerRouteHandler.wsRouter)
app.router.use(routePrefix, vscode.router)
app.wsRouter.use(routePrefix, vscode.wsRouter.router)
}
app.router.use(() => {
@@ -188,6 +186,6 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
return () => {
heart.dispose()
pluginApi?.dispose()
vsServerRouteHandler.dispose()
vscode.dispose()
}
}

View File

@@ -1,13 +1,12 @@
import { Router, Request } from "express"
import { promises as fs } from "fs"
import { RateLimiter as Limiter } from "limiter"
import * as os from "os"
import * as path from "path"
import { CookieKeys } from "../../common/http"
import { rootPath } from "../constants"
import { authenticated, getCookieOptions, redirect, replaceTemplates } from "../http"
import { getPasswordMethod, handlePasswordValidation, humanPath, sanitizeString, escapeHtml } from "../util"
import i18n from "../i18n"
import { getPasswordMethod, handlePasswordValidation, sanitizeString, escapeHtml } from "../util"
// RateLimiter wraps around the limiter library for logins.
// It allows 2 logins every minute plus 12 logins every hour.
@@ -33,7 +32,7 @@ const getRoot = async (req: Request, error?: Error): Promise<string> => {
i18n.changeLanguage(locale)
const appName = req.args["app-name"] || "code-server"
const welcomeText = req.args["welcome-text"] || (i18n.t("WELCOME", { app: appName }) as string)
let passwordMsg = i18n.t("LOGIN_PASSWORD", { configFile: humanPath(os.homedir(), req.args.config) })
let passwordMsg = i18n.t("LOGIN_PASSWORD", { configFile: req.args.config })
if (req.args.usingEnvPassword) {
passwordMsg = i18n.t("LOGIN_USING_ENV_PASSWORD")
} else if (req.args.usingEnvHashedPassword) {
@@ -69,8 +68,8 @@ router.get("/", async (req, res) => {
res.send(await getRoot(req))
})
router.post<{}, string, { password: string; base?: string }, { to?: string }>("/", async (req, res) => {
const password = sanitizeString(req.body.password)
router.post<{}, string, { password?: string; base?: string } | undefined, { to?: string }>("/", async (req, res) => {
const password = sanitizeString(req.body?.password)
const hashedPasswordFromArgs = req.args["hashed-password"]
try {

View File

@@ -1,17 +1,14 @@
import { Request, Response } from "express"
import * as path from "path"
import * as qs from "qs"
import * as pluginapi from "../../../typings/pluginapi"
import { HttpCode, HttpError } from "../../common/http"
import { authenticated, ensureAuthenticated, redirect, self } from "../http"
import { ensureProxyEnabled, authenticated, ensureAuthenticated, ensureOrigin, redirect, self } from "../http"
import { proxy as _proxy } from "../proxy"
const getProxyTarget = (req: Request, passthroughPath?: boolean): string => {
if (passthroughPath) {
return `http://0.0.0.0:${req.params.port}/${req.originalUrl}`
}
const query = qs.stringify(req.query)
return `http://0.0.0.0:${req.params.port}/${req.params[0] || ""}${query ? `?${query}` : ""}`
const getProxyTarget = (req: Request): string => {
// If there is a base path, strip it out.
const base = (req as any).base || ""
return `http://0.0.0.0:${req.params.port}/${req.originalUrl.slice(base.length)}`
}
export async function proxy(
@@ -21,9 +18,11 @@ export async function proxy(
passthroughPath?: boolean
},
): Promise<void> {
ensureProxyEnabled(req)
if (!(await authenticated(req))) {
// If visiting the root (/:port only) redirect to the login page.
if (!req.params[0] || req.params[0] === "/") {
if (!req.params.path || req.params.path === "/") {
const to = self(req)
return redirect(req, res, "login", {
to: to !== "/" ? to : undefined,
@@ -32,15 +31,14 @@ export async function proxy(
throw new HttpError("Unauthorized", HttpCode.Unauthorized)
}
// The base is used for rewriting (redirects, target).
if (!opts?.passthroughPath) {
// Absolute redirects need to be based on the subpath when rewriting.
// See proxy.ts.
;(req as any).base = req.path.split(path.sep).slice(0, 3).join(path.sep)
}
_proxy.web(req, res, {
ignorePath: true,
target: getProxyTarget(req, opts?.passthroughPath),
target: getProxyTarget(req),
})
}
@@ -50,9 +48,17 @@ export async function wsProxy(
passthroughPath?: boolean
},
): Promise<void> {
ensureProxyEnabled(req)
ensureOrigin(req)
await ensureAuthenticated(req)
// The base is used for rewriting (redirects, target).
if (!opts?.passthroughPath) {
;(req as any).base = req.path.split(path.sep).slice(0, 3).join(path.sep)
}
_proxy.ws(req, req.ws, req.head, {
ignorePath: true,
target: getProxyTarget(req, opts?.passthroughPath),
target: getProxyTarget(req),
})
}

View File

@@ -1,5 +1,7 @@
import { logger } from "@coder/logger"
import * as crypto from "crypto"
import * as express from "express"
import { promises as fs } from "fs"
import * as http from "http"
import * as net from "net"
import * as path from "path"
@@ -7,177 +9,195 @@ import { WebsocketRequest } from "../../../typings/pluginapi"
import { logError } from "../../common/util"
import { CodeArgs, toCodeArgs } from "../cli"
import { isDevMode } from "../constants"
import { authenticated, ensureAuthenticated, redirect, replaceTemplates, self } from "../http"
import { authenticated, ensureAuthenticated, ensureOrigin, redirect, replaceTemplates, self } from "../http"
import { SocketProxyProvider } from "../socket"
import { isFile, loadAMDModule } from "../util"
import { Router as WsRouter } from "../wsRouter"
export const router = express.Router()
export const wsRouter = WsRouter()
/**
* This is the API of Code's web client server. code-server delegates requests
* to Code here.
* The API of VS Code's web client server. code-server delegates requests to VS
* Code here.
*
* @see ../../../lib/vscode/src/vs/server/node/server.main.ts:72
*/
export interface IServerAPI {
export interface IVSCodeServerAPI {
handleRequest(req: http.IncomingMessage, res: http.ServerResponse): Promise<void>
handleUpgrade(req: http.IncomingMessage, socket: net.Socket): void
handleServerError(err: Error): void
dispose(): void
}
// Types for ../../../lib/vscode/src/vs/server/node/server.main.ts:72.
export type CreateServer = (address: string | net.AddressInfo | null, args: CodeArgs) => Promise<IServerAPI>
// See ../../../lib/vscode/src/vs/server/node/server.main.ts:72.
export type CreateServer = (address: string | net.AddressInfo | null, args: CodeArgs) => Promise<IVSCodeServerAPI>
export class CodeServerRouteWrapper {
/** Assigned in `ensureCodeServerLoaded` */
private _codeServerMain!: IServerAPI
private _wsRouterWrapper = WsRouter()
private _socketProxyProvider = new SocketProxyProvider()
public router = express.Router()
public get wsRouter() {
return this._wsRouterWrapper.router
}
//#region Route Handlers
private manifest: express.Handler = async (req, res, next) => {
res.writeHead(200, { "Content-Type": "application/manifest+json" })
return res.end(
replaceTemplates(
req,
JSON.stringify(
{
name: "code-server",
short_name: "code-server",
start_url: ".",
display: "fullscreen",
description: "Run Code on a remote server.",
icons: [192, 512].map((size) => ({
src: `{{BASE}}/_static/src/browser/media/pwa-icon-${size}.png`,
type: "image/png",
sizes: `${size}x${size}`,
})),
},
null,
2,
),
),
)
}
private $root: express.Handler = async (req, res, next) => {
const isAuthenticated = await authenticated(req)
const NO_FOLDER_OR_WORKSPACE_QUERY = !req.query.folder && !req.query.workspace
// Ew means the workspace was closed so clear the last folder/workspace.
const FOLDER_OR_WORKSPACE_WAS_CLOSED = req.query.ew
if (!isAuthenticated) {
const to = self(req)
return redirect(req, res, "login", {
to: to !== "/" ? to : undefined,
})
}
if (NO_FOLDER_OR_WORKSPACE_QUERY && !FOLDER_OR_WORKSPACE_WAS_CLOSED) {
const settings = await req.settings.read()
const lastOpened = settings.query || {}
// This flag disables the last opened behavior
const IGNORE_LAST_OPENED = req.args["ignore-last-opened"]
const HAS_LAST_OPENED_FOLDER_OR_WORKSPACE = lastOpened.folder || lastOpened.workspace
const HAS_FOLDER_OR_WORKSPACE_FROM_CLI = req.args._.length > 0
const to = self(req)
let folder = undefined
let workspace = undefined
// Redirect to the last folder/workspace if nothing else is opened.
if (HAS_LAST_OPENED_FOLDER_OR_WORKSPACE && !IGNORE_LAST_OPENED) {
folder = lastOpened.folder
workspace = lastOpened.workspace
} else if (HAS_FOLDER_OR_WORKSPACE_FROM_CLI) {
const lastEntry = path.resolve(req.args._[req.args._.length - 1])
const entryIsFile = await isFile(lastEntry)
const IS_WORKSPACE_FILE = entryIsFile && path.extname(lastEntry) === ".code-workspace"
if (IS_WORKSPACE_FILE) {
workspace = lastEntry
} else if (!entryIsFile) {
folder = lastEntry
}
}
if (folder || workspace) {
return redirect(req, res, to, {
folder,
workspace,
})
}
}
// Store the query parameters so we can use them on the next load. This
// also allows users to create functionality around query parameters.
await req.settings.write({ query: req.query })
next()
}
private $proxyRequest: express.Handler = async (req, res, next) => {
this._codeServerMain.handleRequest(req, res)
}
private $proxyWebsocket = async (req: WebsocketRequest) => {
const wrappedSocket = await this._socketProxyProvider.createProxy(req.ws)
// This should actually accept a duplex stream but it seems Code has not
// been updated to match the Node 16 types so cast for now. There does not
// appear to be any code specific to sockets so this should be fine.
this._codeServerMain.handleUpgrade(req, wrappedSocket as net.Socket)
req.ws.resume()
}
//#endregion
/**
* Fetches a code server instance asynchronously to avoid an initial memory overhead.
*/
private ensureCodeServerLoaded: express.Handler = async (req, _res, next) => {
if (this._codeServerMain) {
// Already loaded...
return next()
}
// Create the server...
const { args } = req
// See ../../../lib/vscode/src/vs/server/node/server.main.ts:72.
const createVSServer = await loadAMDModule<CreateServer>("vs/server/node/server.main", "createServer")
try {
this._codeServerMain = await createVSServer(null, {
...(await toCodeArgs(args)),
"without-connection-token": true,
})
} catch (error) {
logError(logger, "CodeServerRouteWrapper", error)
if (isDevMode) {
return next(new Error((error instanceof Error ? error.message : error) + " (VS Code may still be compiling)"))
}
return next(error)
}
// The VS Code server is dynamically loaded in when a request is made to this
// router by `ensureCodeServerLoaded`.
let vscodeServer: IVSCodeServerAPI | undefined
/**
* Ensure the VS Code server is loaded.
*/
export const ensureVSCodeLoaded = async (
req: express.Request,
_: express.Response,
next: express.NextFunction,
): Promise<void> => {
if (vscodeServer) {
return next()
}
constructor() {
this.router.get("/", this.ensureCodeServerLoaded, this.$root)
this.router.get("/manifest.json", this.manifest)
this.router.all("*", ensureAuthenticated, this.ensureCodeServerLoaded, this.$proxyRequest)
this._wsRouterWrapper.ws("*", ensureAuthenticated, this.ensureCodeServerLoaded, this.$proxyWebsocket)
}
dispose() {
this._codeServerMain?.dispose()
this._socketProxyProvider.stop()
// See ../../../lib/vscode/src/vs/server/node/server.main.ts:72.
const createVSServer = await loadAMDModule<CreateServer>("vs/server/node/server.main", "createServer")
try {
vscodeServer = await createVSServer(null, {
...(await toCodeArgs(req.args)),
"accept-server-license-terms": true,
// This seems to be used to make the connection token flags optional (when
// set to 1.63) but we have always included them.
compatibility: "1.64",
"without-connection-token": true,
})
} catch (error) {
logError(logger, "CodeServerRouteWrapper", error)
if (isDevMode) {
return next(new Error((error instanceof Error ? error.message : error) + " (VS Code may still be compiling)"))
}
return next(error)
}
return next()
}
router.get("/", ensureVSCodeLoaded, async (req, res, next) => {
const isAuthenticated = await authenticated(req)
const NO_FOLDER_OR_WORKSPACE_QUERY = !req.query.folder && !req.query.workspace
// Ew means the workspace was closed so clear the last folder/workspace.
const FOLDER_OR_WORKSPACE_WAS_CLOSED = req.query.ew
if (!isAuthenticated) {
const to = self(req)
return redirect(req, res, "login", {
to: to !== "/" ? to : undefined,
})
}
if (NO_FOLDER_OR_WORKSPACE_QUERY && !FOLDER_OR_WORKSPACE_WAS_CLOSED) {
const settings = await req.settings.read()
const lastOpened = settings.query || {}
// This flag disables the last opened behavior
const IGNORE_LAST_OPENED = req.args["ignore-last-opened"]
const HAS_LAST_OPENED_FOLDER_OR_WORKSPACE = lastOpened.folder || lastOpened.workspace
const HAS_FOLDER_OR_WORKSPACE_FROM_CLI = req.args._.length > 0
const to = self(req)
let folder = undefined
let workspace = undefined
// Redirect to the last folder/workspace if nothing else is opened.
if (HAS_LAST_OPENED_FOLDER_OR_WORKSPACE && !IGNORE_LAST_OPENED) {
folder = lastOpened.folder
workspace = lastOpened.workspace
} else if (HAS_FOLDER_OR_WORKSPACE_FROM_CLI) {
const lastEntry = path.resolve(req.args._[req.args._.length - 1])
const entryIsFile = await isFile(lastEntry)
const IS_WORKSPACE_FILE = entryIsFile && path.extname(lastEntry) === ".code-workspace"
if (IS_WORKSPACE_FILE) {
workspace = lastEntry
} else if (!entryIsFile) {
folder = lastEntry
}
}
if (folder || workspace) {
return redirect(req, res, to, {
folder,
workspace,
})
}
}
// Store the query parameters so we can use them on the next load. This
// also allows users to create functionality around query parameters.
await req.settings.write({ query: req.query })
next()
})
router.get("/manifest.json", async (req, res) => {
const appName = req.args["app-name"] || "code-server"
res.writeHead(200, { "Content-Type": "application/manifest+json" })
return res.end(
replaceTemplates(
req,
JSON.stringify(
{
name: appName,
short_name: appName,
start_url: ".",
display: "fullscreen",
display_override: ["window-controls-overlay"],
description: "Run Code on a remote server.",
icons: [192, 512].map((size) => ({
src: `{{BASE}}/_static/src/browser/media/pwa-icon-${size}.png`,
type: "image/png",
sizes: `${size}x${size}`,
})),
},
null,
2,
),
),
)
})
let mintKeyPromise: Promise<Buffer> | undefined
router.post("/mint-key", async (req, res) => {
if (!mintKeyPromise) {
mintKeyPromise = new Promise(async (resolve) => {
const keyPath = path.join(req.args["user-data-dir"], "serve-web-key-half")
logger.debug(`Reading server web key half from ${keyPath}`)
try {
resolve(await fs.readFile(keyPath))
return
} catch (error: any) {
if (error.code !== "ENOENT") {
logError(logger, `read ${keyPath}`, error)
}
}
// VS Code wants 256 bits.
const key = crypto.randomBytes(32)
try {
await fs.writeFile(keyPath, key)
} catch (error: any) {
logError(logger, `write ${keyPath}`, error)
}
resolve(key)
})
}
const key = await mintKeyPromise
res.end(key)
})
router.all(/.*/, ensureAuthenticated, ensureVSCodeLoaded, async (req, res) => {
vscodeServer!.handleRequest(req, res)
})
const socketProxyProvider = new SocketProxyProvider()
wsRouter.ws(/.*/, ensureOrigin, ensureAuthenticated, ensureVSCodeLoaded, async (req: WebsocketRequest) => {
const wrappedSocket = await socketProxyProvider.createProxy(req.ws)
// This should actually accept a duplex stream but it seems Code has not
// been updated to match the Node 16 types so cast for now. There does not
// appear to be any code specific to sockets so this should be fine.
vscodeServer!.handleUpgrade(req, wrappedSocket as net.Socket)
req.ws.resume()
})
export function dispose() {
vscodeServer?.dispose()
socketProxyProvider.stop()
}

View File

@@ -1,7 +1,7 @@
import { field, logger } from "@coder/logger"
import * as http from "http"
import * as https from "https"
import ProxyAgent from "proxy-agent"
import { ProxyAgent } from "proxy-agent"
import * as semver from "semver"
import * as url from "url"
import { httpProxyUri, version } from "./constants"
@@ -104,7 +104,10 @@ export class UpdateProvider {
const request = (uri: string): void => {
logger.debug("Making request", field("uri", uri))
const isHttps = uri.startsWith("https")
const agent = httpProxyUri ? new ProxyAgent(httpProxyUri) : undefined
const agent = new ProxyAgent({
keepAlive: true,
getProxyForUrl: () => httpProxyUri || "",
})
const httpx = isHttps ? https : http
const client = httpx.get(uri, { headers: { "User-Agent": "code-server" }, agent }, (response) => {
if (!response.statusCode || response.statusCode < 200 || response.statusCode >= 400) {

View File

@@ -87,20 +87,6 @@ export function getEnvPaths(platform = process.platform): Paths {
}
}
/**
* humanPath replaces the home directory in path with ~.
* Makes it more readable.
*
* @param homedir - the home directory(i.e. `os.homedir()`)
* @param path - a file path
*/
export function humanPath(homedir: string, path?: string): string {
if (!path) {
return ""
}
return path.replace(homedir, "~")
}
export const generateCertificate = async (hostname: string): Promise<{ cert: string; certKey: string }> => {
const certPath = path.join(paths.data, `${hostname.replace(/\./g, "_")}.crt`)
const certKeyPath = path.join(paths.data, `${hostname.replace(/\./g, "_")}.key`)
@@ -541,3 +527,13 @@ export const loadAMDModule = async <T>(amdPath: string, exportName: string): Pro
return module[exportName] as T
}
/**
* Split a string on the first equals. The result will always be an array with
* two items regardless of how many equals there are. The second item will be
* undefined if empty or missing.
*/
export function splitOnFirstEquals(str: string): [string, string | undefined] {
const split = str.split(/=(.+)?/, 2)
return [split[0], split[1]]
}

211
src/node/vscodeSocket.ts Normal file
View File

@@ -0,0 +1,211 @@
import { logger } from "@coder/logger"
import express from "express"
import * as http from "http"
import * as path from "path"
import { HttpCode } from "../common/http"
import { listen } from "./app"
import { canConnect } from "./util"
export interface EditorSessionEntry {
workspace: {
id: string
folders: {
uri: {
path: string
}
}[]
}
socketPath: string
}
interface DeleteSessionRequest {
socketPath?: string
}
interface AddSessionRequest {
entry?: EditorSessionEntry
}
interface GetSessionResponse {
socketPath?: string
}
export async function makeEditorSessionManagerServer(
codeServerSocketPath: string,
editorSessionManager: EditorSessionManager,
): Promise<http.Server> {
const router = express()
// eslint-disable-next-line import/no-named-as-default-member
router.use(express.json())
router.get<{}, GetSessionResponse | string | unknown, undefined, { filePath?: string }>(
"/session",
async (req, res) => {
const filePath = req.query.filePath
if (!filePath) {
res.status(HttpCode.BadRequest).send("filePath is required")
return
}
try {
const socketPath = await editorSessionManager.getConnectedSocketPath(filePath)
const response: GetSessionResponse = { socketPath }
res.json(response)
} catch (error: unknown) {
res.status(HttpCode.ServerError).send(error)
}
},
)
router.post<{}, string, AddSessionRequest | undefined>("/add-session", async (req, res) => {
const entry = req.body?.entry
if (!entry) {
res.status(400).send("entry is required")
return
}
editorSessionManager.addSession(entry)
res.status(200).send("session added")
})
router.post<{}, string, DeleteSessionRequest | undefined>("/delete-session", async (req, res) => {
const socketPath = req.body?.socketPath
if (!socketPath) {
res.status(400).send("socketPath is required")
return
}
editorSessionManager.deleteSession(socketPath)
res.status(200).send("session deleted")
})
const server = http.createServer(router)
try {
await listen(server, { socket: codeServerSocketPath })
} catch (e) {
logger.warn(`Could not create socket at ${codeServerSocketPath}`)
}
return server
}
export class EditorSessionManager {
// Map from socket path to EditorSessionEntry.
private entries = new Map<string, EditorSessionEntry>()
addSession(entry: EditorSessionEntry): void {
logger.debug(`Adding session to session registry: ${entry.socketPath}`)
this.entries.set(entry.socketPath, entry)
}
getCandidatesForFile(filePath: string): EditorSessionEntry[] {
const matchCheckResults = new Map<string, boolean>()
const checkMatch = (entry: EditorSessionEntry): boolean => {
if (matchCheckResults.has(entry.socketPath)) {
return matchCheckResults.get(entry.socketPath)!
}
const result = entry.workspace.folders.some((folder) => filePath.startsWith(folder.uri.path + path.sep))
matchCheckResults.set(entry.socketPath, result)
return result
}
return Array.from(this.entries.values())
.reverse() // Most recently registered first.
.sort((a, b) => {
// Matches first.
const aMatch = checkMatch(a)
const bMatch = checkMatch(b)
if (aMatch === bMatch) {
return 0
}
if (aMatch) {
return -1
}
return 1
})
}
deleteSession(socketPath: string): void {
logger.debug(`Deleting session from session registry: ${socketPath}`)
this.entries.delete(socketPath)
}
/**
* Returns the best socket path that we can connect to.
* We also delete any sockets that we can't connect to.
*/
async getConnectedSocketPath(filePath: string): Promise<string | undefined> {
const candidates = this.getCandidatesForFile(filePath)
let match: EditorSessionEntry | undefined = undefined
for (const candidate of candidates) {
if (await canConnect(candidate.socketPath)) {
match = candidate
break
}
this.deleteSession(candidate.socketPath)
}
return match?.socketPath
}
}
export class EditorSessionManagerClient {
constructor(private codeServerSocketPath: string) {}
async canConnect() {
return canConnect(this.codeServerSocketPath)
}
async getConnectedSocketPath(filePath: string): Promise<string | undefined> {
const response = await new Promise<GetSessionResponse>((resolve, reject) => {
const opts = {
path: "/session?filePath=" + encodeURIComponent(filePath),
socketPath: this.codeServerSocketPath,
method: "GET",
}
const req = http.request(opts, (res) => {
let rawData = ""
res.setEncoding("utf8")
res.on("data", (chunk) => {
rawData += chunk
})
res.on("end", () => {
try {
const obj = JSON.parse(rawData)
if (res.statusCode === 200) {
resolve(obj)
} else {
reject(new Error("Unexpected status code: " + res.statusCode))
}
} catch (e: unknown) {
reject(e)
}
})
})
req.on("error", reject)
req.end()
})
return response.socketPath
}
// Currently only used for tests.
async addSession(request: AddSessionRequest): Promise<void> {
await new Promise<void>((resolve, reject) => {
const opts = {
path: "/add-session",
socketPath: this.codeServerSocketPath,
method: "POST",
headers: {
"content-type": "application/json",
accept: "application/json",
},
}
const req = http.request(opts, () => {
resolve()
})
req.on("error", reject)
req.write(JSON.stringify(request))
req.end()
})
}
}

View File

@@ -3,7 +3,7 @@ import * as cp from "child_process"
import * as path from "path"
import * as rfs from "rotating-file-stream"
import { Emitter } from "../common/emitter"
import { DefaultedArgs } from "./cli"
import { DefaultedArgs, redactArgs } from "./cli"
import { paths } from "./util"
const timeoutInterval = 10000 // 10s, matches VS Code's timeouts.
@@ -44,10 +44,11 @@ export function onMessage<M, T extends M>(
}
const onMessage = (message: M) => {
;(customLogger || logger).trace("got message", field("message", message))
if (fn(message)) {
cleanup()
resolve(message)
} else {
;(customLogger || logger).debug("got unhandled message", field("message", message))
}
}
@@ -77,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)
@@ -172,6 +176,7 @@ export class ChildProcess extends Process {
* Initiate the handshake and wait for a response from the parent.
*/
public async handshake(): Promise<DefaultedArgs> {
this.logger.debug("initiating handshake")
this.send({ type: "handshake" })
const message = await onMessage<ParentMessage, ParentHandshakeMessage>(
process,
@@ -180,6 +185,13 @@ export class ChildProcess extends Process {
},
this.logger,
)
this.logger.debug(
"got message",
field("message", {
type: message.type,
args: redactArgs(message.args),
}),
)
return message.args
}
@@ -280,6 +292,10 @@ export class ParentProcess extends Process {
}
public start(args: DefaultedArgs): Promise<void> {
// Our logger was created before we parsed CLI arguments so update the level
// in case it has changed.
this.logger.level = logger.level
// Store for relaunches.
this.args = args
if (!this.started) {
@@ -306,7 +322,7 @@ export class ParentProcess extends Process {
})
}
this.logger.debug(`spawned inner process ${child.pid}`)
this.logger.debug(`spawned child process ${child.pid}`)
await this.handshake(child)
@@ -334,13 +350,14 @@ export class ParentProcess extends Process {
if (!this.args) {
throw new Error("started without args")
}
await onMessage<ChildMessage, ChildHandshakeMessage>(
const message = await onMessage<ChildMessage, ChildHandshakeMessage>(
child,
(message): message is ChildHandshakeMessage => {
return message.type === "handshake"
},
this.logger,
)
this.logger.debug("got message", field("message", message))
this.send(child, { type: "handshake", args: this.args })
}

View File

@@ -32,6 +32,9 @@ export class WebsocketRouter {
/**
* Handle a websocket at this route. Note that websockets are immediately
* paused when they come in.
*
* If the origin header exists it must match the host or the connection will
* be prevented.
*/
public ws(route: expressCore.PathParams, ...handlers: pluginapi.WebSocketHandler[]): void {
this.router.get(

View File

@@ -23,6 +23,41 @@ describe("Downloads (enabled)", ["--disable-workspace-trust"], {}, async () => {
expect(await codeServerPage.page.isVisible("text=Download...")).toBe(true)
})
test("should see the 'Show Local' button on Save As", async ({ codeServerPage }) => {
// Setup
const workspaceDir = await codeServerPage.workspaceDir
const fileName = "unique-file-save-as.txt"
const tmpFilePath = path.join(workspaceDir, fileName)
await fs.writeFile(tmpFilePath, "Hello World")
// Action
await codeServerPage.page.waitForSelector(`text=${fileName}`)
await codeServerPage.openFile(fileName)
await codeServerPage.page.click(".tab")
await codeServerPage.navigateMenus(["File", "Auto Save"])
await codeServerPage.page.keyboard.type("Making some edits.")
await codeServerPage.navigateMenus(["File", "Save As..."])
await codeServerPage.page.waitForSelector(".quick-input-widget")
expect(await codeServerPage.page.isVisible("text=Show Local")).toBe(true)
})
test("should see the 'Show Local' button on Save File", async ({ codeServerPage }) => {
// Action
await codeServerPage.navigateMenus(["File", "New Text File"])
await codeServerPage.waitForTab("Untitled-1")
await codeServerPage.navigateMenus(["File", "Save"])
await codeServerPage.page.waitForSelector(".quick-input-widget")
expect(await codeServerPage.page.isVisible("text=Show Local")).toBe(true)
})
test("should see the 'Show Local' button on Save Workspace As", async ({ codeServerPage }) => {
// Action
await codeServerPage.navigateMenus(["File", "Save Workspace As..."])
await codeServerPage.page.waitForSelector(".quick-input-widget")
expect(await codeServerPage.page.isVisible("text=Show Local")).toBe(true)
})
})
describe("Downloads (disabled)", ["--disable-workspace-trust", "--disable-file-downloads"], {}, async () => {
@@ -35,7 +70,7 @@ describe("Downloads (disabled)", ["--disable-workspace-trust", "--disable-file-d
// Setup
const workspaceDir = await codeServerPage.workspaceDir
const tmpFilePath = path.join(workspaceDir, "unique-file.txt")
await fs.writeFile(tmpFilePath, "hello world")
await fs.writeFile(tmpFilePath, "Hello World")
// Action
const fileInExplorer = await codeServerPage.page.waitForSelector("text=unique-file.txt")
@@ -45,4 +80,35 @@ describe("Downloads (disabled)", ["--disable-workspace-trust", "--disable-file-d
expect(await codeServerPage.page.isVisible("text=Download...")).toBe(false)
})
test("should not see the 'Show Local' button on Save as", async ({ codeServerPage }) => {
// Setup
const workspaceDir = await codeServerPage.workspaceDir
const fileName = "unique-file-save-as.txt"
const tmpFilePath = path.join(workspaceDir, fileName)
await fs.writeFile(tmpFilePath, "Hello World")
// Action
await codeServerPage.page.waitForSelector(`text=${fileName}`)
await codeServerPage.openFile(fileName)
await codeServerPage.page.click(".tab")
await codeServerPage.navigateMenus(["File", "Save As..."])
expect(await codeServerPage.page.isVisible("text=Show Local")).toBe(false)
})
test("should not see the 'Show Local' button on Save File", async ({ codeServerPage }) => {
// Action
await codeServerPage.navigateMenus(["File", "New Text File"])
await codeServerPage.waitForTab("Untitled-1")
await codeServerPage.navigateMenus(["File", "Save"])
await codeServerPage.page.waitForSelector(".quick-input-widget")
expect(await codeServerPage.page.isVisible("text=Show Local")).toBe(false)
})
test("should not see the 'Show Local' button on Save Workspace As", async ({ codeServerPage }) => {
// Action
await codeServerPage.navigateMenus(["File", "Save Workspace As..."])
await codeServerPage.page.waitForSelector(".quick-input-widget")
expect(await codeServerPage.page.isVisible("text=Show Local")).toBe(false)
})
})

View File

@@ -77,9 +77,9 @@ export class CodeServer {
*/
private async createWorkspace(): Promise<string> {
const dir = await this.workspaceDir
await fs.mkdir(path.join(dir, "User"), { recursive: true })
await fs.mkdir(path.join(dir, "Machine"), { recursive: true })
await fs.writeFile(
path.join(dir, "User/settings.json"),
path.join(dir, "Machine/settings.json"),
JSON.stringify({
"workbench.startupEditor": "none",
}),
@@ -117,40 +117,26 @@ export class CodeServer {
* directories.
*/
private async spawn(): Promise<CodeServerProcess> {
// This will be used both as the workspace and data directory to ensure
// instances don't bleed into each other.
const dir = await this.createWorkspace()
const args = await this.argsWithDefaults([
"--auth",
"none",
// The workspace to open.
...(this.args.includes("--ignore-last-opened") ? [] : [dir]),
...this.args,
// Using port zero will spawn on a random port.
"--bind-addr",
"127.0.0.1:0",
])
return new Promise((resolve, reject) => {
const args = [
this.entry,
"--extensions-dir",
path.join(dir, "extensions"),
"--auth",
"none",
// The workspace to open.
...(this.args.includes("--ignore-last-opened") ? [] : [dir]),
...this.args,
// Using port zero will spawn on a random port.
"--bind-addr",
"127.0.0.1:0",
// Setting the XDG variables would be easier and more thorough but the
// modules we import ignores those variables for non-Linux operating
// systems so use these flags instead.
"--config",
path.join(dir, "config.yaml"),
"--user-data-dir",
dir,
]
this.logger.debug("spawning `node " + args.join(" ") + "`")
const proc = cp.spawn("node", args, {
cwd: path.join(__dirname, "../../.."),
env: {
...process.env,
...this.env,
// Set to empty string to prevent code-server from
// using the existing instance when running the e2e tests
// from an integrated terminal.
// Prevent code-server from using the existing instance when running
// the e2e tests from an integrated terminal.
VSCODE_IPC_HOOK_CLI: "",
PASSWORD,
},
@@ -173,11 +159,15 @@ export class CodeServer {
reject(error)
})
// Tracks when the HTTP and session servers are ready.
let httpAddress: string | undefined
let sessionAddress: string | undefined
let resolved = false
proc.stdout.setEncoding("utf8")
onLine(proc, (line) => {
// As long as we are actively getting input reset the timer. If we stop
// getting input and still have not found the address the timer will
// getting input and still have not found the addresses the timer will
// reject.
timer.reset()
@@ -186,20 +176,69 @@ export class CodeServer {
if (resolved) {
return
}
const match = line.trim().match(/HTTPS? server listening on (https?:\/\/[.:\d]+)\/?$/)
let match = line.trim().match(/HTTPS? server listening on (https?:\/\/[.:\d]+)\/?$/)
if (match) {
// Cookies don't seem to work on IP address so swap to localhost.
// Cookies don't seem to work on IP addresses so swap to localhost.
// TODO: Investigate whether this is a bug with code-server.
const address = match[1].replace("127.0.0.1", "localhost")
this.logger.debug(`spawned on ${address}`)
httpAddress = match[1].replace("127.0.0.1", "localhost")
}
match = line.trim().match(/Session server listening on (.+)$/)
if (match) {
sessionAddress = match[1]
}
if (typeof httpAddress !== "undefined" && typeof sessionAddress !== "undefined") {
resolved = true
timer.dispose()
resolve({ process: proc, address })
this.logger.debug(`code-server is ready: ${httpAddress} ${sessionAddress}`)
resolve({ process: proc, address: httpAddress })
}
})
})
}
/**
* Execute a short-lived command.
*/
async run(args: string[]): Promise<void> {
args = await this.argsWithDefaults(args)
this.logger.debug("executing `node " + args.join(" ") + "`")
await util.promisify(cp.exec)("node " + args.join(" "), {
cwd: path.join(__dirname, "../../.."),
env: {
...process.env,
...this.env,
// Prevent code-server from using the existing instance when running
// the e2e tests from an integrated terminal.
VSCODE_IPC_HOOK_CLI: "",
},
})
}
/**
* Combine arguments with defaults.
*/
private async argsWithDefaults(args: string[]): Promise<string[]> {
// This will be used both as the workspace and data directory to ensure
// instances don't bleed into each other.
const dir = await this.workspaceDir
return [
this.entry,
"--extensions-dir",
path.join(dir, "extensions"),
...args,
// Setting the XDG variables would be easier and more thorough but the
// modules we import ignores those variables for non-Linux operating
// systems so use these flags instead.
"--config",
path.join(dir, "config.yaml"),
"--user-data-dir",
dir,
]
}
/**
* Close the code-server process.
*/
@@ -230,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())
})
@@ -359,11 +401,18 @@ export class CodeServerPage {
* Open a file by using menus.
*/
async openFile(file: string) {
await this.navigateMenus(["File", "Open File"])
await this.navigateMenus(["File", "Open File..."])
await this.navigateQuickInput([path.basename(file)])
await this.waitForTab(file)
}
/**
* Open a file through an external command.
*/
async openFileExternally(file: string) {
await this.codeServer.run(["--reuse-window", file])
}
/**
* Wait for a tab to open for the specified file.
*/
@@ -383,7 +432,7 @@ export class CodeServerPage {
* it then clicking the match from the results.
*/
async executeCommandViaMenus(command: string) {
await this.navigateMenus(["View", "Command Palette"])
await this.navigateMenus(["View", "Command Palette..."])
await this.page.keyboard.type(command)
@@ -439,19 +488,19 @@ export class CodeServerPage {
// splitting them into two steps each we can cancel before running the
// action.
steps.push({
fn: () => this.page.hover(`${selector} :text("${item}")`, { trial: true }),
fn: () => this.page.hover(`${selector} :text-is("${item}")`, { trial: true }),
name: `${item}:hover:trial`,
})
steps.push({
fn: () => this.page.hover(`${selector} :text("${item}")`, { force: true }),
fn: () => this.page.hover(`${selector} :text-is("${item}")`, { force: true }),
name: `${item}:hover:force`,
})
steps.push({
fn: () => this.page.click(`${selector} :text("${item}")`, { trial: true }),
fn: () => this.page.click(`${selector} :text-is("${item}")`, { trial: true }),
name: `${item}:click:trial`,
})
steps.push({
fn: () => this.page.click(`${selector} :text("${item}")`, { force: true }),
fn: () => this.page.click(`${selector} :text-is("${item}")`, { force: true }),
name: `${item}:click:force`,
})
}

View File

@@ -1,5 +1,5 @@
import { describe, test, expect } from "./baseFixture"
import { clean, getMaybeProxiedPathname } from "../utils/helpers"
import { describe, test, expect } from "./baseFixture"
const routes = ["/", "/vscode", "/vscode/"]
@@ -103,7 +103,7 @@ describe("VS Code Routes with no workspace or folder", ["--disable-workspace-tru
// Closing the folder should stop the redirecting.
await codeServerPage.navigate("/?ew=true")
let url = new URL(codeServerPage.page.url())
const url = new URL(codeServerPage.page.url())
const pathname = getMaybeProxiedPathname(url)
expect(pathname).toBe("/")
expect(url.search).toBe("?ew=true")

Some files were not shown because too many files have changed in this diff Show More