Merge pull request #26070 from overleaf/msm-disable-dropbox

[web] Disable Dropbox Capability

GitOrigin-RevId: 5f91d2918bf3b88e52f4d27c828a4715f9b88629
This commit is contained in:
Miguel Serrano
2025-06-19 10:39:38 +02:00
committed by Copybot
parent edf4fdda50
commit 04fa5366ce
19 changed files with 44 additions and 44 deletions

View File

@@ -13,7 +13,6 @@ import en from '../../../services/web/locales/en.json'
function resetMeta() {
window.metaAttributesCache = new Map()
window.metaAttributesCache.set('ol-i18n', { currentLangCode: 'en' })
window.metaAttributesCache.set('ol-chatEnabled', true)
window.metaAttributesCache.set('ol-ExposedSettings', {
adminEmail: 'placeholder@example.com',
appName: 'Overleaf',

View File

@@ -728,14 +728,6 @@ const _ProjectController = {
? 'project/ide-react-detached'
: 'project/ide-react'
let chatEnabled
if (Features.hasFeature('saas')) {
chatEnabled =
Features.hasFeature('chat') && req.capabilitySet.has('chat')
} else {
chatEnabled = Features.hasFeature('chat')
}
const isOverleafAssistBundleEnabled =
splitTestAssignments['overleaf-assist-bundle']?.variant === 'enabled'
@@ -841,7 +833,7 @@ const _ProjectController = {
isTokenMember,
isInvitedMember
),
chatEnabled,
capabilities: [...req.capabilitySet],
projectHistoryBlobsEnabled: Features.hasFeature(
'project-history-blobs'
),

View File

@@ -8,6 +8,7 @@ function _canHaveNoIpAddressId(operation, info) {
if (operation === 'must-reset-password-set') return true
if (operation === 'remove-email' && info.script) return true
if (operation === 'release-managed-user' && info.script) return true
if (operation === 'unlink-dropbox' && info.batch) return true
return false
}

View File

@@ -176,6 +176,7 @@ async function settingsPage(req, res) {
gitBridgeEnabled: Settings.enableGitBridge,
isSaas: Features.hasFeature('saas'),
memberOfSSOEnabledGroups,
capabilities: [...req.capabilitySet],
})
}

View File

@@ -27,6 +27,9 @@ const GroupPolicySchema = new Schema(
// User can't use the chat feature
userCannotUseChat: Boolean,
// User can't use the Dropbox feature
userCannotUseDropbox: Boolean,
},
{ minimize: false }
)

View File

@@ -12,7 +12,7 @@ meta(name="ol-isRestrictedTokenMember" data-type="boolean" content=isRestrictedT
meta(name="ol-maxDocLength" data-type="json" content=maxDocLength)
meta(name="ol-maxReconnectGracefullyIntervalMs" data-type="json" content=maxReconnectGracefullyIntervalMs)
meta(name="ol-wikiEnabled" data-type="boolean" content=settings.proxyLearn)
meta(name="ol-chatEnabled" data-type="boolean" content=chatEnabled)
meta(name="ol-capabilities" data-type="json" content=capabilities)
meta(name="ol-projectHistoryBlobsEnabled" data-type="boolean" content=projectHistoryBlobsEnabled)
meta(name="ol-gitBridgePublicBaseUrl" content=gitBridgePublicBaseUrl)
meta(name="ol-gitBridgeEnabled" data-type="boolean" content=gitBridgeEnabled)

View File

@@ -32,6 +32,7 @@ block append meta
meta(name="ol-gitBridgeEnabled" data-type="boolean" content=gitBridgeEnabled)
meta(name="ol-isSaas" data-type="boolean" content=isSaas)
meta(name="ol-memberOfSSOEnabledGroups" data-type="json" content=memberOfSSOEnabledGroups)
meta(name="ol-capabilities" data-type="json" content=capabilities)
block content
main.content.content-alt#main-content

View File

@@ -193,7 +193,7 @@ export const ChatContext = createContext<
>(undefined)
export const ChatProvider: FC<React.PropsWithChildren> = ({ children }) => {
const chatEnabled = getMeta('ol-chatEnabled')
const chatEnabled = getMeta('ol-capabilities')?.includes('chat')
const clientId = useRef<string>()
if (clientId.current === undefined) {

View File

@@ -80,7 +80,7 @@ const ToolbarHeader = React.memo(function ToolbarHeader({
openShareModal: () => void
trackChangesVisible: boolean | undefined
}) {
const chatEnabled = getMeta('ol-chatEnabled')
const chatEnabled = getMeta('ol-capabilities')?.includes('chat')
const { t } = useTranslation()
const shouldDisplayPublishButton = hasPublishPermissions && PublishButton

View File

@@ -47,7 +47,8 @@ export const MainLayout: FC = () => {
handlePaneExpand: handleChatExpand,
} = useChatPane()
const chatEnabled = getMeta('ol-chatEnabled') && !isRestrictedTokenMember
const chatEnabled =
getMeta('ol-capabilities')?.includes('chat') && !isRestrictedTokenMember
const { t } = useTranslation()

View File

@@ -156,7 +156,7 @@ export const RailLayout = () => {
component: <ChatPane />,
indicator: <ChatIndicator />,
title: t('chat'),
hide: !getMeta('ol-chatEnabled'),
hide: !getMeta('ol-capabilities')?.includes('chat'),
},
{
key: 'errors',

View File

@@ -85,7 +85,7 @@ export interface Meta {
'ol-cannot-link-other-third-party-sso': boolean
'ol-cannot-reactivate-subscription': boolean
'ol-cannot-use-ai': boolean
'ol-chatEnabled': boolean
'ol-capabilities': Array<'dropbox' | 'chat'>
'ol-compileSettings': {
reducedTimeoutWarning: string
compileTimeout: number

View File

@@ -0,0 +1,23 @@
const tags = ['saas']
const migrate = async client => {
const { db } = client
await db.grouppolicies.updateMany(
{},
{ $set: { userCannotUseDropbox: false } }
)
}
const rollback = async client => {
const { db } = client
await db.grouppolicies.updateMany(
{},
{ $unset: { userCannotUseDropbox: '' } }
)
}
export default {
tags,
migrate,
rollback,
}

View File

@@ -19,7 +19,6 @@ describe('<ChatPane />', function () {
beforeEach(function () {
window.metaAttributesCache.set('ol-user', user)
window.metaAttributesCache.set('ol-chatEnabled', true)
window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
})

View File

@@ -27,7 +27,6 @@ describe('ChatContext', function () {
stubMathJax()
window.metaAttributesCache.set('ol-user', user)
window.metaAttributesCache.set('ol-chatEnabled', true)
window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
this.stub = sinon.stub(chatClientIdGenerator, 'generate').returns(uuidValue)

View File

@@ -27,7 +27,6 @@ describe('<ToolbarHeader />', function () {
}
beforeEach(function () {
window.metaAttributesCache.set('ol-chatEnabled', true)
window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
})

View File

@@ -85,6 +85,8 @@ export function EditorProviders({
merge({}, defaultUserSettings, userSettings)
)
window.metaAttributesCache.set('ol-capabilities', ['chat', 'dropbox'])
const scope = merge(
{
user,

View File

@@ -2,6 +2,7 @@ export function resetMeta() {
window.metaAttributesCache = new Map()
window.metaAttributesCache.set('ol-projectHistoryBlobsEnabled', true)
window.metaAttributesCache.set('ol-i18n', { currentLangCode: 'en' })
window.metaAttributesCache.set('ol-capabilities', ['chat', 'dropbox'])
window.metaAttributesCache.set('ol-ExposedSettings', {
appName: 'Overleaf',
maxEntitiesPerProject: 10,

View File

@@ -300,6 +300,7 @@ describe('ProjectController', function () {
translate() {},
},
ip: '192.170.18.1',
capabilitySet: new Set(['chat']),
}
this.res = {
locals: {
@@ -1085,34 +1086,12 @@ describe('ProjectController', function () {
this.ProjectController.loadEditor(this.req, this.res)
})
describe('chatEnabled flag', function () {
it('should be set to false when the feature is disabled', function (done) {
describe('capabilitySet', function () {
it('should be passed as an array when loading the editor', function (done) {
this.Features.hasFeature = sinon.stub().withArgs('chat').returns(false)
this.res.render = (pageName, opts) => {
expect(opts.chatEnabled).to.be.false
done()
}
this.ProjectController.loadEditor(this.req, this.res)
})
it('should be set to false when the feature is enabled but the capability is not available', function (done) {
this.Features.hasFeature = sinon.stub().withArgs('chat').returns(false)
this.req.capabilitySet = new Set()
this.res.render = (pageName, opts) => {
expect(opts.chatEnabled).to.be.false
done()
}
this.ProjectController.loadEditor(this.req, this.res)
})
it('should be set to true when the feature is enabled and the capability is available', function (done) {
this.Features.hasFeature = sinon.stub().withArgs('chat').returns(true)
this.req.capabilitySet = new Set(['chat'])
this.res.render = (pageName, opts) => {
expect(opts.chatEnabled).to.be.true
expect(opts.capabilities).to.deep.equal(['chat'])
done()
}
this.ProjectController.loadEditor(this.req, this.res)