userCanInstallPython passed null as the token, so anonymous users
accessing via a share link got privilege level NONE from the WithoutUser
path and allowPythonInstall was always false for them.
Read the token from req.session.anonTokenAccess via
TokenAccessHandler.getRequestToken and forward it through
userCanInstallPython to getPrivilegeLevelForProject. For TOKEN_BASED
projects this resolves the anonymous user's access level via
getPrivilegeLevelForProjectWithToken, enabling package installation.
Also update Quarto Slides badge color to #e4637c.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
options.compiler is set from req.body.compiler which the frontend never
sends, so the condition was never true and quartoFlavor was never written.
Use ProjectGetter to read the stored compiler instead. Fire-and-forget so
it does not delay the compile response.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix wrong import path '../models/Project.mjs' → '../../models/Project.mjs'
(from Features/Compile/, '..' is Features/, not src/; the server would
crash on startup with ERR_MODULE_NOT_FOUND in Node.js ESM)
- Log MongoDB errors instead of silently swallowing them
- Remove null from Mongoose String enum (not a valid enum value for strings)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add a quartoFlavor field ('revealjs' | 'pdf') to the Project model.
After each successful Quarto compile, CompileController detects the output
type (output.html → revealjs, otherwise pdf) and persists it.
ProjectListController includes it in the projection and serialization so
it reaches the frontend without an extra round-trip.
Badge variants:
- quartoFlavor unset (new/uncompiled) → "Quarto PDF" #447099
- quartoFlavor 'pdf' → "Quarto PDF" #447099 (Quarto blue)
- quartoFlavor 'revealjs' → "Quarto Slides" #7e56c2 (purple)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Base image: add opencv-python-headless (cv2) and tqdm to the bundled
scientific stack, and python3-venv (needed to build per-project venvs).
Per-project dependencies: a project's requirements.txt is now installed into a
venv cached by its sha256 (python3 -m venv --system-site-packages, so the
bundled stack stays visible and only extra packages are installed); QuartoRunner
points Quarto at it via QUARTO_PYTHON. A per-hash flock serialises concurrent
builds; pip output is merged into output.log; on failure the render falls back
to the base interpreter. Venvs live under PYTHON_VENVS_DIR
(default /var/lib/overleaf/data/python-venvs).
Gating: PythonVenvGate.userCanInstallPython restricts installs to the project
owner + invited collaborators (ignorePublicAccess excludes anonymous/link
users), threaded to CLSI as allowPythonInstall on the editor compile,
presentation export, and publish paths. Behind OVERLEAF_ENABLE_PROJECT_PYTHON_VENV
(enabled in the deployment). Design doc updated; Phase 2 (egress policy) and
Phase 3 (venv eviction) remain.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* [web] add includeReferer flag to SplitTestHandler.getAssignment
* [web] tests: migrate User.getSplitTestAssignment to async/await
I don't want to fight with callbacks and optional arguments. Just move
it to async/await. New tests should use async/await, so there is no
point in making this work in callback-hell.
* [web] remove unused URL import
GitOrigin-RevId: 6251001e6ba7354f704fa663be8ef365ca0b9d23
The req.body.rootResourcePath has been shipped three weeks ago, so it's
unlikely to trip up stale editor sessions.
For now, only block node-fetch and log the rest.
GitOrigin-RevId: 541189675f68fdcab09f4b409b4143024a29f94a
* [clsi] initial implementation of compile from history
* [clsi] copy changes
* [saas-e2e] extend test case with nested folder
* [saas-e2e] add test case for tracked changes
* [web] fix accumulating changes from multiple chunks
* [web] optimize size check for compile request payload
* [clsi] deduplicate globalBlobs
* [clsi] add validation for request body details
* [clsi] add metrics for compile from history
* [clsi] download binary files concurrently
* [clsi] skip download of empty file blob
* [clsi] break down e2e compile time metric by compileFromHistory
GitOrigin-RevId: 0dadef93e89d8a172c35cb130a1042d9d1bec42a
* [web] increase timeout for downloads from clsi
* [web] detach request timeout from streaming timeout
* [web] align timeout for clsi-cache downloads with clsi downloads
* [web] destroy stream when bailing out early from aborted requests
GitOrigin-RevId: cc4cad9d684214b2eee0f5fc43513e430ceb0977
* [monorepo] switch all output file reads to clsi-nginx
* [clsi-lb] allow gallery download requests
* [terraform] clsi: use nginx.conf from clsi service
* [clsi] fix flakey tests
* [clsi] replace alias with rewrite and root in nginx config
* [k8s] clsi-lb: expose download port on internal service
* [web] add explicit endpoint for downloading all output files
Serve the output.zip endpoint from clsi.
* [clsi] fix regex for latexqc submission ids
Previously, we only handled template submission ids.
GitOrigin-RevId: 6c3b21b01ec41ae767530b14aac31fbe3d640dd5
* [web] add clsi-cache prompts
* [web] add new editor variant to segmentation
* [web] add tests for useNewEditorVariant
* [web] adjust start of using clsi-cache in split-test
GitOrigin-RevId: c9c5b1eff2ceefb65ef82516d9074cb971cb4c48