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-20 08:05:20 +00:00
committed by Copybot
parent edf4fdda50
commit 04fa5366ce
19 changed files with 44 additions and 44 deletions
-1
View File
@@ -13,7 +13,6 @@ import en from '../../../services/web/locales/en.json'
function resetMeta() { function resetMeta() {
window.metaAttributesCache = new Map() window.metaAttributesCache = new Map()
window.metaAttributesCache.set('ol-i18n', { currentLangCode: 'en' }) window.metaAttributesCache.set('ol-i18n', { currentLangCode: 'en' })
window.metaAttributesCache.set('ol-chatEnabled', true)
window.metaAttributesCache.set('ol-ExposedSettings', { window.metaAttributesCache.set('ol-ExposedSettings', {
adminEmail: 'placeholder@example.com', adminEmail: 'placeholder@example.com',
appName: 'Overleaf', appName: 'Overleaf',
@@ -728,14 +728,6 @@ const _ProjectController = {
? 'project/ide-react-detached' ? 'project/ide-react-detached'
: 'project/ide-react' : 'project/ide-react'
let chatEnabled
if (Features.hasFeature('saas')) {
chatEnabled =
Features.hasFeature('chat') && req.capabilitySet.has('chat')
} else {
chatEnabled = Features.hasFeature('chat')
}
const isOverleafAssistBundleEnabled = const isOverleafAssistBundleEnabled =
splitTestAssignments['overleaf-assist-bundle']?.variant === 'enabled' splitTestAssignments['overleaf-assist-bundle']?.variant === 'enabled'
@@ -841,7 +833,7 @@ const _ProjectController = {
isTokenMember, isTokenMember,
isInvitedMember isInvitedMember
), ),
chatEnabled, capabilities: [...req.capabilitySet],
projectHistoryBlobsEnabled: Features.hasFeature( projectHistoryBlobsEnabled: Features.hasFeature(
'project-history-blobs' 'project-history-blobs'
), ),
@@ -8,6 +8,7 @@ function _canHaveNoIpAddressId(operation, info) {
if (operation === 'must-reset-password-set') return true if (operation === 'must-reset-password-set') return true
if (operation === 'remove-email' && info.script) return true if (operation === 'remove-email' && info.script) return true
if (operation === 'release-managed-user' && info.script) return true if (operation === 'release-managed-user' && info.script) return true
if (operation === 'unlink-dropbox' && info.batch) return true
return false return false
} }
@@ -176,6 +176,7 @@ async function settingsPage(req, res) {
gitBridgeEnabled: Settings.enableGitBridge, gitBridgeEnabled: Settings.enableGitBridge,
isSaas: Features.hasFeature('saas'), isSaas: Features.hasFeature('saas'),
memberOfSSOEnabledGroups, memberOfSSOEnabledGroups,
capabilities: [...req.capabilitySet],
}) })
} }
@@ -27,6 +27,9 @@ const GroupPolicySchema = new Schema(
// User can't use the chat feature // User can't use the chat feature
userCannotUseChat: Boolean, userCannotUseChat: Boolean,
// User can't use the Dropbox feature
userCannotUseDropbox: Boolean,
}, },
{ minimize: false } { minimize: false }
) )
@@ -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-maxDocLength" data-type="json" content=maxDocLength)
meta(name="ol-maxReconnectGracefullyIntervalMs" data-type="json" content=maxReconnectGracefullyIntervalMs) meta(name="ol-maxReconnectGracefullyIntervalMs" data-type="json" content=maxReconnectGracefullyIntervalMs)
meta(name="ol-wikiEnabled" data-type="boolean" content=settings.proxyLearn) 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-projectHistoryBlobsEnabled" data-type="boolean" content=projectHistoryBlobsEnabled)
meta(name="ol-gitBridgePublicBaseUrl" content=gitBridgePublicBaseUrl) meta(name="ol-gitBridgePublicBaseUrl" content=gitBridgePublicBaseUrl)
meta(name="ol-gitBridgeEnabled" data-type="boolean" content=gitBridgeEnabled) meta(name="ol-gitBridgeEnabled" data-type="boolean" content=gitBridgeEnabled)
+1
View File
@@ -32,6 +32,7 @@ block append meta
meta(name="ol-gitBridgeEnabled" data-type="boolean" content=gitBridgeEnabled) meta(name="ol-gitBridgeEnabled" data-type="boolean" content=gitBridgeEnabled)
meta(name="ol-isSaas" data-type="boolean" content=isSaas) meta(name="ol-isSaas" data-type="boolean" content=isSaas)
meta(name="ol-memberOfSSOEnabledGroups" data-type="json" content=memberOfSSOEnabledGroups) meta(name="ol-memberOfSSOEnabledGroups" data-type="json" content=memberOfSSOEnabledGroups)
meta(name="ol-capabilities" data-type="json" content=capabilities)
block content block content
main.content.content-alt#main-content main.content.content-alt#main-content
@@ -193,7 +193,7 @@ export const ChatContext = createContext<
>(undefined) >(undefined)
export const ChatProvider: FC<React.PropsWithChildren> = ({ children }) => { export const ChatProvider: FC<React.PropsWithChildren> = ({ children }) => {
const chatEnabled = getMeta('ol-chatEnabled') const chatEnabled = getMeta('ol-capabilities')?.includes('chat')
const clientId = useRef<string>() const clientId = useRef<string>()
if (clientId.current === undefined) { if (clientId.current === undefined) {
@@ -80,7 +80,7 @@ const ToolbarHeader = React.memo(function ToolbarHeader({
openShareModal: () => void openShareModal: () => void
trackChangesVisible: boolean | undefined trackChangesVisible: boolean | undefined
}) { }) {
const chatEnabled = getMeta('ol-chatEnabled') const chatEnabled = getMeta('ol-capabilities')?.includes('chat')
const { t } = useTranslation() const { t } = useTranslation()
const shouldDisplayPublishButton = hasPublishPermissions && PublishButton const shouldDisplayPublishButton = hasPublishPermissions && PublishButton
@@ -47,7 +47,8 @@ export const MainLayout: FC = () => {
handlePaneExpand: handleChatExpand, handlePaneExpand: handleChatExpand,
} = useChatPane() } = useChatPane()
const chatEnabled = getMeta('ol-chatEnabled') && !isRestrictedTokenMember const chatEnabled =
getMeta('ol-capabilities')?.includes('chat') && !isRestrictedTokenMember
const { t } = useTranslation() const { t } = useTranslation()
@@ -156,7 +156,7 @@ export const RailLayout = () => {
component: <ChatPane />, component: <ChatPane />,
indicator: <ChatIndicator />, indicator: <ChatIndicator />,
title: t('chat'), title: t('chat'),
hide: !getMeta('ol-chatEnabled'), hide: !getMeta('ol-capabilities')?.includes('chat'),
}, },
{ {
key: 'errors', key: 'errors',
+1 -1
View File
@@ -85,7 +85,7 @@ export interface Meta {
'ol-cannot-link-other-third-party-sso': boolean 'ol-cannot-link-other-third-party-sso': boolean
'ol-cannot-reactivate-subscription': boolean 'ol-cannot-reactivate-subscription': boolean
'ol-cannot-use-ai': boolean 'ol-cannot-use-ai': boolean
'ol-chatEnabled': boolean 'ol-capabilities': Array<'dropbox' | 'chat'>
'ol-compileSettings': { 'ol-compileSettings': {
reducedTimeoutWarning: string reducedTimeoutWarning: string
compileTimeout: number compileTimeout: number
@@ -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,
}
@@ -19,7 +19,6 @@ describe('<ChatPane />', function () {
beforeEach(function () { beforeEach(function () {
window.metaAttributesCache.set('ol-user', user) window.metaAttributesCache.set('ol-user', user)
window.metaAttributesCache.set('ol-chatEnabled', true)
window.metaAttributesCache.set('ol-preventCompileOnLoad', true) window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
}) })
@@ -27,7 +27,6 @@ describe('ChatContext', function () {
stubMathJax() stubMathJax()
window.metaAttributesCache.set('ol-user', user) window.metaAttributesCache.set('ol-user', user)
window.metaAttributesCache.set('ol-chatEnabled', true)
window.metaAttributesCache.set('ol-preventCompileOnLoad', true) window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
this.stub = sinon.stub(chatClientIdGenerator, 'generate').returns(uuidValue) this.stub = sinon.stub(chatClientIdGenerator, 'generate').returns(uuidValue)
@@ -27,7 +27,6 @@ describe('<ToolbarHeader />', function () {
} }
beforeEach(function () { beforeEach(function () {
window.metaAttributesCache.set('ol-chatEnabled', true)
window.metaAttributesCache.set('ol-preventCompileOnLoad', true) window.metaAttributesCache.set('ol-preventCompileOnLoad', true)
}) })
@@ -85,6 +85,8 @@ export function EditorProviders({
merge({}, defaultUserSettings, userSettings) merge({}, defaultUserSettings, userSettings)
) )
window.metaAttributesCache.set('ol-capabilities', ['chat', 'dropbox'])
const scope = merge( const scope = merge(
{ {
user, user,
@@ -2,6 +2,7 @@ export function resetMeta() {
window.metaAttributesCache = new Map() window.metaAttributesCache = new Map()
window.metaAttributesCache.set('ol-projectHistoryBlobsEnabled', true) window.metaAttributesCache.set('ol-projectHistoryBlobsEnabled', true)
window.metaAttributesCache.set('ol-i18n', { currentLangCode: 'en' }) window.metaAttributesCache.set('ol-i18n', { currentLangCode: 'en' })
window.metaAttributesCache.set('ol-capabilities', ['chat', 'dropbox'])
window.metaAttributesCache.set('ol-ExposedSettings', { window.metaAttributesCache.set('ol-ExposedSettings', {
appName: 'Overleaf', appName: 'Overleaf',
maxEntitiesPerProject: 10, maxEntitiesPerProject: 10,
@@ -300,6 +300,7 @@ describe('ProjectController', function () {
translate() {}, translate() {},
}, },
ip: '192.170.18.1', ip: '192.170.18.1',
capabilitySet: new Set(['chat']),
} }
this.res = { this.res = {
locals: { locals: {
@@ -1085,34 +1086,12 @@ describe('ProjectController', function () {
this.ProjectController.loadEditor(this.req, this.res) this.ProjectController.loadEditor(this.req, this.res)
}) })
describe('chatEnabled flag', function () { describe('capabilitySet', function () {
it('should be set to false when the feature is disabled', function (done) { it('should be passed as an array when loading the editor', function (done) {
this.Features.hasFeature = sinon.stub().withArgs('chat').returns(false) this.Features.hasFeature = sinon.stub().withArgs('chat').returns(false)
this.res.render = (pageName, opts) => { this.res.render = (pageName, opts) => {
expect(opts.chatEnabled).to.be.false expect(opts.capabilities).to.deep.equal(['chat'])
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
done() done()
} }
this.ProjectController.loadEditor(this.req, this.res) this.ProjectController.loadEditor(this.req, this.res)