mirror of
https://github.com/coder/code-server.git
synced 2026-04-14 15:19:07 -05:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64fa789278 | ||
|
|
76db1a1467 | ||
|
|
9ffc2fdfe0 | ||
|
|
674382fb7f | ||
|
|
853fb91eb7 | ||
|
|
51a066dedc | ||
|
|
408e15aee0 | ||
|
|
0a895e6d0e | ||
|
|
a5d3212389 | ||
|
|
2588f1ea24 | ||
|
|
eea8171c56 |
38
.github/workflows/ci.yaml
vendored
38
.github/workflows/ci.yaml
vendored
@@ -33,13 +33,13 @@ jobs:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
|
||||
- name: Install Node.js v16
|
||||
- name: Install Node.js v14
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16"
|
||||
node-version: "14"
|
||||
|
||||
- name: Install helm
|
||||
uses: azure/setup-helm@v2.1
|
||||
uses: azure/setup-helm@v1.1
|
||||
|
||||
- name: Fetch dependencies from cache
|
||||
id: cache-yarn
|
||||
@@ -74,10 +74,10 @@ jobs:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
|
||||
- name: Install Node.js v16
|
||||
- name: Install Node.js v14
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16"
|
||||
node-version: "14"
|
||||
|
||||
- name: Fetch dependencies from cache
|
||||
id: cache-yarn
|
||||
@@ -116,10 +116,10 @@ jobs:
|
||||
- name: Patch Code
|
||||
run: quilt push -a
|
||||
|
||||
- name: Install Node.js v16
|
||||
- name: Install Node.js v14
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16"
|
||||
node-version: "14"
|
||||
|
||||
- name: Fetch dependencies from cache
|
||||
id: cache-yarn
|
||||
@@ -253,15 +253,15 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install Node.js v16
|
||||
- name: Install Node.js v14
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16"
|
||||
node-version: "14"
|
||||
|
||||
- name: Install development tools
|
||||
run: |
|
||||
yum install -y epel-release centos-release-scl
|
||||
yum install -y devtoolset-9-{make,gcc,gcc-c++} jq rsync python3
|
||||
yum install -y devtoolset-9-{make,gcc,gcc-c++} jq rsync
|
||||
|
||||
- name: Install nfpm and envsubst
|
||||
run: |
|
||||
@@ -337,7 +337,7 @@ jobs:
|
||||
CXX: ${{ format('{0}-g++', matrix.prefix) }}
|
||||
LINK: ${{ format('{0}-g++', matrix.prefix) }}
|
||||
NPM_CONFIG_ARCH: ${{ matrix.arch }}
|
||||
NODE_VERSION: v16.13.0
|
||||
NODE_VERSION: v14.17.4
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
@@ -345,10 +345,10 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install Node.js v16
|
||||
- name: Install Node.js v14
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16"
|
||||
node-version: "14"
|
||||
|
||||
- name: Install nfpm
|
||||
run: |
|
||||
@@ -397,10 +397,10 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install Node.js v16
|
||||
- name: Install Node.js v14
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16"
|
||||
node-version: "14"
|
||||
|
||||
- name: Install nfpm
|
||||
run: |
|
||||
@@ -446,10 +446,10 @@ jobs:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
|
||||
- name: Install Node.js v16
|
||||
- name: Install Node.js v14
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: "16"
|
||||
node-version: "14"
|
||||
|
||||
- name: Fetch dependencies from cache
|
||||
id: cache-yarn
|
||||
@@ -506,7 +506,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Run Trivy vulnerability scanner in repo mode
|
||||
uses: aquasecurity/trivy-action@2b30463ddb3d11724a04e760e020c7d9af24d8b3
|
||||
uses: aquasecurity/trivy-action@40c4ca9e7421287d0c5576712fdff370978f9c3c
|
||||
with:
|
||||
scan-type: "fs"
|
||||
scan-ref: "."
|
||||
@@ -517,6 +517,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@v1
|
||||
with:
|
||||
sarif_file: "trivy-repo-results.sarif"
|
||||
|
||||
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
@@ -35,13 +35,13 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
config-file: ./.github/codeql-config.yml
|
||||
languages: javascript
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v1
|
||||
|
||||
18
.github/workflows/docker.yaml
vendored
18
.github/workflows/docker.yaml
vendored
@@ -39,15 +39,17 @@ jobs:
|
||||
id: version
|
||||
run: echo "::set-output name=version::$(jq -r .version package.json)"
|
||||
|
||||
- name: Download release artifacts
|
||||
uses: robinraju/release-downloader@v1.3
|
||||
- name: Download artifact
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
id: download
|
||||
with:
|
||||
repository: "coder/code-server"
|
||||
tag: v${{ steps.version.outputs.version }}
|
||||
fileName: "*.deb"
|
||||
out-file-path: "release-packages"
|
||||
branch: v${{ steps.version.outputs.version }}
|
||||
workflow: ci.yaml
|
||||
workflow_conclusion: completed
|
||||
name: "release-packages"
|
||||
path: release-packages
|
||||
|
||||
- name: Publish to Docker
|
||||
run: yarn publish:docker
|
||||
- name: Run ./ci/steps/docker-buildx-push.sh
|
||||
run: ./ci/steps/docker-buildx-push.sh
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
|
||||
4
.github/workflows/trivy-docker.yaml
vendored
4
.github/workflows/trivy-docker.yaml
vendored
@@ -51,7 +51,7 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Run Trivy vulnerability scanner in image mode
|
||||
uses: aquasecurity/trivy-action@2b30463ddb3d11724a04e760e020c7d9af24d8b3
|
||||
uses: aquasecurity/trivy-action@40c4ca9e7421287d0c5576712fdff370978f9c3c
|
||||
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@v1
|
||||
with:
|
||||
sarif_file: "trivy-image-results.sarif"
|
||||
|
||||
@@ -1 +1 @@
|
||||
16
|
||||
14
|
||||
|
||||
27
CHANGELOG.md
27
CHANGELOG.md
@@ -11,8 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
Code v99.99.999
|
||||
|
||||
### Changed
|
||||
### Added
|
||||
### Changed
|
||||
### Deprecated
|
||||
### Removed
|
||||
### Fixed
|
||||
@@ -20,31 +20,6 @@ Code v99.99.999
|
||||
|
||||
-->
|
||||
|
||||
## [4.4.0](https://github.com/coder/code-server/releases/tag/v4.4.0) - 2022-05-06
|
||||
|
||||
Code v1.66.2
|
||||
|
||||
### Changed
|
||||
|
||||
- Refactored methods in `Heart` class and made `Heart.beat()` async to make
|
||||
testing easier.
|
||||
- Upgraded to Code 1.66.2.
|
||||
|
||||
### Added
|
||||
|
||||
- Added back telemetry patch which was removed in the Code reachitecture.
|
||||
- Added support to use `true` for `CS_DISABLE_FILE_DOWNLOADS` environment
|
||||
variable. This means you can disable file downloads by setting
|
||||
`CS_DISABLE_FILE_DOWNLOADS` to `true` or `1`.
|
||||
- Added tests for `Heart` class.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed installation issue in AUR after LICENSE rename.
|
||||
- Fixed issue with listening on IPv6 addresses.
|
||||
- Fixed issue with Docker publish action not being able to find artifacts. Now
|
||||
it downloads the release assets from the release.
|
||||
|
||||
## [4.3.0](https://github.com/coder/code-server/releases/tag/v4.3.0) - 2022-04-14
|
||||
|
||||
Code v1.65.2
|
||||
|
||||
@@ -146,7 +146,7 @@ EOF
|
||||
# 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"
|
||||
rsync "$VSCODE_SRC_PATH/extensions/postinstall.mjs" "$VSCODE_OUT_PATH/extensions/postinstall.mjs"
|
||||
rsync "$VSCODE_SRC_PATH/extensions/postinstall.js" "$VSCODE_OUT_PATH/extensions/postinstall.js"
|
||||
|
||||
pushd "$VSCODE_OUT_PATH"
|
||||
symlink_asar
|
||||
|
||||
@@ -33,8 +33,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:-14}" ]; then
|
||||
echo "ERROR: code-server currently requires node v14."
|
||||
if [ -n "$FORCE_NODE_VERSION" ]; then
|
||||
echo "However, you have overrided the version check to use v$FORCE_NODE_VERSION."
|
||||
fi
|
||||
@@ -92,7 +92,7 @@ symlink_asar() {
|
||||
vscode_yarn() {
|
||||
echo 'Installing Code dependencies...'
|
||||
cd lib/vscode
|
||||
yarn --production --frozen-lockfile --no-default-rc
|
||||
yarn --production --frozen-lockfile
|
||||
|
||||
symlink_asar
|
||||
|
||||
|
||||
@@ -7,9 +7,6 @@ install-deps() {
|
||||
if [[ ${CI-} ]]; then
|
||||
args+=(--frozen-lockfile)
|
||||
fi
|
||||
if [[ "$1" == "lib/vscode" ]]; then
|
||||
args+=(--no-default-rc)
|
||||
fi
|
||||
# If there is no package.json then yarn will look upward and end up installing
|
||||
# from the root resulting in an infinite loop (this can happen if you have not
|
||||
# checked out the submodule yet for example).
|
||||
|
||||
@@ -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: 2.5.0
|
||||
version: 2.4.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.4.0
|
||||
appVersion: 4.3.0
|
||||
|
||||
@@ -6,7 +6,7 @@ replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: codercom/code-server
|
||||
tag: '4.4.0'
|
||||
tag: '4.3.0'
|
||||
pullPolicy: Always
|
||||
|
||||
# Specifies one or more secrets to be used when pulling images from a
|
||||
|
||||
@@ -31,7 +31,7 @@ for [VS
|
||||
Code](https://github.com/Microsoft/vscode/wiki/How-to-Contribute#prerequisites).
|
||||
Here is what is needed:
|
||||
|
||||
- `node` v16.x
|
||||
- `node` v14.x
|
||||
- `git` v2.x or greater
|
||||
- [`git-lfs`](https://git-lfs.github.com)
|
||||
- [`yarn`](https://classic.yarnpkg.com/en/)
|
||||
@@ -96,8 +96,6 @@ re-apply the patches.
|
||||
### Version updates to Code
|
||||
|
||||
1. Update the `lib/vscode` submodule to the desired upstream version branch.
|
||||
1. `cd lib/vscode && git checkout release/1.66 && cd ../..`
|
||||
2. `git add lib && git commit -m "chore: update Code"`
|
||||
2. Apply the patches (`quilt push -a`) or restore your stashed changes. At this
|
||||
stage you may need to resolve conflicts. For example use `quilt push -f`,
|
||||
manually apply the rejected portions, then `quilt refresh`.
|
||||
@@ -132,13 +130,11 @@ yarn build:vscode
|
||||
yarn release
|
||||
```
|
||||
|
||||
_NOTE: this does not keep `node_modules`. If you want them to be kept, use `KEEP_MODULES=1 yarn release` (if you're testing in Coder, you'll want to do this)_
|
||||
|
||||
Run your build:
|
||||
|
||||
```shell
|
||||
cd release
|
||||
yarn --production # Skip if you used KEEP_MODULES=1
|
||||
yarn --production
|
||||
# Runs the built JavaScript with Node.
|
||||
node .
|
||||
```
|
||||
|
||||
@@ -164,7 +164,7 @@ If you're the current release manager, follow these steps:
|
||||
|
||||
### Publishing a release
|
||||
|
||||
1. Create a new branch called `v0.0.0` (replace 0s with actual version aka v4.4.0)
|
||||
1. Create a new branch called `v0.0.0` (replace 0s with actual version aka v4.3.0)
|
||||
1. Run `yarn release:prep` and type in the new version (e.g., `3.8.1`)
|
||||
1. GitHub Actions will generate the `npm-package`, `release-packages` and
|
||||
`release-images` artifacts. You do not have to wait for this step to complete
|
||||
|
||||
@@ -11,11 +11,11 @@ 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 14:
|
||||
|
||||
```shell
|
||||
nvm install 16
|
||||
nvm use 16
|
||||
nvm install 14
|
||||
nvm use 14
|
||||
```
|
||||
|
||||
8. Install code-server globally on device with: `npm i -g code-server`
|
||||
|
||||
@@ -60,6 +60,6 @@ As `code-server` is based on VS Code, you can follow the steps described on Duck
|
||||
code-server --enable-proposed-api genuitecllc.codetogether
|
||||
```
|
||||
|
||||
Another option would be to add a value in code-server's [config file](https://coder.com/docs/code-server/v4.4.0/FAQ#how-does-the-config-file-work).
|
||||
Another option would be to add a value in code-server's [config file](https://coder.com/docs/code-server/v4.3.0/FAQ#how-does-the-config-file-work).
|
||||
|
||||
3. Refresh code-server and navigate to the CodeTogether icon in the sidebar to host or join a coding session.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# code-server Helm Chart
|
||||
|
||||
[](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square) [](https://img.shields.io/badge/Type-application-informational?style=flat-square) [](https://img.shields.io/badge/AppVersion-4.4.0-informational?style=flat-square)
|
||||
[](https://img.shields.io/badge/Version-1.0.0-informational?style=flat-square) [](https://img.shields.io/badge/Type-application-informational?style=flat-square) [](https://img.shields.io/badge/AppVersion-4.3.0-informational?style=flat-square)
|
||||
|
||||
[code-server](https://github.com/coder/code-server) code-server is VS Code running
|
||||
on a remote server, accessible through the browser.
|
||||
@@ -73,7 +73,7 @@ and their default values.
|
||||
| hostnameOverride | string | `""` |
|
||||
| image.pullPolicy | string | `"Always"` |
|
||||
| image.repository | string | `"codercom/code-server"` |
|
||||
| image.tag | string | `"4.4.0"` |
|
||||
| image.tag | string | `"4.3.0"` |
|
||||
| imagePullSecrets | list | `[]` |
|
||||
| ingress.enabled | bool | `false` |
|
||||
| nameOverride | string | `""` |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"versions": ["v4.4.0"],
|
||||
"versions": ["v4.3.0"],
|
||||
"routes": [
|
||||
{
|
||||
"title": "Home",
|
||||
@@ -73,7 +73,7 @@
|
||||
{
|
||||
"title": "Upgrade",
|
||||
"description": "How to upgrade code-server.",
|
||||
"icon": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M17.8049 2.19795C17.7385 2.1311 17.6587 2.07899 17.5708 2.04504C17.4829 2.01108 17.3889 1.99604 17.2948 2.00089C7.89216 2.49153 4.4188 10.8673 4.38528 10.9517C4.33624 11.0736 4.32406 11.2071 4.4.028 11.3358C4.3765 11.4645 4.43995 11.5827 4.53274 11.6756L8.32449 15.4674C8.41787 15.5606 8.53669 15.6242 8.66606 15.6502C8.79543 15.6762 8.92959 15.6634 9.05174 15.6135C9.13552 15.5793 17.4664 12.0671 17.9986 2.7087C18.0039 2.61474 17.9895 2.5207 17.9561 2.4327C17.9227 2.3447 17.8712 2.26471 17.8049 2.19795ZM12.3314 9.56427C12.1439 9.75179 11.9051 9.87951 11.645 9.93126C11.385 9.98302 11.1154 9.9565 10.8704 9.85505C10.6254 9.7536 10.4161 9.58178 10.2687 9.36131C10.1214 9.14085 10.0428 8.88166 10.0428 8.6165C10.0428 8.35135 10.1214 8.09215 10.2687 7.87169C10.4161 7.65123 10.6254 7.47941 10.8704 7.37796C11.1154 7.27651 11.385 7.24998 11.645 7.30174C11.9051 7.3535 12.1439 7.48121 12.3314 7.66873C12.5827 7.92012 12.7239 8.26104 12.7239 8.6165C12.7239 8.97197 12.5827 9.31288 12.3314 9.56427Z\"/><path d=\"M2.74602 14.5444C2.92281 14.3664 3.133 14.2251 3.36454 14.1285C3.59608 14.0319 3.8444 13.9819 4.09529 13.9815C4.34617 13.9811 4.59466 14.0.12 4.82653 14.126C5.05839 14.2218 5.26907 14.3624 5.44647 14.5398C5.62386 14.7172 5.7645 14.9279 5.86031 15.1598C5.95612 15.3916 6.00522 15.6401 6.00479 15.891C6.00437 16.1419 5.95442 16.3902 5.85782 16.6218C5.76122 16.8533 5.61987 17.0635 5.44186 17.2403C4.69719 17.985 2 18.0004 2 18.0004C2 18.0004 2 15.2884 2.74602 14.5444Z\"/><path d=\"M8.9416 3.48269C7.99688 3.31826 7.02645 3.38371 6.11237 3.67352C5.19828 3.96332 4.36741 4.46894 3.68999 5.14765C3.33153 5.50944.4.01988 5.91477 2.76233 6.35415C2.68692 6.4822 2.6562 6.63169 2.67501 6.77911C2.69381 6.92652 2.76108 7.06351 2.86623 7.16853L4.1994 8.50238C5.43822 6.53634 7.04911 4.83119 8.9416 3.48269Z\"/><path d=\"M16.5181 11.0585C16.6825 12.0033 16.6171 12.9737 16.3273 13.8878C16.0375 14.8019 15.5318 15.6327 14.8531 16.3101C14.4914 16.6686 14.086 16.9803 13.6466 17.2378C13.5186 17.3132 13.3691 17.3439 13.2217 17.3251C13.0743 17.3063 12.9373 17.2391 12.8323 17.1339L11.4984 15.8007C13.4645 14.5619 15.1696 12.951 16.5181 11.0585Z\"/></svg>",
|
||||
"icon": "<svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M17.8049 2.19795C17.7385 2.1311 17.6587 2.07899 17.5708 2.04504C17.4829 2.01108 17.3889 1.99604 17.2948 2.00089C7.89216 2.49153 4.4188 10.8673 4.38528 10.9517C4.33624 11.0736 4.32406 11.2071 4.35028 11.3358C4.3765 11.4645 4.43995 11.5827 4.53274 11.6756L8.32449 15.4674C8.41787 15.5606 8.53669 15.6242 8.66606 15.6502C8.79543 15.6762 8.92959 15.6634 9.05174 15.6135C9.13552 15.5793 17.4664 12.0671 17.9986 2.7087C18.0039 2.61474 17.9895 2.5207 17.9561 2.4327C17.9227 2.3447 17.8712 2.26471 17.8049 2.19795ZM12.3314 9.56427C12.1439 9.75179 11.9051 9.87951 11.645 9.93126C11.385 9.98302 11.1154 9.9565 10.8704 9.85505C10.6254 9.7536 10.4161 9.58178 10.2687 9.36131C10.1214 9.14085 10.0428 8.88166 10.0428 8.6165C10.0428 8.35135 10.1214 8.09215 10.2687 7.87169C10.4161 7.65123 10.6254 7.47941 10.8704 7.37796C11.1154 7.27651 11.385 7.24998 11.645 7.30174C11.9051 7.3535 12.1439 7.48121 12.3314 7.66873C12.5827 7.92012 12.7239 8.26104 12.7239 8.6165C12.7239 8.97197 12.5827 9.31288 12.3314 9.56427Z\"/><path d=\"M2.74602 14.5444C2.92281 14.3664 3.133 14.2251 3.36454 14.1285C3.59608 14.0319 3.8444 13.9819 4.09529 13.9815C4.34617 13.9811 4.59466 14.0.12 4.82653 14.126C5.05839 14.2218 5.26907 14.3624 5.44647 14.5398C5.62386 14.7172 5.7645 14.9279 5.86031 15.1598C5.95612 15.3916 6.00522 15.6401 6.00479 15.891C6.00437 16.1419 5.95442 16.3902 5.85782 16.6218C5.76122 16.8533 5.61987 17.0635 5.44186 17.2403C4.69719 17.985 2 18.0004 2 18.0004C2 18.0004 2 15.2884 2.74602 14.5444Z\"/><path d=\"M8.9416 3.48269C7.99688 3.31826 7.02645 3.38371 6.11237 3.67352C5.19828 3.96332 4.36741 4.46894 3.68999 5.14765C3.33153 5.50944 3.01988 5.91477 2.76233 6.35415C2.68692 6.4822 2.6562 6.63169 2.67501 6.77911C2.69381 6.92652 2.76108 7.06351 2.86623 7.16853L4.1994 8.50238C5.43822 6.53634 7.04911 4.83119 8.9416 3.48269Z\"/><path d=\"M16.5181 11.0585C16.6825 12.0033 16.6171 12.9737 16.3273 13.8878C16.0375 14.8019 15.5318 15.6327 14.8531 16.3101C14.4914 16.6686 14.086 16.9803 13.6466 17.2378C13.5186 17.3132 13.3691 17.3439 13.2217 17.3251C13.0743 17.3063 12.9373 17.2391 12.8323 17.1339L11.4984 15.8007C13.4645 14.5619 15.1696 12.951 16.5181 11.0585Z\"/></svg>",
|
||||
"path": "./upgrade.md"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -22,8 +22,8 @@ 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
|
||||
We use the same major version of Node.js shipped with VSCode's Electron,
|
||||
which is currently `14.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
|
||||
@@ -72,7 +72,7 @@ Proceed to [installing](#installing)
|
||||
## FreeBSD
|
||||
|
||||
```sh
|
||||
pkg install -y git python npm-node16 yarn-node16 pkgconf
|
||||
pkg install -y git python npm-node14 yarn-node14 pkgconf
|
||||
pkg install -y libinotify
|
||||
```
|
||||
|
||||
|
||||
Submodule lib/vscode updated: dfd34e8260...c722ca6c7e
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "code-server",
|
||||
"license": "MIT",
|
||||
"version": "4.4.0",
|
||||
"version": "4.3.0",
|
||||
"description": "Run VS Code on a remote server.",
|
||||
"homepage": "https://github.com/coder/code-server",
|
||||
"bugs": {
|
||||
@@ -24,7 +24,6 @@
|
||||
"package": "./ci/build/build-packages.sh",
|
||||
"postinstall": "./ci/dev/postinstall.sh",
|
||||
"publish:npm": "./ci/steps/publish-npm.sh",
|
||||
"publish:docker": "./ci/steps/docker-buildx-push.sh",
|
||||
"_audit": "./ci/dev/audit.sh",
|
||||
"fmt": "./ci/dev/fmt.sh",
|
||||
"lint": "./ci/dev/lint.sh",
|
||||
@@ -122,7 +121,7 @@
|
||||
"browser-ide"
|
||||
],
|
||||
"engines": {
|
||||
"node": "16"
|
||||
"node": ">= 14"
|
||||
},
|
||||
"jest": {
|
||||
"transform": {
|
||||
|
||||
@@ -159,7 +159,7 @@ 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
|
||||
@@ -253,7 +253,10 @@ export class WebClientServer {
|
||||
@@ -252,7 +252,10 @@ export class WebClientServer {
|
||||
return res.end();
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
|
||||
function escapeAttribute(value: string): string {
|
||||
return value.replace(/"/g, '"');
|
||||
@@ -275,6 +278,8 @@ export class WebClientServer {
|
||||
@@ -272,6 +275,8 @@ export class WebClientServer {
|
||||
accessToken: this._environmentService.args['github-auth'],
|
||||
scopes: [['user:email'], ['repo']]
|
||||
} : undefined;
|
||||
@@ -180,15 +180,15 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
const data = (await util.promisify(fs.readFile)(filePath)).toString()
|
||||
.replace('{{WORKBENCH_WEB_CONFIGURATION}}', escapeAttribute(JSON.stringify({
|
||||
remoteAuthority,
|
||||
@@ -285,6 +290,7 @@ export class WebClientServer {
|
||||
folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']),
|
||||
workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']),
|
||||
@@ -279,6 +284,7 @@ export class WebClientServer {
|
||||
developmentOptions: { enableSmokeTestDriver: this._environmentService.driverHandle === 'web' ? true : undefined },
|
||||
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
|
||||
productConfiguration: <Partial<IProductConfiguration>>{
|
||||
+ rootEndpoint: base,
|
||||
codeServerVersion: this._productService.codeServerVersion,
|
||||
embedderIdentifier: 'server-distro',
|
||||
extensionsGallery: this._webExtensionResourceUrlTemplate ? {
|
||||
@@ -297,7 +303,9 @@ export class WebClientServer {
|
||||
@@ -291,7 +297,9 @@ export class WebClientServer {
|
||||
} : undefined
|
||||
}
|
||||
})))
|
||||
@@ -199,7 +199,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
|
||||
const cspDirectives = [
|
||||
'default-src \'self\';',
|
||||
@@ -376,3 +384,70 @@ export class WebClientServer {
|
||||
@@ -370,3 +378,70 @@ export class WebClientServer {
|
||||
return res.end(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,18 +4,12 @@ This allows the backend to distinguish them. In our case we use them to count a
|
||||
single "open" of Code so we need to be able to distinguish between web sockets
|
||||
from two instances and two web sockets used in a single instance.
|
||||
|
||||
To test this,
|
||||
1. Run code-server
|
||||
2. Open Network tab in Browser DevTools and filter for websocket requests
|
||||
3. You should see the `type=<connection-type>` in the request url
|
||||
|
||||
|
||||
Index: code-server/lib/vscode/src/vs/platform/remote/common/remoteAgentConnection.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/platform/remote/common/remoteAgentConnection.ts
|
||||
+++ code-server/lib/vscode/src/vs/platform/remote/common/remoteAgentConnection.ts
|
||||
@@ -231,7 +231,7 @@ async function connectToRemoteExtensionH
|
||||
|
||||
|
||||
let socket: ISocket;
|
||||
try {
|
||||
- socket = await createSocket(options.logService, options.socketFactory, options.host, options.port, `reconnectionToken=${options.reconnectionToken}&reconnection=${options.reconnectionProtocol ? 'true' : 'false'}`, `renderer-${connectionTypeToString(connectionType)}-${options.reconnectionToken}`, timeoutCancellationToken);
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
Prevent builtin extensions from being updated
|
||||
|
||||
Updating builtin extensions from the marketplace prevents us from patching them
|
||||
(for example out GitHub authentication patches).
|
||||
|
||||
Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts
|
||||
===================================================================
|
||||
--- 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
|
||||
@@ -206,6 +206,9 @@ export class Extension implements IExten
|
||||
if (!this.gallery || !this.local) {
|
||||
return false;
|
||||
}
|
||||
+ if (this.type !== ExtensionType.User) {
|
||||
+ return false;
|
||||
+ }
|
||||
if (!this.local.preRelease && this.gallery.properties.isPreReleaseVersion) {
|
||||
return false;
|
||||
}
|
||||
@@ -1057,6 +1060,10 @@ export class ExtensionsWorkbenchService
|
||||
// Skip if check updates only for builtin extensions and current extension is not builtin.
|
||||
continue;
|
||||
}
|
||||
+ if (installed.type !== ExtensionType.User) {
|
||||
+ // Never update builtin extensions.
|
||||
+ continue;
|
||||
+ }
|
||||
if (installed.isBuiltin && !installed.local?.identifier.uuid) {
|
||||
// Skip if the builtin extension does not have Marketplace id
|
||||
continue;
|
||||
@@ -12,7 +12,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
|
||||
@@ -215,6 +215,11 @@ export interface IWorkbenchConstructionO
|
||||
@@ -210,6 +210,11 @@ export interface IWorkbenchConstructionO
|
||||
*/
|
||||
readonly userDataPath?: string
|
||||
|
||||
@@ -66,7 +66,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -96,6 +97,7 @@ export interface ServerParsedArgs {
|
||||
@@ -92,6 +93,7 @@ export interface ServerParsedArgs {
|
||||
'disable-update-check'?: boolean;
|
||||
'auth'?: string
|
||||
'locale'?: string
|
||||
@@ -78,14 +78,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
|
||||
@@ -293,6 +293,7 @@ export class WebClientServer {
|
||||
@@ -290,6 +290,7 @@ export class WebClientServer {
|
||||
logLevel: this._logService.getLevel(),
|
||||
},
|
||||
userDataPath: this._environmentService.userDataPath,
|
||||
+ isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'],
|
||||
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
|
||||
enableWorkspaceTrust: !this._environmentService.args['disable-workspace-trust'],
|
||||
folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']),
|
||||
productConfiguration: <Partial<IProductConfiguration>>{
|
||||
rootEndpoint: base,
|
||||
Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/browser/contextkeys.ts
|
||||
@@ -135,7 +135,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions
|
||||
===================================================================
|
||||
--- 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
|
||||
@@ -22,7 +22,7 @@ import { CLOSE_SAVED_EDITORS_COMMAND_ID,
|
||||
@@ -21,7 +21,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';
|
||||
@@ -144,7 +144,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions
|
||||
import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
@@ -476,13 +476,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo
|
||||
@@ -475,13 +475,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo
|
||||
id: DOWNLOAD_COMMAND_ID,
|
||||
title: DOWNLOAD_LABEL
|
||||
},
|
||||
|
||||
@@ -6,7 +6,7 @@ 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
|
||||
@@ -192,6 +192,9 @@ export async function setupServerService
|
||||
@@ -188,6 +188,9 @@ export async function setupServerService
|
||||
const channel = new ExtensionManagementChannel(extensionManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority));
|
||||
socketServer.registerChannel('extensions', channel);
|
||||
|
||||
@@ -94,7 +94,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
|
||||
@@ -108,7 +108,7 @@ export abstract class AbstractNativeEnvi
|
||||
@@ -105,7 +105,7 @@ export abstract class AbstractNativeEnvi
|
||||
return URI.file(join(vscodePortable, 'argv.json'));
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ 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
|
||||
@@ -27,6 +27,7 @@ import { URI } from 'vs/base/common/uri'
|
||||
@@ -26,6 +26,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';
|
||||
@@ -176,7 +176,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
|
||||
const textMimeType = {
|
||||
'.html': 'text/html',
|
||||
@@ -280,6 +281,8 @@ export class WebClientServer {
|
||||
@@ -277,6 +278,8 @@ export class WebClientServer {
|
||||
} : undefined;
|
||||
const base = relativeRoot(getOriginalUrl(req))
|
||||
const vscodeBase = relativePath(getOriginalUrl(req))
|
||||
@@ -185,7 +185,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
const data = (await util.promisify(fs.readFile)(filePath)).toString()
|
||||
.replace('{{WORKBENCH_WEB_CONFIGURATION}}', escapeAttribute(JSON.stringify({
|
||||
remoteAuthority,
|
||||
@@ -309,7 +312,8 @@ export class WebClientServer {
|
||||
@@ -303,7 +306,8 @@ export class WebClientServer {
|
||||
})))
|
||||
.replace('{{WORKBENCH_AUTH_SESSION}}', () => authSessionInfo ? escapeAttribute(JSON.stringify(authSessionInfo)) : '')
|
||||
.replace(/{{BASE}}/g, base)
|
||||
@@ -207,7 +207,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -94,6 +95,7 @@ export interface ServerParsedArgs {
|
||||
@@ -90,6 +91,7 @@ export interface ServerParsedArgs {
|
||||
/* ----- code-server ----- */
|
||||
'disable-update-check'?: boolean;
|
||||
'auth'?: string
|
||||
@@ -252,7 +252,7 @@ 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
|
||||
@@ -112,6 +112,10 @@ registerSingleton(IDiagnosticsService, N
|
||||
@@ -111,6 +111,10 @@ registerSingleton(IDiagnosticsService, N
|
||||
|
||||
//#region --- workbench contributions
|
||||
|
||||
|
||||
@@ -1,104 +1,118 @@
|
||||
Add the ability to provide a GitHub token
|
||||
Use our own GitHub auth relay server
|
||||
|
||||
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.
|
||||
Microsoft's does not work with self-hosted instances so we run our own.
|
||||
|
||||
Index: code-server/lib/vscode/src/vs/platform/credentials/node/credentialsMainService.ts
|
||||
Also add an extra set of scopes so that tokens provided via --github-auth will
|
||||
work for the PR extension.
|
||||
|
||||
Index: code-server/lib/vscode/extensions/github-authentication/src/githubServer.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,18 +5,32 @@
|
||||
--- code-server.orig/lib/vscode/extensions/github-authentication/src/githubServer.ts
|
||||
+++ code-server/lib/vscode/extensions/github-authentication/src/githubServer.ts
|
||||
@@ -17,7 +17,7 @@ const localize = nls.loadMessageBundle()
|
||||
const CLIENT_ID = '01ab8ac9400c4e429b23';
|
||||
|
||||
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';
|
||||
const NETWORK_ERROR = 'network error';
|
||||
-const AUTH_RELAY_SERVER = 'vscode-auth.github.com';
|
||||
+const AUTH_RELAY_SERVER = 'auth.code-server.dev';
|
||||
// const AUTH_RELAY_STAGING_SERVER = 'client-auth-staging-14a768b.herokuapp.com';
|
||||
|
||||
class UriEventHandler extends vscode.EventEmitter<vscode.Uri> implements vscode.UriHandler {
|
||||
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
|
||||
@@ -274,7 +274,7 @@ export class WebClientServer {
|
||||
id: generateUuid(),
|
||||
providerId: 'github',
|
||||
accessToken: this._environmentService.args['github-auth'],
|
||||
- scopes: [['user:email'], ['repo']]
|
||||
+ scopes: [['read:user', 'user:email', 'repo'], ['user:email'], ['repo']]
|
||||
} : undefined;
|
||||
const base = relativeRoot(getOriginalUrl(req))
|
||||
const vscodeBase = relativePath(getOriginalUrl(req))
|
||||
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
|
||||
@@ -17,6 +17,7 @@ import { isFolderToOpen, isWorkspaceToOp
|
||||
import { create, ICredentialsProvider, IURLCallbackProvider, IWorkbenchConstructionOptions, IWorkspace, IWorkspaceProvider } from 'vs/workbench/workbench.web.main';
|
||||
import { posix } from 'vs/base/common/path';
|
||||
import { ltrim } from 'vs/base/common/strings';
|
||||
+import { equals as arrayEquals } from 'vs/base/common/arrays';
|
||||
+
|
||||
|
||||
interface ICredential {
|
||||
service: string;
|
||||
@@ -24,6 +25,13 @@ interface ICredential {
|
||||
password: string;
|
||||
}
|
||||
|
||||
+interface IToken {
|
||||
+ accessToken: string
|
||||
+ account?: { label: string }
|
||||
+ id: string
|
||||
+ scopes: string[]
|
||||
+}
|
||||
+
|
||||
class LocalStorageCredentialsProvider implements ICredentialsProvider {
|
||||
|
||||
export class CredentialsWebMainService extends BaseCredentialsMainService {
|
||||
|
||||
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)
|
||||
private static readonly CREDENTIALS_STORAGE_KEY = 'credentials.provider';
|
||||
@@ -51,6 +59,58 @@ class LocalStorageCredentialsProvider im
|
||||
scopes,
|
||||
accessToken: authSessionInfo!.accessToken
|
||||
}))));
|
||||
+
|
||||
+ // Add tokens for extensions to use. This works for extensions like the
|
||||
+ // pull requests one or GitLens.
|
||||
+ const extensionId = `vscode.${authSessionInfo.providerId}-authentication`;
|
||||
+ const service = `${product.urlProtocol}${extensionId}`;
|
||||
+ const account = `${authSessionInfo.providerId}.auth`;
|
||||
+ // 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[] = authSessionInfo.scopes.map((scopes) => ({
|
||||
+ id: authSessionInfo!.id,
|
||||
+ scopes: scopes.sort(), // Sort for comparing later.
|
||||
+ accessToken: authSessionInfo!.accessToken,
|
||||
+ }));
|
||||
+ this.getPassword(service, account).then((raw) => {
|
||||
+ let existing: {
|
||||
+ content: IToken[]
|
||||
+ } | undefined;
|
||||
+
|
||||
+ if (raw) {
|
||||
+ try {
|
||||
+ const json = JSON.parse(raw);
|
||||
+ json.content = JSON.parse(json.content);
|
||||
+ existing = json;
|
||||
+ } catch (error) {
|
||||
+ console.log(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 || []),
|
||||
+ ])
|
||||
+ }));
|
||||
+ })
|
||||
+ }
|
||||
}
|
||||
|
||||
// If the credentials service is running on the server, we add a suffix -server to differentiate from the location that the
|
||||
@@ -45,4 +59,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 || []),
|
||||
+ ])
|
||||
+ }));
|
||||
+ }
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,7 @@ may think code-server is broken. Ideally there would be a notification at the
|
||||
point where these things are used instead of this though.
|
||||
|
||||
To test access over something like an HTTP domain or an IP address (not
|
||||
localhost). For example:
|
||||
|
||||
1. run code-server
|
||||
2. use ngrok to expose code-server
|
||||
3. access via HTTP
|
||||
4. look for notification in bottom right
|
||||
localhost).
|
||||
|
||||
Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
|
||||
===================================================================
|
||||
@@ -20,7 +15,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
+import { localize } from 'vs/nls';
|
||||
+import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
|
||||
|
||||
export class CodeServerClient extends Disposable {
|
||||
constructor (
|
||||
+ @INotificationService private notificationService: INotificationService,
|
||||
|
||||
@@ -21,7 +21,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import * as perf from 'vs/base/common/performance';
|
||||
|
||||
@@ -33,38 +33,43 @@ const errorReporter: ErrorReporter = {
|
||||
@@ -33,37 +33,42 @@ const errorReporter: ErrorReporter = {
|
||||
}
|
||||
};
|
||||
|
||||
@@ -34,7 +34,6 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts
|
||||
-const USER_DATA_PATH = join(REMOTE_DATA_FOLDER, 'data');
|
||||
-const APP_SETTINGS_HOME = join(USER_DATA_PATH, 'User');
|
||||
-const GLOBAL_STORAGE_HOME = join(APP_SETTINGS_HOME, 'globalStorage');
|
||||
-const LOCAL_HISTORY_HOME = join(APP_SETTINGS_HOME, 'History');
|
||||
-const MACHINE_SETTINGS_HOME = join(USER_DATA_PATH, 'Machine');
|
||||
-args['user-data-dir'] = USER_DATA_PATH;
|
||||
-const APP_ROOT = dirname(FileAccess.asFileUri('', require).fsPath);
|
||||
@@ -42,7 +41,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts
|
||||
-args['builtin-extensions-dir'] = BUILTIN_EXTENSIONS_FOLDER_PATH;
|
||||
-args['extensions-dir'] = args['extensions-dir'] || join(REMOTE_DATA_FOLDER, 'extensions');
|
||||
-
|
||||
-[REMOTE_DATA_FOLDER, args['extensions-dir'], USER_DATA_PATH, APP_SETTINGS_HOME, MACHINE_SETTINGS_HOME, GLOBAL_STORAGE_HOME, LOCAL_HISTORY_HOME].forEach(f => {
|
||||
-[REMOTE_DATA_FOLDER, args['extensions-dir'], USER_DATA_PATH, APP_SETTINGS_HOME, MACHINE_SETTINGS_HOME, GLOBAL_STORAGE_HOME].forEach(f => {
|
||||
- try {
|
||||
- if (!fs.existsSync(f)) {
|
||||
- fs.mkdirSync(f, { mode: 0o700 });
|
||||
@@ -54,7 +53,6 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts
|
||||
+ const USER_DATA_PATH = args['user-data-dir'] || join(REMOTE_DATA_FOLDER, 'data');
|
||||
+ const APP_SETTINGS_HOME = join(USER_DATA_PATH, 'User');
|
||||
+ const GLOBAL_STORAGE_HOME = join(APP_SETTINGS_HOME, 'globalStorage');
|
||||
+ const LOCAL_HISTORY_HOME = join(APP_SETTINGS_HOME, 'History');
|
||||
+ const MACHINE_SETTINGS_HOME = join(USER_DATA_PATH, 'Machine');
|
||||
+ args['user-data-dir'] = USER_DATA_PATH;
|
||||
+ const APP_ROOT = dirname(FileAccess.asFileUri('', require).fsPath);
|
||||
@@ -62,14 +60,14 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts
|
||||
+ args['builtin-extensions-dir'] = BUILTIN_EXTENSIONS_FOLDER_PATH;
|
||||
+ args['extensions-dir'] = args['extensions-dir'] || join(REMOTE_DATA_FOLDER, 'extensions');
|
||||
+
|
||||
+ [REMOTE_DATA_FOLDER, args['extensions-dir'], USER_DATA_PATH, APP_SETTINGS_HOME, MACHINE_SETTINGS_HOME, GLOBAL_STORAGE_HOME, LOCAL_HISTORY_HOME].forEach(f => {
|
||||
+ [REMOTE_DATA_FOLDER, args['extensions-dir'], USER_DATA_PATH, APP_SETTINGS_HOME, MACHINE_SETTINGS_HOME, GLOBAL_STORAGE_HOME].forEach(f => {
|
||||
+ try {
|
||||
+ if (!fs.existsSync(f)) {
|
||||
+ fs.mkdirSync(f, { mode: 0o700 });
|
||||
+ }
|
||||
+ } catch (err) { console.error(err); }
|
||||
+ });
|
||||
+ return REMOTE_DATA_FOLDER;
|
||||
+ return REMOTE_DATA_FOLDER
|
||||
+}
|
||||
|
||||
/**
|
||||
@@ -263,9 +261,9 @@ 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
|
||||
@@ -285,6 +285,7 @@ export class WebClientServer {
|
||||
folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']),
|
||||
workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']),
|
||||
@@ -279,6 +279,7 @@ export class WebClientServer {
|
||||
developmentOptions: { enableSmokeTestDriver: this._environmentService.driverHandle === 'web' ? true : undefined },
|
||||
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
|
||||
productConfiguration: <Partial<IProductConfiguration>>{
|
||||
+ codeServerVersion: this._productService.codeServerVersion,
|
||||
embedderIdentifier: 'server-distro',
|
||||
|
||||
8
patches/last-opened.diff
Normal file
8
patches/last-opened.diff
Normal file
@@ -0,0 +1,8 @@
|
||||
Remove last opened functionality
|
||||
|
||||
This conflicts with our own handling of the last opened workspace. If we wanted
|
||||
to switch to this we would need to pass through the disable-last-opened flag and
|
||||
respect it here then remove our own redirction code that handles this.
|
||||
|
||||
Our version might be better anyway since it puts the workspace in the URL.
|
||||
|
||||
@@ -20,19 +20,19 @@ 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
|
||||
@@ -292,6 +292,7 @@ export class WebClientServer {
|
||||
@@ -289,6 +289,7 @@ export class WebClientServer {
|
||||
enableSmokeTestDriver: this._environmentService.driverHandle === 'web' ? true : undefined,
|
||||
logLevel: this._logService.getLevel(),
|
||||
},
|
||||
+ userDataPath: this._environmentService.userDataPath,
|
||||
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
|
||||
enableWorkspaceTrust: !this._environmentService.args['disable-workspace-trust'],
|
||||
folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']),
|
||||
productConfiguration: <Partial<IProductConfiguration>>{
|
||||
rootEndpoint: base,
|
||||
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
|
||||
@@ -210,6 +210,11 @@ export interface IWorkbenchConstructionO
|
||||
@@ -205,6 +205,11 @@ export interface IWorkbenchConstructionO
|
||||
*/
|
||||
readonly configurationDefaults?: Record<string, any>;
|
||||
|
||||
@@ -52,7 +52,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi
|
||||
get logFile(): URI { return joinPath(this.logsHome, 'window.log'); }
|
||||
|
||||
@memoize
|
||||
- get userRoamingDataHome(): URI { return URI.file('/User').with({ scheme: Schemas.vscodeUserData }); }
|
||||
- get userRoamingDataHome(): URI { return URI.file('/User').with({ scheme: Schemas.userData }); }
|
||||
+ get userRoamingDataHome(): URI { return joinPath(URI.file(this.userDataPath).with({ scheme: Schemas.vscodeRemote }), 'User'); }
|
||||
+
|
||||
+ get userDataPath(): string {
|
||||
|
||||
@@ -7,7 +7,7 @@ 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
|
||||
@@ -288,7 +288,10 @@ export class WebClientServer {
|
||||
@@ -285,7 +285,10 @@ export class WebClientServer {
|
||||
remoteAuthority,
|
||||
webviewEndpoint: vscodeBase + '/static/out/vs/workbench/contrib/webview/browser/pre',
|
||||
_wrapWebWorkerExtHostInIframe,
|
||||
@@ -17,5 +17,5 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
|
||||
+ logLevel: this._logService.getLevel(),
|
||||
+ },
|
||||
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
|
||||
enableWorkspaceTrust: !this._environmentService.args['disable-workspace-trust'],
|
||||
folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']),
|
||||
productConfiguration: <Partial<IProductConfiguration>>{
|
||||
rootEndpoint: base,
|
||||
|
||||
@@ -28,7 +28,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -92,6 +93,7 @@ export const serverOptions: OptionDescri
|
||||
@@ -88,6 +89,7 @@ export const serverOptions: OptionDescri
|
||||
export interface ServerParsedArgs {
|
||||
/* ----- code-server ----- */
|
||||
'disable-update-check'?: boolean;
|
||||
@@ -40,7 +40,7 @@ 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
|
||||
@@ -293,6 +293,7 @@ export class WebClientServer {
|
||||
@@ -287,6 +287,7 @@ export class WebClientServer {
|
||||
productConfiguration: <Partial<IProductConfiguration>>{
|
||||
rootEndpoint: base,
|
||||
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
|
||||
|
||||
@@ -32,7 +32,7 @@ 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
|
||||
@@ -293,14 +293,14 @@ export class WebClientServer {
|
||||
@@ -287,14 +287,14 @@ export class WebClientServer {
|
||||
rootEndpoint: base,
|
||||
codeServerVersion: this._productService.codeServerVersion,
|
||||
embedderIdentifier: 'server-distro',
|
||||
|
||||
107
patches/node-version.diff
Normal file
107
patches/node-version.diff
Normal file
@@ -0,0 +1,107 @@
|
||||
Patch the Node version to use the current version of Node
|
||||
|
||||
Previously it would use the yarnrc which results in builds that cannot run with
|
||||
the version of Node they were built with because the native modules are
|
||||
targeting the wrong version.
|
||||
|
||||
One way test this is to build in a fresh Docker container, run the build, then
|
||||
try opening the built-in terminal.
|
||||
|
||||
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
|
||||
@@ -124,9 +124,7 @@ const serverWithWebEntryPoints = [
|
||||
];
|
||||
|
||||
function getNodeVersion() {
|
||||
- const yarnrc = fs.readFileSync(path.join(REPO_ROOT, 'remote', '.yarnrc'), 'utf8');
|
||||
- const target = /^target "(.*)"$/m.exec(yarnrc)[1];
|
||||
- return target;
|
||||
+ return process.versions.node;
|
||||
}
|
||||
|
||||
const nodeVersion = getNodeVersion();
|
||||
Index: code-server/lib/vscode/build/lib/node.js
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/build/lib/node.js
|
||||
+++ code-server/lib/vscode/build/lib/node.js
|
||||
@@ -7,9 +7,7 @@ Object.defineProperty(exports, "__esModu
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const root = path.dirname(path.dirname(__dirname));
|
||||
-const yarnrcPath = path.join(root, 'remote', '.yarnrc');
|
||||
-const yarnrc = fs.readFileSync(yarnrcPath, 'utf8');
|
||||
-const version = /^target\s+"([^"]+)"$/m.exec(yarnrc)[1];
|
||||
+const version = process.versions.node;
|
||||
const platform = process.platform;
|
||||
const arch = platform === 'darwin' ? 'x64' : process.arch;
|
||||
const node = platform === 'win32' ? 'node.exe' : 'node';
|
||||
Index: code-server/lib/vscode/build/lib/node.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/build/lib/node.ts
|
||||
+++ code-server/lib/vscode/build/lib/node.ts
|
||||
@@ -7,9 +7,7 @@ import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
|
||||
const root = path.dirname(path.dirname(__dirname));
|
||||
-const yarnrcPath = path.join(root, 'remote', '.yarnrc');
|
||||
-const yarnrc = fs.readFileSync(yarnrcPath, 'utf8');
|
||||
-const version = /^target\s+"([^"]+)"$/m.exec(yarnrc)![1];
|
||||
+const version = process.versions.node;
|
||||
|
||||
const platform = process.platform;
|
||||
const arch = platform === 'darwin' ? 'x64' : process.arch;
|
||||
Index: code-server/lib/vscode/build/lib/util.js
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/build/lib/util.js
|
||||
+++ code-server/lib/vscode/build/lib/util.js
|
||||
@@ -298,9 +298,7 @@ function streamToPromise(stream) {
|
||||
}
|
||||
exports.streamToPromise = streamToPromise;
|
||||
function getElectronVersion() {
|
||||
- const yarnrc = fs.readFileSync(path.join(root, '.yarnrc'), 'utf8');
|
||||
- const target = /^target "(.*)"$/m.exec(yarnrc)[1];
|
||||
- return target;
|
||||
+ return process.versions.node;
|
||||
}
|
||||
exports.getElectronVersion = getElectronVersion;
|
||||
function acquireWebNodePaths() {
|
||||
Index: code-server/lib/vscode/build/lib/util.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/build/lib/util.ts
|
||||
+++ code-server/lib/vscode/build/lib/util.ts
|
||||
@@ -371,9 +371,7 @@ export function streamToPromise(stream:
|
||||
}
|
||||
|
||||
export function getElectronVersion(): string {
|
||||
- const yarnrc = fs.readFileSync(path.join(root, '.yarnrc'), 'utf8');
|
||||
- const target = /^target "(.*)"$/m.exec(yarnrc)![1];
|
||||
- return target;
|
||||
+ return process.versions.node;
|
||||
}
|
||||
|
||||
export function acquireWebNodePaths() {
|
||||
@@ -455,4 +453,3 @@ export function buildWebNodePaths(outDir
|
||||
result.taskName = 'build-web-node-paths';
|
||||
return result;
|
||||
}
|
||||
-
|
||||
Index: code-server/lib/vscode/remote/.yarnrc
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/remote/.yarnrc
|
||||
+++ /dev/null
|
||||
@@ -1,4 +0,0 @@
|
||||
-disturl "http://nodejs.org/dist"
|
||||
-target "14.16.0"
|
||||
-runtime "node"
|
||||
-build_from_source "true"
|
||||
Index: code-server/lib/vscode/.yarnrc
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/.yarnrc
|
||||
+++ /dev/null
|
||||
@@ -1,4 +0,0 @@
|
||||
-disturl "https://electronjs.org/headers"
|
||||
-target "13.5.2"
|
||||
-runtime "electron"
|
||||
-build_from_source "true"
|
||||
@@ -1,24 +0,0 @@
|
||||
Remove parentOriginHash checko
|
||||
|
||||
This fixes webviews from not working properly due to a change upstream.
|
||||
Upstream added a check to ensure parent authority is encoded into the webview
|
||||
origin. Since our webview origin is the parent authority, we can bypass this
|
||||
check.
|
||||
|
||||
Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/main.js
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/main.js
|
||||
+++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/main.js
|
||||
@@ -317,6 +317,12 @@ const hostMessaging = new class HostMess
|
||||
const id = searchParams.get('id');
|
||||
|
||||
const hostname = location.hostname;
|
||||
+
|
||||
+ // It is safe to run if we are on the same host.
|
||||
+ const parent = new URL(parentOrigin)
|
||||
+ if (parent.hostname == location.hostname) {
|
||||
+ return start(parentOrigin)
|
||||
+ }
|
||||
|
||||
if (!crypto.subtle) {
|
||||
// cannot validate, not running in a secure context
|
||||
26
patches/post-install.diff
Normal file
26
patches/post-install.diff
Normal file
@@ -0,0 +1,26 @@
|
||||
Replace rimraf with fs.rmSync in postinstall
|
||||
|
||||
The postinstall gets ran when you install with npm but rimraf is a development
|
||||
dependency so it will not exist.
|
||||
|
||||
Index: code-server/lib/vscode/extensions/postinstall.js
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/extensions/postinstall.js
|
||||
+++ code-server/lib/vscode/extensions/postinstall.js
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
-const rimraf = require('rimraf');
|
||||
|
||||
const root = path.join(__dirname, 'node_modules', 'typescript');
|
||||
|
||||
@@ -21,7 +20,7 @@ function processRoot() {
|
||||
if (!toKeep.has(name)) {
|
||||
const filePath = path.join(root, name);
|
||||
console.log(`Removed ${filePath}`);
|
||||
- rimraf.sync(filePath);
|
||||
+ fs.rmSync(filePath, { recursive: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/abstra
|
||||
===================================================================
|
||||
--- 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
|
||||
@@ -1471,7 +1471,7 @@ class ProposedApiController {
|
||||
@@ -1163,7 +1163,7 @@ class ProposedApiController {
|
||||
|
||||
this._envEnabledExtensions = new Set((_environmentService.extensionEnabledProposedApi ?? []).map(id => ExtensionIdentifier.toKey(id)));
|
||||
|
||||
@@ -22,7 +22,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/extens
|
||||
===================================================================
|
||||
--- 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
|
||||
@@ -163,10 +163,7 @@ export interface IExtensionHost {
|
||||
@@ -134,10 +134,7 @@ export interface IExtensionHost {
|
||||
}
|
||||
|
||||
export function isProposedApiEnabled(extension: IExtensionDescription, proposal: ApiProposalName): boolean {
|
||||
|
||||
@@ -68,7 +68,7 @@ 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
|
||||
@@ -294,6 +294,7 @@ export class WebClientServer {
|
||||
@@ -288,6 +288,7 @@ export class WebClientServer {
|
||||
rootEndpoint: base,
|
||||
updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
|
||||
logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined,
|
||||
@@ -93,7 +93,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalE
|
||||
===================================================================
|
||||
--- 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
|
||||
@@ -388,7 +388,7 @@ export function createTerminalEnvironmen
|
||||
@@ -390,7 +390,7 @@ export function createTerminalEnvironmen
|
||||
|
||||
// Sanitize the environment, removing any undesirable VS Code and Electron environment
|
||||
// variables
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
integration.diff
|
||||
node-version.diff
|
||||
base-path.diff
|
||||
proposed-api.diff
|
||||
marketplace.diff
|
||||
webview.diff
|
||||
disable-builtin-ext-update.diff
|
||||
insecure-notification.diff
|
||||
update-check.diff
|
||||
logout.diff
|
||||
@@ -12,10 +12,10 @@ proxy-uri.diff
|
||||
display-language.diff
|
||||
github-auth.diff
|
||||
unique-db.diff
|
||||
post-install.diff
|
||||
log-level.diff
|
||||
local-storage.diff
|
||||
service-worker.diff
|
||||
connection-type.diff
|
||||
sourcemaps.diff
|
||||
disable-downloads.diff
|
||||
telemetry.diff
|
||||
|
||||
@@ -21,7 +21,7 @@ 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,10 @@ export class WebClientServer {
|
||||
@@ -298,6 +298,10 @@ export class WebClientServer {
|
||||
proxyEndpointTemplate: base + '/proxy/{{port}}',
|
||||
codeServerVersion: this._productService.codeServerVersion,
|
||||
embedderIdentifier: 'server-distro',
|
||||
|
||||
@@ -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
|
||||
@@ -191,8 +191,7 @@ function packageTask(type, platform, arc
|
||||
@@ -197,8 +197,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) => {
|
||||
@@ -231,9 +230,9 @@ function packageTask(type, platform, arc
|
||||
@@ -237,9 +236,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;
|
||||
@@ -368,7 +367,7 @@ function tweakProductForServerWeb(produc
|
||||
@@ -374,7 +373,7 @@ function tweakProductForServerWeb(produc
|
||||
const minifyTask = task.define(`minify-vscode-${type}`, task.series(
|
||||
optimizeTask,
|
||||
util.rimraf(`out-vscode-${type}-min`),
|
||||
|
||||
@@ -3,12 +3,6 @@ Store a static reference to the IPC socket
|
||||
This lets us use it to open files inside code-server from outside of
|
||||
code-server.
|
||||
|
||||
To test this:
|
||||
1. run code-server
|
||||
2. open file outside of code-server i.e. `code-server <path-to-file`
|
||||
|
||||
It should open in your existing code-server instance.
|
||||
|
||||
Index: code-server/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.ts
|
||||
|
||||
@@ -1,212 +0,0 @@
|
||||
Add support for telemetry endpoint
|
||||
|
||||
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
|
||||
@@ -68,6 +68,7 @@ import { REMOTE_TERMINAL_CHANNEL_NAME }
|
||||
import { RemoteExtensionLogFileName } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
import { REMOTE_FILE_SYSTEM_CHANNEL_NAME } from 'vs/workbench/services/remote/common/remoteFileSystemProviderClient';
|
||||
import { ExtensionHostStatusService, IExtensionHostStatusService } from 'vs/server/node/extensionHostStatusService';
|
||||
+import { TelemetryClient } from "vs/server/node/telemetryClient";
|
||||
|
||||
const eventPrefix = 'monacoworkbench';
|
||||
|
||||
@@ -120,7 +121,11 @@ export async function setupServerService
|
||||
let appInsightsAppender: ITelemetryAppender = NullAppender;
|
||||
const machineId = await getMachineId();
|
||||
if (supportsTelemetry(productService, environmentService)) {
|
||||
- if (productService.aiConfig && productService.aiConfig.asimovKey) {
|
||||
+ const telemetryEndpoint = process.env.CS_TELEMETRY_URL || "https://v1.telemetry.coder.com/track";
|
||||
+ if (telemetryEndpoint) {
|
||||
+ appInsightsAppender = new AppInsightsAppender(eventPrefix, null, () => new TelemetryClient(telemetryEndpoint) as any);
|
||||
+ disposables.add(toDisposable(() => appInsightsAppender!.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
|
||||
+ } else if (productService.aiConfig && productService.aiConfig.asimovKey) {
|
||||
appInsightsAppender = new AppInsightsAppender(eventPrefix, null, productService.aiConfig.asimovKey);
|
||||
disposables.add(toDisposable(() => appInsightsAppender!.flush())); // Ensure the AI appender is disposed so that it flushes remaining data
|
||||
}
|
||||
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,135 @@
|
||||
+import * as appInsights from 'applicationinsights';
|
||||
+import * as https from 'https';
|
||||
+import * as http from 'http';
|
||||
+import * as os from 'os';
|
||||
+
|
||||
+class Channel {
|
||||
+ public get _sender() {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+ public get _buffer() {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public setUseDiskRetryCaching(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+ public send(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+ public triggerSend(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+// Unable to use implements because TypeScript tells you a private property is
|
||||
+// missing but if you add it then it complains they have different private
|
||||
+// properties. Uncommenting it during development can be helpful though to see
|
||||
+// if anything is missing.
|
||||
+export class TelemetryClient /* implements appInsights.TelemetryClient */ {
|
||||
+ private _telemetryProcessors: any = undefined;
|
||||
+ public context: any = undefined;
|
||||
+ public commonProperties: any = undefined;
|
||||
+ public config: any = {};
|
||||
+ public quickPulseClient: any = undefined;
|
||||
+
|
||||
+ public channel: any = new Channel();
|
||||
+
|
||||
+ public constructor(private readonly endpoint: string) {
|
||||
+ // Nothing to do.
|
||||
+ }
|
||||
+
|
||||
+ public addTelemetryProcessor(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public clearTelemetryProcessors(): void {
|
||||
+ if (this._telemetryProcessors) {
|
||||
+ this._telemetryProcessors = undefined;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public runTelemetryProcessors(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackTrace(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackMetric(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackException(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackRequest(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackDependency(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public track(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackNodeHttpRequestSync(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackNodeHttpRequest(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackNodeHttpDependency(): void {
|
||||
+ throw new Error('unimplemented');
|
||||
+ }
|
||||
+
|
||||
+ public trackEvent(options: appInsights.Contracts.EventTelemetry): void {
|
||||
+ if (!options.properties) {
|
||||
+ options.properties = {};
|
||||
+ }
|
||||
+ if (!options.measurements) {
|
||||
+ options.measurements = {};
|
||||
+ }
|
||||
+
|
||||
+ try {
|
||||
+ const cpus = os.cpus();
|
||||
+ options.measurements.cores = cpus.length;
|
||||
+ options.properties['common.cpuModel'] = cpus[0].model;
|
||||
+ } catch (error) {}
|
||||
+
|
||||
+ try {
|
||||
+ options.measurements.memoryFree = os.freemem();
|
||||
+ options.measurements.memoryTotal = os.totalmem();
|
||||
+ } catch (error) {}
|
||||
+
|
||||
+ try {
|
||||
+ options.properties['common.shell'] = os.userInfo().shell;
|
||||
+ options.properties['common.release'] = os.release();
|
||||
+ options.properties['common.arch'] = os.arch();
|
||||
+ } catch (error) {}
|
||||
+
|
||||
+ try {
|
||||
+ const request = (/^http:/.test(this.endpoint) ? http : https).request(this.endpoint, {
|
||||
+ method: 'POST',
|
||||
+ headers: {
|
||||
+ 'Content-Type': 'application/json',
|
||||
+ },
|
||||
+ });
|
||||
+ request.on('error', () => { /* We don't care. */ });
|
||||
+ request.write(JSON.stringify(options));
|
||||
+ request.end();
|
||||
+ } catch (error) {}
|
||||
+ }
|
||||
+
|
||||
+ public flush(options: { callback: (v: string) => void }): void {
|
||||
+ if (options.callback) {
|
||||
+ options.callback('');
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
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 {
|
||||
logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined,
|
||||
proxyEndpointTemplate: base + '/proxy/{{port}}',
|
||||
codeServerVersion: this._productService.codeServerVersion,
|
||||
+ enableTelemetry: this._productService.enableTelemetry,
|
||||
embedderIdentifier: 'server-distro',
|
||||
serviceWorker: {
|
||||
scope: vscodeBase + '/',
|
||||
Index: code-server/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts
|
||||
@@ -119,16 +119,19 @@ export class TelemetryService extends Di
|
||||
) {
|
||||
super();
|
||||
|
||||
- if (supportsTelemetry(productService, environmentService) && productService.aiConfig?.asimovKey) {
|
||||
+ if (supportsTelemetry(productService, environmentService)) {
|
||||
// If remote server is present send telemetry through that, else use the client side appender
|
||||
- const telemetryProvider: ITelemetryAppender = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : new WebAppInsightsAppender('monacoworkbench', productService.aiConfig?.asimovKey);
|
||||
- const config: ITelemetryServiceConfig = {
|
||||
- appenders: [new WebTelemetryAppender(telemetryProvider), new TelemetryLogAppender(loggerService, environmentService)],
|
||||
- commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.remoteAuthority, productService.embedderIdentifier, productService.removeTelemetryMachineId, environmentService.options && environmentService.options.resolveCommonTelemetryProperties),
|
||||
- sendErrorTelemetry: this.sendErrorTelemetry,
|
||||
- };
|
||||
-
|
||||
- this.impl = this._register(new BaseTelemetryService(config, configurationService, productService));
|
||||
+ const telemetryProvider: ITelemetryAppender | undefined = remoteAgentService.getConnection() !== null ? { log: remoteAgentService.logTelemetry.bind(remoteAgentService), flush: remoteAgentService.flushTelemetry.bind(remoteAgentService) } : productService.aiConfig?.asimovKey ? new WebAppInsightsAppender('monacoworkbench', productService.aiConfig?.asimovKey) : undefined;
|
||||
+ if (telemetryProvider) {
|
||||
+ const config: ITelemetryServiceConfig = {
|
||||
+ appenders: [new WebTelemetryAppender(telemetryProvider), new TelemetryLogAppender(loggerService, environmentService)],
|
||||
+ commonProperties: resolveWorkbenchCommonProperties(storageService, productService.commit, productService.version, environmentService.remoteAuthority, productService.embedderIdentifier, productService.removeTelemetryMachineId, environmentService.options && environmentService.options.resolveCommonTelemetryProperties),
|
||||
+ sendErrorTelemetry: this.sendErrorTelemetry,
|
||||
+ };
|
||||
+ this.impl = this._register(new BaseTelemetryService(config, configurationService, productService));
|
||||
+ } else {
|
||||
+ this.impl = NullTelemetryService;
|
||||
+ }
|
||||
} else {
|
||||
this.impl = NullTelemetryService;
|
||||
}
|
||||
@@ -3,11 +3,6 @@ Add a notification that lets you know when an update is out
|
||||
The easiest way to test this is probably to change the version in your
|
||||
package.json and delete the last notification storage item.
|
||||
|
||||
1. change version in root `package.json`
|
||||
2. Open DevTools > Application > Storage (top-level)
|
||||
3. Click "Clear site data"
|
||||
4. See update notification
|
||||
|
||||
Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/browser/client.ts
|
||||
@@ -19,7 +14,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
+import { IProductService } from 'vs/platform/product/common/productService';
|
||||
+import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
|
||||
|
||||
export class CodeServerClient extends Disposable {
|
||||
constructor (
|
||||
+ @ILogService private logService: ILogService,
|
||||
@@ -98,15 +93,15 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts
|
||||
readonly codeServerVersion?: string
|
||||
readonly rootEndpoint?: string
|
||||
+ readonly updateEndpoint?: string
|
||||
|
||||
|
||||
readonly version: string;
|
||||
readonly date?: string;
|
||||
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
|
||||
@@ -292,6 +292,7 @@ export class WebClientServer {
|
||||
workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']),
|
||||
@@ -286,6 +286,7 @@ export class WebClientServer {
|
||||
settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined,
|
||||
productConfiguration: <Partial<IProductConfiguration>>{
|
||||
rootEndpoint: base,
|
||||
+ updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined,
|
||||
@@ -119,19 +114,19 @@ Index: code-server/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';
|
||||
|
||||
|
||||
export const serverOptions: OptionDescriptions<ServerParsedArgs> = {
|
||||
+ /* ----- code-server ----- */
|
||||
+ 'disable-update-check': { type: 'boolean' },
|
||||
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
@@ -88,6 +90,8 @@ export const serverOptions: OptionDescri
|
||||
|
||||
@@ -84,6 +86,8 @@ export const serverOptions: OptionDescri
|
||||
};
|
||||
|
||||
|
||||
export interface ServerParsedArgs {
|
||||
+ /* ----- code-server ----- */
|
||||
+ 'disable-update-check'?: boolean;
|
||||
|
||||
|
||||
/* ----- server setup ----- */
|
||||
|
||||
|
||||
|
||||
@@ -15,16 +15,13 @@ Since this code exists only for the authentication case we can just skip it when
|
||||
it is served from the current host as authentication is not a problem if the
|
||||
request is not cross-origin.
|
||||
|
||||
There is also an origin check we bypass (this seems to be related to how the
|
||||
webview host is separate by default but we serve on the same host).
|
||||
|
||||
To test, open a few types of webviews (images, markdown, extension details, etc).
|
||||
|
||||
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
|
||||
@@ -179,7 +179,7 @@ export class BrowserWorkbenchEnvironment
|
||||
@@ -176,7 +176,7 @@ export class BrowserWorkbenchEnvironment
|
||||
|
||||
@memoize
|
||||
get webviewExternalEndpoint(): string {
|
||||
@@ -37,7 +34,7 @@ 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
|
||||
@@ -283,6 +283,7 @@ export class WebClientServer {
|
||||
@@ -280,6 +280,7 @@ export class WebClientServer {
|
||||
const data = (await util.promisify(fs.readFile)(filePath)).toString()
|
||||
.replace('{{WORKBENCH_WEB_CONFIGURATION}}', escapeAttribute(JSON.stringify({
|
||||
remoteAuthority,
|
||||
@@ -49,7 +46,7 @@ Index: code-server/lib/vscode/src/vs/workbench/common/webview.ts
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/common/webview.ts
|
||||
+++ code-server/lib/vscode/src/vs/workbench/common/webview.ts
|
||||
@@ -22,7 +22,7 @@ export const webviewResourceBaseHost = '
|
||||
@@ -24,7 +24,7 @@ export const webviewResourceBaseHost = '
|
||||
|
||||
export const webviewRootResourceAuthority = `vscode-resource.${webviewResourceBaseHost}`;
|
||||
|
||||
@@ -77,20 +74,3 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/servi
|
||||
switch (event.request.method) {
|
||||
case 'GET':
|
||||
case 'HEAD':
|
||||
Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/main.js
|
||||
===================================================================
|
||||
--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/main.js
|
||||
+++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/main.js
|
||||
@@ -318,6 +318,12 @@ const hostMessaging = new class HostMess
|
||||
|
||||
const hostname = location.hostname;
|
||||
|
||||
+ // It is safe to run if we are on the same host.
|
||||
+ const parent = new URL(parentOrigin)
|
||||
+ if (parent.hostname === location.hostname) {
|
||||
+ return start(parentOrigin)
|
||||
+ }
|
||||
+
|
||||
if (!crypto.subtle) {
|
||||
// cannot validate, not running in a secure context
|
||||
throw new Error(`Cannot validate in current context!`);
|
||||
|
||||
@@ -94,8 +94,7 @@ export const ensureAddress = (server: http.Server, protocol: string): URL | stri
|
||||
}
|
||||
|
||||
if (typeof addr !== "string") {
|
||||
const host = addr.family === "IPv6" ? `[${addr.address}]` : addr.address
|
||||
return new URL(`${protocol}://${host}:${addr.port}`)
|
||||
return new URL(`${protocol}://${addr.address}:${addr.port}`)
|
||||
}
|
||||
|
||||
// If this is a string then it is a pipe or Unix socket.
|
||||
|
||||
@@ -542,7 +542,7 @@ export async function setDefaults(cliArgs: UserProvidedArgs, configArgs?: Config
|
||||
args.password = process.env.PASSWORD
|
||||
}
|
||||
|
||||
if (process.env.CS_DISABLE_FILE_DOWNLOADS?.match(/^(1|true)$/)) {
|
||||
if (process.env.CS_DISABLE_FILE_DOWNLOADS === "1") {
|
||||
args["disable-file-downloads"] = true
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,7 @@ export class Heart {
|
||||
private heartbeatInterval = 60000
|
||||
public lastHeartbeat = 0
|
||||
|
||||
public constructor(private readonly heartbeatPath: string, private readonly isActive: () => Promise<boolean>) {
|
||||
this.beat = this.beat.bind(this)
|
||||
this.alive = this.alive.bind(this)
|
||||
}
|
||||
public constructor(private readonly heartbeatPath: string, private readonly isActive: () => Promise<boolean>) {}
|
||||
|
||||
public alive(): boolean {
|
||||
const now = Date.now()
|
||||
@@ -23,22 +20,30 @@ export class Heart {
|
||||
* timeout and start or reset a timer that keeps running as long as there is
|
||||
* activity. Failures are logged as warnings.
|
||||
*/
|
||||
public async beat(): Promise<void> {
|
||||
public beat(): void {
|
||||
if (this.alive()) {
|
||||
return
|
||||
}
|
||||
|
||||
logger.trace("heartbeat")
|
||||
fs.writeFile(this.heartbeatPath, "").catch((error) => {
|
||||
logger.warn(error.message)
|
||||
})
|
||||
this.lastHeartbeat = Date.now()
|
||||
if (typeof this.heartbeatTimer !== "undefined") {
|
||||
clearTimeout(this.heartbeatTimer)
|
||||
}
|
||||
this.heartbeatTimer = setTimeout(() => heartbeatTimer(this.isActive, this.beat), this.heartbeatInterval)
|
||||
try {
|
||||
return await fs.writeFile(this.heartbeatPath, "")
|
||||
} catch (error: any) {
|
||||
logger.warn(error.message)
|
||||
}
|
||||
this.heartbeatTimer = setTimeout(() => {
|
||||
this.isActive()
|
||||
.then((active) => {
|
||||
if (active) {
|
||||
this.beat()
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
logger.warn(error.message)
|
||||
})
|
||||
}, this.heartbeatInterval)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,20 +55,3 @@ export class Heart {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for the heartbeatTimer.
|
||||
*
|
||||
* If heartbeat is active, call beat. Otherwise do nothing.
|
||||
*
|
||||
* Extracted to make it easier to test.
|
||||
*/
|
||||
export async function heartbeatTimer(isActive: Heart["isActive"], beat: Heart["beat"]) {
|
||||
try {
|
||||
if (await isActive()) {
|
||||
beat()
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
logger.warn((error as Error).message)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,8 +56,6 @@ export const register = async (app: App, args: DefaultedArgs): Promise<Disposabl
|
||||
// /healthz|/healthz/ needs to be excluded otherwise health checks will make
|
||||
// it look like code-server is always in use.
|
||||
if (!/^\/healthz\/?$/.test(req.url)) {
|
||||
// NOTE@jsjoeio - intentionally not awaiting the .beat() call here because
|
||||
// we don't want to slow down the request.
|
||||
heart.beat()
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ export class SocketProxyProvider {
|
||||
this.proxyPipe = pipe
|
||||
return Promise.all([
|
||||
fs.mkdir(path.dirname(this.proxyPipe), { recursive: true }),
|
||||
fs.rm(this.proxyPipe, { force: true, recursive: true }),
|
||||
fs.rmdir(this.proxyPipe, { recursive: true }),
|
||||
])
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
@@ -203,9 +203,8 @@ class ChildProcess extends Process {
|
||||
|
||||
/**
|
||||
* Parent process wrapper that spawns the child process and performs a handshake
|
||||
* with it. Will relaunch the child if it receives a SIGUSR1 or SIGUSR2 or is
|
||||
* asked to by the child. If the child otherwise exits the parent will also
|
||||
* exit.
|
||||
* with it. Will relaunch the child if it receives a SIGUSR1 or is asked to by
|
||||
* the child. If the child otherwise exits the parent will also exit.
|
||||
*/
|
||||
export class ParentProcess extends Process {
|
||||
public logger = logger.named(`parent:${process.pid}`)
|
||||
@@ -228,11 +227,6 @@ export class ParentProcess extends Process {
|
||||
this.relaunch()
|
||||
})
|
||||
|
||||
process.on("SIGUSR2", async () => {
|
||||
this.logger.info("Received SIGUSR2; hotswapping")
|
||||
this.relaunch()
|
||||
})
|
||||
|
||||
const opts = {
|
||||
size: "10M",
|
||||
maxFiles: 10,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { promises as fs } from "fs"
|
||||
import * as path from "path"
|
||||
import { promises as fs } from "fs"
|
||||
import { clean } from "../utils/helpers"
|
||||
import { describe, test, expect } from "./baseFixture"
|
||||
|
||||
|
||||
@@ -81,9 +81,6 @@ export class CodeServer {
|
||||
path.join(dir, "User/settings.json"),
|
||||
JSON.stringify({
|
||||
"workbench.startupEditor": "none",
|
||||
// NOTE@jsjoeio - needed to prevent Trust Policy prompt
|
||||
// in end-to-end tests.
|
||||
"security.workspace.trust.enabled": false,
|
||||
}),
|
||||
"utf8",
|
||||
)
|
||||
|
||||
@@ -152,20 +152,10 @@ describe("ensureAddress", () => {
|
||||
it("should throw and error if no address", () => {
|
||||
expect(() => ensureAddress(mockServer, "http")).toThrow("Server has no address")
|
||||
})
|
||||
it("should return the address if it's a string", async () => {
|
||||
mockServer.address = () => "/path/to/unix.sock"
|
||||
it("should return the address if it exists", async () => {
|
||||
mockServer.address = () => "http://localhost:8080/"
|
||||
const address = ensureAddress(mockServer, "http")
|
||||
expect(address.toString()).toBe(`/path/to/unix.sock`)
|
||||
})
|
||||
it("should construct URL with an IPv4 address", async () => {
|
||||
mockServer.address = () => ({ address: "1.2.3.4", port: 5678, family: "IPv4" })
|
||||
const address = ensureAddress(mockServer, "http")
|
||||
expect(address.toString()).toBe(`http://1.2.3.4:5678/`)
|
||||
})
|
||||
it("should construct URL with an IPv6 address", async () => {
|
||||
mockServer.address = () => ({ address: "a:b:c:d::1234", port: 5678, family: "IPv6" })
|
||||
const address = ensureAddress(mockServer, "http")
|
||||
expect(address.toString()).toBe(`http://[a:b:c:d::1234]:5678/`)
|
||||
expect(address.toString()).toBe(`http://localhost:8080/`)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -362,18 +362,6 @@ describe("parser", () => {
|
||||
})
|
||||
})
|
||||
|
||||
it("should use env var CS_DISABLE_FILE_DOWNLOADS set to true", async () => {
|
||||
process.env.CS_DISABLE_FILE_DOWNLOADS = "true"
|
||||
const args = parse([])
|
||||
expect(args).toEqual({})
|
||||
|
||||
const defaultArgs = await setDefaults(args)
|
||||
expect(defaultArgs).toEqual({
|
||||
...defaults,
|
||||
"disable-file-downloads": true,
|
||||
})
|
||||
})
|
||||
|
||||
it("should error if password passed in", () => {
|
||||
expect(() => parse(["--password", "supersecret123"])).toThrowError(
|
||||
"--password can only be set in the config file or passed in via $PASSWORD",
|
||||
@@ -458,7 +446,7 @@ describe("cli", () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
delete process.env.VSCODE_IPC_HOOK_CLI
|
||||
await fs.rm(vscodeIpcPath, { force: true, recursive: true })
|
||||
await fs.rmdir(vscodeIpcPath, { recursive: true })
|
||||
})
|
||||
|
||||
it("should use existing if inside code-server", async () => {
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
import { logger } from "@coder/logger"
|
||||
import { readFile, writeFile, stat, utimes } from "fs/promises"
|
||||
import { Heart, heartbeatTimer } from "../../../src/node/heart"
|
||||
import { clean, mockLogger, tmpdir } from "../../utils/helpers"
|
||||
|
||||
const mockIsActive = (resolveTo: boolean) => jest.fn().mockResolvedValue(resolveTo)
|
||||
|
||||
describe("Heart", () => {
|
||||
const testName = "heartTests"
|
||||
let testDir = ""
|
||||
let heart: Heart
|
||||
|
||||
beforeAll(async () => {
|
||||
mockLogger()
|
||||
await clean(testName)
|
||||
testDir = await tmpdir(testName)
|
||||
})
|
||||
beforeEach(() => {
|
||||
heart = new Heart(`${testDir}/shutdown.txt`, mockIsActive(true))
|
||||
})
|
||||
afterAll(() => {
|
||||
jest.restoreAllMocks()
|
||||
})
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks()
|
||||
jest.useRealTimers()
|
||||
if (heart) {
|
||||
heart.dispose()
|
||||
}
|
||||
})
|
||||
it("should write to a file when given a valid file path", async () => {
|
||||
// Set up heartbeat file with contents
|
||||
const text = "test"
|
||||
const pathToFile = `${testDir}/file.txt`
|
||||
await writeFile(pathToFile, text)
|
||||
const fileContents = await readFile(pathToFile, { encoding: "utf8" })
|
||||
// Explicitly set the modified time to 0 so that we can check
|
||||
// that the file was indeed modified after calling heart.beat().
|
||||
// This works around any potential race conditions.
|
||||
// Docs: https://nodejs.org/api/fs.html#fspromisesutimespath-atime-mtime
|
||||
await utimes(pathToFile, 0, 0)
|
||||
|
||||
expect(fileContents).toBe(text)
|
||||
|
||||
heart = new Heart(pathToFile, mockIsActive(true))
|
||||
await heart.beat()
|
||||
// Check that the heart wrote to the heartbeatFilePath and overwrote our text
|
||||
const fileContentsAfterBeat = await readFile(pathToFile, { encoding: "utf8" })
|
||||
expect(fileContentsAfterBeat).not.toBe(text)
|
||||
// Make sure the modified timestamp was updated.
|
||||
const fileStatusAfterEdit = await stat(pathToFile)
|
||||
expect(fileStatusAfterEdit.mtimeMs).toBeGreaterThan(0)
|
||||
})
|
||||
it("should log a warning when given an invalid file path", async () => {
|
||||
heart = new Heart(`fakeDir/fake.txt`, mockIsActive(false))
|
||||
await heart.beat()
|
||||
expect(logger.warn).toHaveBeenCalled()
|
||||
})
|
||||
it("should be active after calling beat", async () => {
|
||||
await heart.beat()
|
||||
|
||||
const isAlive = heart.alive()
|
||||
expect(isAlive).toBe(true)
|
||||
})
|
||||
it("should not be active after dispose is called", () => {
|
||||
heart.dispose()
|
||||
|
||||
const isAlive = heart.alive()
|
||||
expect(isAlive).toBe(false)
|
||||
})
|
||||
it("should beat twice without warnings", async () => {
|
||||
// Use fake timers so we can speed up setTimeout
|
||||
jest.useFakeTimers()
|
||||
heart = new Heart(`${testDir}/hello.txt`, mockIsActive(true))
|
||||
await heart.beat()
|
||||
// we need to speed up clocks, timeouts
|
||||
// call heartbeat again (and it won't be alive I think)
|
||||
// then assert no warnings were called
|
||||
jest.runAllTimers()
|
||||
expect(logger.warn).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe("heartbeatTimer", () => {
|
||||
beforeAll(() => {
|
||||
mockLogger()
|
||||
})
|
||||
afterAll(() => {
|
||||
jest.restoreAllMocks()
|
||||
})
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks()
|
||||
})
|
||||
it("should call beat when isActive resolves to true", async () => {
|
||||
const isActive = true
|
||||
const mockIsActive = jest.fn().mockResolvedValue(isActive)
|
||||
const mockBeatFn = jest.fn()
|
||||
await heartbeatTimer(mockIsActive, mockBeatFn)
|
||||
expect(mockIsActive).toHaveBeenCalled()
|
||||
expect(mockBeatFn).toHaveBeenCalled()
|
||||
})
|
||||
it("should log a warning when isActive rejects", async () => {
|
||||
const errorMsg = "oh no"
|
||||
const error = new Error(errorMsg)
|
||||
const mockIsActive = jest.fn().mockRejectedValue(error)
|
||||
const mockBeatFn = jest.fn()
|
||||
await heartbeatTimer(mockIsActive, mockBeatFn)
|
||||
expect(mockIsActive).toHaveBeenCalled()
|
||||
expect(mockBeatFn).not.toHaveBeenCalled()
|
||||
expect(logger.warn).toHaveBeenCalledWith(errorMsg)
|
||||
})
|
||||
})
|
||||
@@ -53,7 +53,7 @@ describe("SocketProxyProvider", () => {
|
||||
|
||||
await fs.mkdir(path.join(tmpdir, "tests"), { recursive: true })
|
||||
const socketPath = await provider.findFreeSocketPath(path.join(tmpdir, "tests/tls-socket-proxy"))
|
||||
await fs.rm(socketPath, { force: true, recursive: true })
|
||||
await fs.rmdir(socketPath, { recursive: true })
|
||||
|
||||
return new Promise<void>((_resolve) => {
|
||||
const resolved: { [key: string]: boolean } = { client: false, server: false }
|
||||
|
||||
@@ -131,8 +131,7 @@ describe("update", () => {
|
||||
|
||||
await expect(settings().read()).resolves.toEqual({ update })
|
||||
expect(isNaN(update.checked)).toEqual(false)
|
||||
expect(update.checked).toBeGreaterThanOrEqual(now)
|
||||
expect(update.checked).toBeLessThanOrEqual(Date.now())
|
||||
expect(update.checked < Date.now() && update.checked >= now).toEqual(true)
|
||||
expect(update.version).toStrictEqual("2.1.0")
|
||||
expect(spy).toEqual(["/latest"])
|
||||
})
|
||||
@@ -146,7 +145,7 @@ describe("update", () => {
|
||||
|
||||
await expect(settings().read()).resolves.toEqual({ update })
|
||||
expect(isNaN(update.checked)).toStrictEqual(false)
|
||||
expect(update.checked).toBeLessThanOrEqual(now)
|
||||
expect(update.checked < now).toBe(true)
|
||||
expect(update.version).toStrictEqual("2.1.0")
|
||||
expect(spy).toEqual([])
|
||||
})
|
||||
@@ -160,8 +159,7 @@ describe("update", () => {
|
||||
|
||||
await expect(settings().read()).resolves.toEqual({ update })
|
||||
expect(isNaN(update.checked)).toStrictEqual(false)
|
||||
expect(update.checked).toBeGreaterThanOrEqual(now)
|
||||
expect(update.checked).toBeLessThanOrEqual(Date.now())
|
||||
expect(update.checked < Date.now() && update.checked >= now).toStrictEqual(true)
|
||||
expect(update.version).toStrictEqual("4.1.1")
|
||||
expect(spy).toStrictEqual(["/latest"])
|
||||
})
|
||||
@@ -206,16 +204,14 @@ describe("update", () => {
|
||||
let now = Date.now()
|
||||
let update = await provider.getUpdate(true)
|
||||
expect(isNaN(update.checked)).toStrictEqual(false)
|
||||
expect(update.checked).toBeGreaterThanOrEqual(now)
|
||||
expect(update.checked).toBeLessThanOrEqual(Date.now())
|
||||
expect(update.checked < Date.now() && update.checked >= now).toEqual(true)
|
||||
expect(update.version).toStrictEqual("unknown")
|
||||
|
||||
provider = new UpdateProvider("http://probably.invalid.dev.localhost/latest", settings())
|
||||
now = Date.now()
|
||||
update = await provider.getUpdate(true)
|
||||
expect(isNaN(update.checked)).toStrictEqual(false)
|
||||
expect(update.checked).toBeGreaterThanOrEqual(now)
|
||||
expect(update.checked).toBeLessThanOrEqual(Date.now())
|
||||
expect(update.checked < Date.now() && update.checked >= now).toEqual(true)
|
||||
expect(update.version).toStrictEqual("unknown")
|
||||
})
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ export function mockLogger() {
|
||||
*/
|
||||
export async function clean(testName: string): Promise<void> {
|
||||
const dir = path.join(os.tmpdir(), `code-server/tests/${testName}`)
|
||||
await fs.rm(dir, { force: true, recursive: true })
|
||||
await fs.rmdir(dir, { recursive: true })
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user