diff --git a/services/web/app/src/Features/Project/ProjectController.mjs b/services/web/app/src/Features/Project/ProjectController.mjs index 0152910bc2..d677673358 100644 --- a/services/web/app/src/Features/Project/ProjectController.mjs +++ b/services/web/app/src/Features/Project/ProjectController.mjs @@ -813,22 +813,25 @@ const _ProjectController = { let aiFeaturesAllowedForUser = false let aiFeaturesAllowedForProject = false - if (userId && Features.hasFeature('saas')) { + + const canUserWriteOrReviewProjectContent = + privilegeLevel === PrivilegeLevels.READ_AND_WRITE || + privilegeLevel === PrivilegeLevels.OWNER || + privilegeLevel === PrivilegeLevels.REVIEW + + if ( + userId && + canUserWriteOrReviewProjectContent && + Features.hasFeature('saas') + ) { try { aiFeaturesAllowedForUser = await checkUserPermissions(user, [ 'use-ai', ]) - - const canUserWriteOrReviewProjectContent = - privilegeLevel === PrivilegeLevels.READ_AND_WRITE || - privilegeLevel === PrivilegeLevels.OWNER || - privilegeLevel === PrivilegeLevels.REVIEW - if (canUserWriteOrReviewProjectContent) { - aiFeaturesAllowedForProject = await checkUserPermissions( - project.owner_ref, - ['use-ai'] - ) - } + aiFeaturesAllowedForProject = await checkUserPermissions( + project.owner_ref, + ['use-ai'] + ) } catch (err) { // still allow users to access project if we cant get their permissions, but disable AI feature aiFeaturesAllowedForUser = false diff --git a/services/web/frontend/js/features/source-editor/components/toolbar/math-dropdown.tsx b/services/web/frontend/js/features/source-editor/components/toolbar/math-dropdown.tsx index 9bf170006c..3c07f5166d 100644 --- a/services/web/frontend/js/features/source-editor/components/toolbar/math-dropdown.tsx +++ b/services/web/frontend/js/features/source-editor/components/toolbar/math-dropdown.tsx @@ -35,6 +35,7 @@ export const MathDropdown = memo(function MathDropdown() { {t('toolbar_insert_math_lowercase')} )} diff --git a/services/web/frontend/js/features/source-editor/components/toolbar/table-dropdown.tsx b/services/web/frontend/js/features/source-editor/components/toolbar/table-dropdown.tsx index 459195de47..906d3e0fac 100644 --- a/services/web/frontend/js/features/source-editor/components/toolbar/table-dropdown.tsx +++ b/services/web/frontend/js/features/source-editor/components/toolbar/table-dropdown.tsx @@ -47,6 +47,7 @@ export const TableDropdown = memo(function TableDropdown() { {t('toolbar_table_insert_table_lowercase')}
{ + ctx.res.render = (pageName, opts) => { + expect(opts.showAiFeatures).to.equal(false) + resolve() + } + ctx.ProjectController.loadEditor(ctx.req, ctx.res, err => { + if (err) reject(err) + }) + }) + }) + it('should set showAiFeatures to false when the user can use ai but the project disallows it', async function (ctx) { ctx.PermissionsManager.promises.checkUserPermissions.callsFake( subject => Promise.resolve(typeof subject !== 'string') @@ -1760,6 +1776,23 @@ describe('ProjectController', function () { }) }) }) + + it('should set showAiFeatures to false and showAiFeaturesDisabled to false when the user has read-only access', async function (ctx) { + ctx.PermissionsManager.promises.checkUserPermissions.resolves(true) + ctx.AuthorizationManager.promises.getPrivilegeLevelForProject.resolves( + 'readOnly' + ) + await new Promise((resolve, reject) => { + ctx.res.render = (pageName, opts) => { + expect(opts.showAiFeatures).to.equal(false) + expect(opts.showAiFeaturesDisabled).to.equal(false) + resolve() + } + ctx.ProjectController.loadEditor(ctx.req, ctx.res, err => { + if (err) reject(err) + }) + }) + }) }) }) })