Skip to content

Cookie Expiration Age Fix #7327

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ Code v99.99.999

## Unreleased

## [4.99.3](https://github.com/coder/code-server/releases/tag/v4.99.3) - 2025-04-17

Code v1.99.3

### Added

- Added `--skip-auth-preflight` flag to let preflight requests through the
proxy.

### Changed

- Update to Code 1.99.3.

## [4.99.2](https://github.com/coder/code-server/releases/tag/v4.99.2) - 2025-04-10

Code v1.99.2
Expand Down
4 changes: 2 additions & 2 deletions ci/helm-chart/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 3.26.2
version: 3.26.3

# 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.99.2
appVersion: 4.99.3
2 changes: 1 addition & 1 deletion ci/helm-chart/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ replicaCount: 1

image:
repository: codercom/code-server
tag: '4.99.2'
tag: '4.99.3'
pullPolicy: Always

# Specifies one or more secrets to be used when pulling images from a
Expand Down
71 changes: 43 additions & 28 deletions docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- [Proxying to an Angular app](#proxying-to-an-angular-app)
- [Proxying to a Svelte app](#proxying-to-a-svelte-app)
- [Prefixing `/absproxy/<port>` with a path](#prefixing-absproxyport-with-a-path)
- [Preflight requests](#preflight-requests)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- prettier-ignore-end -->
Expand Down Expand Up @@ -119,22 +120,22 @@ access code-server on an iPad or do not want to use SSH port forwarding.

1. This option requires that the remote machine be exposed to the internet. Make sure that your instance allows HTTP/HTTPS traffic.

1. You'll need a domain name (if you don't have one, you can purchase one from
2. You'll need a domain name (if you don't have one, you can purchase one from
[Google Domains](https://domains.google.com) or the domain service of your
choice). Once you have a domain name, add an A record to your domain that contains your
instance's IP address.

1. Install [Caddy](https://caddyserver.com/docs/download#debian-ubuntu-raspbian):
3. Install [Caddy](https://caddyserver.com/docs/download#debian-ubuntu-raspbian):

```console
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
```
```console
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy
```

1. Replace `/etc/caddy/Caddyfile` using `sudo` so that the file looks like this:
4. Replace `/etc/caddy/Caddyfile` using `sudo` so that the file looks like this:

```text
mydomain.com {
Expand All @@ -153,7 +154,7 @@ sudo apt install caddy

Remember to replace `mydomain.com` with your domain name!

1. Reload Caddy:
5. Reload Caddy:

```console
sudo systemctl reload caddy
Expand All @@ -164,21 +165,22 @@ At this point, you should be able to access code-server via

### Using Let's Encrypt with NGINX

1. This option requires that the remote machine be exposed to the internet. Make sure that your instance allows HTTP/HTTPS traffic.
1. This option requires that the remote machine be exposed to the internet. Make
sure that your instance allows HTTP/HTTPS traffic.

1. You'll need a domain name (if you don't have one, you can purchase one from
2. You'll need a domain name (if you don't have one, you can purchase one from
[Google Domains](https://domains.google.com) or the domain service of your
choice). Once you have a domain name, add an A record to your domain that contains your
instance's IP address.

1. Install NGINX:
3. Install NGINX:

```bash
sudo apt update
sudo apt install -y nginx certbot python3-certbot-nginx
```

1. Update `/etc/nginx/sites-available/code-server` using sudo with the following
4. Update `/etc/nginx/sites-available/code-server` using sudo with the following
configuration:

```text
Expand All @@ -196,16 +198,13 @@ At this point, you should be able to access code-server via
}
}
```

Be sure to replace `mydomain.com` with your domain name!

1. Enable the config:

5. Enable the config:
```console
sudo ln -s ../sites-available/code-server /etc/nginx/sites-enabled/code-server
sudo certbot --non-interactive --redirect --agree-tos --nginx -d mydomain.com -m [email protected]
```

Be sure to replace `[email protected]` with your actual email.

At this point, you should be able to access code-server via
Expand Down Expand Up @@ -292,7 +291,9 @@ redirect all HTTP requests to HTTPS.
> You can use [Let's Encrypt](https://letsencrypt.org/) to get a TLS certificate
> for free.

Note: if you set `proxy_set_header Host $host;` in your reverse proxy config, it will change the address displayed in the green section of code-server in the bottom left to show the correct address.
Note: if you set `proxy_set_header Host $host;` in your reverse proxy config, it
will change the address displayed in the green section of code-server in the
bottom left to show the correct address.

## Accessing web services

Expand Down Expand Up @@ -378,14 +379,16 @@ PUBLIC_URL=/absproxy/3000 \
BROWSER=none yarn start
```

You should then be able to visit `https://my-code-server-address.io/absproxy/3000` to see your app exposed through
code-server!
You should then be able to visit
`https://my-code-server-address.io/absproxy/3000` to see your app exposed
through code-server.

> We highly recommend using the subdomain approach instead to avoid this class of issue.

### Proxying to a Vue app

Similar to the situation with React apps, you have to make a few modifications to proxy a Vue app.
Similar to the situation with React apps, you have to make a few modifications
to proxy a Vue app.

1. add `vue.config.js`
2. update the values to match this (you can use any free port):
Expand All @@ -406,7 +409,8 @@ Read more about `publicPath` in the [Vue.js docs](https://cli.vuejs.org/config/#

### Proxying to an Angular app

In order to use code-server's built-in proxy with Angular, you need to make the following changes in your app:
In order to use code-server's built-in proxy with Angular, you need to make the
following changes in your app:

1. use `<base href="./.">` in `src/index.html`
2. add `--serve-path /absproxy/4200` to `ng serve` in your `package.json`
Expand All @@ -415,7 +419,8 @@ For additional context, see [this GitHub Discussion](https://github.com/coder/co

### Proxying to a Svelte app

In order to use code-server's built-in proxy with Svelte, you need to make the following changes in your app:
In order to use code-server's built-in proxy with Svelte, you need to make the
following changes in your app:

1. Add `svelte.config.js` if you don't already have one
2. Update the values to match this (you can use any free port):
Expand All @@ -436,9 +441,19 @@ For additional context, see [this Github Issue](https://github.com/sveltejs/kit/

### Prefixing `/absproxy/<port>` with a path

This is a case where you need to serve an application via `absproxy` as explained above while serving `codeserver` itself from a path other than the root in your domain.
This is a case where you need to serve an application via `absproxy` as
explained above while serving code-server itself from a path other than the root
in your domain.

For example: `http://my-code-server.com/user/123/workspace/my-app`. To achieve this result:
For example: `http://my-code-server.com/user/123/workspace/my-app`. To achieve
this result:

1. Start code server with the switch `--abs-proxy-base-path=/user/123/workspace`
1. Start code-server with the switch `--abs-proxy-base-path=/user/123/workspace`
2. Follow one of the instructions above for your framework.

### Preflight requests

By default, if you have auth enabled, code-server will authenticate all proxied
requests including preflight requests. This can cause issues because preflight
requests do not typically include credentials. To allow all preflight requests
through the proxy without authentication, use `--skip-auth-preflight`.
10 changes: 10 additions & 0 deletions src/node/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,15 @@
// When logging in or out the request must include the href (the full current
// URL of that page) and the relative path to the root as given to it by the
// backend. Using these two we can determine the true absolute root.


function getConfigCookieMaxAgeAsMilliseconds(req: express.Request): number {
// the CLI flag or YAML key should be defined as "auth.cookie-max-age"
const days = Number(req.args["auth.cookie-max-age"] || 0)

Check failure on line 325 in src/node/http.ts

View workflow job for this annotation

GitHub Actions / Build code-server

Element implicitly has an 'any' type because expression of type '"auth.cookie-max-age"' can't be used to index type 'DefaultedArgs'.
return days * 24 * 60 * 60 * 1000
}


const url = new URL(
req.query.base || req.body?.base || "/",
req.query.href || req.body?.href || "http://" + (req.headers.host || "localhost"),
Expand All @@ -326,6 +335,7 @@
domain: getCookieDomain(url.host, req.args["proxy-domain"]),
path: normalize(url.pathname) || "/",
sameSite: "lax",
maxAge: getConfigCookieMaxAgeAsMilliseconds(req) || 0,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wait is 0 the right default? This will delete the cookie instantly, I think? We may want -1.

Copy link
Member

@code-asher code-asher Apr 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm actually zero or negative immediately expires the cookie it seems.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Set-Cookie#max-agenumber
https://datatracker.ietf.org/doc/html/rfc6265#section-5.2.2

Should it just be undefined? Also we may want ?? instead of || in case someone does explicitly set it to zero for some reason.

}
}

Expand Down
Loading