From 8b7da8296ccded4c72bb812775682db4f8099b0b Mon Sep 17 00:00:00 2001 From: claude Date: Wed, 10 Jun 2026 09:17:30 +0000 Subject: [PATCH] fix: pass session token so anonymous users can install python packages 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 --- services/web/app/src/Features/Compile/CompileController.mjs | 4 +++- services/web/app/src/Features/Compile/PythonVenvGate.mjs | 4 ++-- services/web/frontend/stylesheets/pages/project-list.scss | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/services/web/app/src/Features/Compile/CompileController.mjs b/services/web/app/src/Features/Compile/CompileController.mjs index 4fafdb13b5..aed625f2b9 100644 --- a/services/web/app/src/Features/Compile/CompileController.mjs +++ b/services/web/app/src/Features/Compile/CompileController.mjs @@ -9,6 +9,7 @@ import Settings from '@overleaf/settings' import Errors from '../Errors/Errors.js' import SessionManager from '../Authentication/SessionManager.mjs' import { userCanInstallPython } from './PythonVenvGate.mjs' +import TokenAccessHandler from '../TokenAccess/TokenAccessHandler.mjs' import { RateLimiter } from '../../infrastructure/RateLimiter.mjs' import Validation from '../../infrastructure/Validation.mjs' import Path from 'node:path' @@ -206,7 +207,8 @@ const _CompileController = { // Allow building a per-project Python venv from requirements.txt only for // the project owner and invited collaborators — never anonymous or // link-sharing users. - options.allowPythonInstall = await userCanInstallPython(userId, projectId) + const anonToken = TokenAccessHandler.getRequestToken(req, projectId) + options.allowPythonInstall = await userCanInstallPython(userId, projectId, anonToken) let { enablePdfCaching, diff --git a/services/web/app/src/Features/Compile/PythonVenvGate.mjs b/services/web/app/src/Features/Compile/PythonVenvGate.mjs index 206098d0c4..a0f11ff2e2 100644 --- a/services/web/app/src/Features/Compile/PythonVenvGate.mjs +++ b/services/web/app/src/Features/Compile/PythonVenvGate.mjs @@ -9,7 +9,7 @@ import AuthorizationManager from '../Authorization/AuthorizationManager.mjs' // the set of packages to install is already controlled by requirements.vrf // (writable only by project members with write access). Returns false when the // feature is disabled, the privilege check fails, or the user has no access. -export async function userCanInstallPython(userId, projectId) { +export async function userCanInstallPython(userId, projectId, token = null) { if (!Settings.enableProjectPythonVenv) { return false } @@ -18,7 +18,7 @@ export async function userCanInstallPython(userId, projectId) { await AuthorizationManager.promises.getPrivilegeLevelForProject( userId, projectId, - null + token ) return Boolean(privilegeLevel) } catch (err) { diff --git a/services/web/frontend/stylesheets/pages/project-list.scss b/services/web/frontend/stylesheets/pages/project-list.scss index ce8363f47a..e6ecfc8711 100644 --- a/services/web/frontend/stylesheets/pages/project-list.scss +++ b/services/web/frontend/stylesheets/pages/project-list.scss @@ -411,7 +411,7 @@ ul.project-list-filters { } &.project-format-badge-quarto-slides { - background-color: #7e56c2; // purple — presentation feel, blends Quarto + RevealJS + background-color: #e4637c; // RevealJS pink-red } &.project-format-badge-typst {