Merge pull request #36684 from overleaf/em-user-settings-zotero-groups

Stop carrying an _id on reference manager groups in user settings

GitOrigin-RevId: 1ac74d201a3b81b2069215e05b9c84189c42aad6
This commit is contained in:
Eric Mc Sween
2026-09-17 12:00:19 +00:00
committed by Copybot
parent a84079e600
commit 82539b5842
5 changed files with 79 additions and 4 deletions
@@ -13,6 +13,26 @@ function getOverallTheme(user) {
return 'system'
}
/**
* Build the settings for a reference provider (zotero, mendeley, papers).
*
* The group entries are rebuilt explicitly so that the `_id` stored on older
* documents doesn't leak to the frontend, which posts these settings back to us
* unchanged.
*
* @param {object | undefined} settings the provider settings from `user.ace`
*/
function buildRefProviderSettings(settings) {
if (settings == null) {
return settings
}
return {
enabled: settings.enabled,
disablePersonalLibrary: settings.disablePersonalLibrary,
groups: (settings.groups ?? []).map(group => ({ id: group.id })),
}
}
async function buildUserSettings(_req, _res, user) {
return {
mode: user.ace.mode,
@@ -35,9 +55,9 @@ async function buildUserSettings(_req, _res, user) {
referencesSearchMode: user.ace.referencesSearchMode,
darkModePdf: user.ace.darkModePdf ?? false,
floatingMenu: user.ace.floatingMenu ?? true,
zotero: user.ace.zotero,
mendeley: user.ace.mendeley,
papers: user.ace.papers,
zotero: buildRefProviderSettings(user.ace.zotero),
mendeley: buildRefProviderSettings(user.ace.mendeley),
papers: buildRefProviderSettings(user.ace.papers),
}
}
@@ -364,7 +364,7 @@ async function unsubscribe(req, res, next) {
const refProviderSettingsSchema = z
.strictObject({
enabled: z.boolean().optional(),
groups: z.array(z.strictObject({ id: z.string() })).optional(),
groups: z.array(z.object({ id: z.string() })).optional(),
disablePersonalLibrary: z.boolean().optional(),
})
.optional()
+1
View File
@@ -12,6 +12,7 @@ const refProviderSettingsSchema = {
groups: {
type: [
{
_id: false,
id: { type: String },
},
],
@@ -56,4 +56,43 @@ describe('UserSettingsHelper', function () {
expect(settings.overallTheme).toBe('')
})
})
describe('reference provider settings', function () {
it('should drop the _id from group entries', async function (ctx) {
const user = {
ace: {
zotero: {
enabled: true,
disablePersonalLibrary: false,
groups: [{ _id: 'abc123', id: '123' }],
},
},
signUpDate: new Date('2022-01-01'),
}
const settings = await ctx.UserSettingsHelper.buildUserSettings(
ctx.req,
ctx.res,
user
)
expect(settings.zotero).toEqual({
enabled: true,
disablePersonalLibrary: false,
groups: [{ id: '123' }],
})
})
it('should leave unset providers undefined', async function (ctx) {
const user = { ace: {}, signUpDate: new Date('2022-01-01') }
const settings = await ctx.UserSettingsHelper.buildUserSettings(
ctx.req,
ctx.res,
user
)
expect(settings.zotero).toBeUndefined()
})
})
})
@@ -625,6 +625,21 @@ describe('UserController', function () {
})
})
it('should drop the _id from zotero groups', function (ctx) {
return new Promise(resolve => {
ctx.req.body = {
zotero: {
groups: [{ _id: 'abc123', id: '123' }],
},
}
ctx.res.sendStatus = code => {
ctx.user.ace.zotero.groups.should.deep.equal([{ id: '123' }])
resolve()
}
ctx.UserController.updateUserSettings(ctx.req, ctx.res)
})
})
it('should set zotero settings with partial update', function (ctx) {
return new Promise(resolve => {
ctx.user.ace.zotero = {