mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-14 20:40:17 -05:00
[CE/SP] Hotfixes 3.5.10 / 4.0.5 (#13961)
* [CE/SP] Hotfixes 3.5.10 / 4.0.5 * [CE/SP] include PR13122 in 4.0.5 hotfixes --------- Co-authored-by: Jakob Ackermann <jakob.ackermann@overleaf.com> GitOrigin-RevId: 68d31f4a4573d2cad1ee564a62957ad2c858cbe7
This commit is contained in:
parent
d2f470450e
commit
59fe2fe463
7 changed files with 241 additions and 0 deletions
9
server-ce/hotfix/3.5.10/Dockerfile
Normal file
9
server-ce/hotfix/3.5.10/Dockerfile
Normal file
|
@ -0,0 +1,9 @@
|
|||
FROM sharelatex/sharelatex:3.5.9
|
||||
|
||||
# Patch: clear invite and invite tokens through the websocket
|
||||
COPY pr_13427.patch .
|
||||
RUN patch -p0 < pr_13427.patch
|
||||
|
||||
# Patch: https://github.com/Automattic/mongoose/commit/f1efabf350522257364aa5c2cb36e441cf08f1a2
|
||||
COPY mongoose_proto.patch .
|
||||
RUN patch -p0 < mongoose_proto.patch
|
12
server-ce/hotfix/3.5.10/mongoose_proto.patch
Normal file
12
server-ce/hotfix/3.5.10/mongoose_proto.patch
Normal file
|
@ -0,0 +1,12 @@
|
|||
--- node_modules/mongoose/lib/document.js
|
||||
+++ node_modules/mongoose/lib/document.js
|
||||
@@ -689,6 +689,10 @@ function init(self, obj, doc, opts, prefix) {
|
||||
|
||||
function _init(index) {
|
||||
i = keys[index];
|
||||
+ // avoid prototype pollution
|
||||
+ if (i === '__proto__' || i === 'constructor') {
|
||||
+ return;
|
||||
+ }
|
||||
path = prefix + i;
|
||||
schema = self.$__schema.path(path);
|
92
server-ce/hotfix/3.5.10/pr_13427.patch
Normal file
92
server-ce/hotfix/3.5.10/pr_13427.patch
Normal file
|
@ -0,0 +1,92 @@
|
|||
--- services/web/app/src/Features/Editor/EditorHttpController.js
|
||||
+++ services/web/app/src/Features/Editor/EditorHttpController.js
|
||||
@@ -73,6 +73,7 @@ async function joinProject(req, res, next) {
|
||||
if (isRestrictedUser) {
|
||||
project.owner = { _id: project.owner._id }
|
||||
project.members = []
|
||||
+ project.invites = []
|
||||
}
|
||||
// Only show the 'renamed or deleted' message once
|
||||
if (project.deletedByExternalDataSource) {
|
||||
--- services/web/app/src/Features/Project/ProjectEditorHandler.js
|
||||
+++ services/web/app/src/Features/Project/ProjectEditorHandler.js
|
||||
@@ -48,19 +48,13 @@
|
||||
deletedDocsFromDocstore
|
||||
),
|
||||
members: [],
|
||||
- invites,
|
||||
+ invites: this.buildInvitesView(invites),
|
||||
imageName:
|
||||
project.imageName != null
|
||||
? Path.basename(project.imageName)
|
||||
: undefined,
|
||||
}
|
||||
|
||||
- if (result.invites == null) {
|
||||
- result.invites = []
|
||||
- }
|
||||
- result.invites.forEach(invite => {
|
||||
- delete invite.token
|
||||
- })
|
||||
;({ owner, ownerFeatures, members } =
|
||||
this.buildOwnerAndMembersViews(members))
|
||||
result.owner = owner
|
||||
@@ -99,7 +93,7 @@
|
||||
let owner = null
|
||||
let ownerFeatures = null
|
||||
const filteredMembers = []
|
||||
- for (const member of Array.from(members || [])) {
|
||||
+ for (const member of members || []) {
|
||||
if (member.privilegeLevel === 'owner') {
|
||||
ownerFeatures = member.user.features
|
||||
owner = this.buildUserModelView(member.user, 'owner')
|
||||
@@ -128,24 +122,15 @@
|
||||
},
|
||||
|
||||
buildFolderModelView(folder) {
|
||||
- let file
|
||||
const fileRefs = _.filter(folder.fileRefs || [], file => file != null)
|
||||
return {
|
||||
_id: folder._id,
|
||||
name: folder.name,
|
||||
- folders: Array.from(folder.folders || []).map(childFolder =>
|
||||
+ folders: (folder.folders || []).map(childFolder =>
|
||||
this.buildFolderModelView(childFolder)
|
||||
),
|
||||
- fileRefs: (() => {
|
||||
- const result = []
|
||||
- for (file of Array.from(fileRefs)) {
|
||||
- result.push(this.buildFileModelView(file))
|
||||
- }
|
||||
- return result
|
||||
- })(),
|
||||
- docs: Array.from(folder.docs || []).map(doc =>
|
||||
- this.buildDocModelView(doc)
|
||||
- ),
|
||||
+ fileRefs: fileRefs.map(file => this.buildFileModelView(file)),
|
||||
+ docs: (folder.docs || []).map(doc => this.buildDocModelView(doc)),
|
||||
}
|
||||
},
|
||||
|
||||
@@ -164,4 +149,21 @@
|
||||
name: doc.name,
|
||||
}
|
||||
},
|
||||
+
|
||||
+ buildInvitesView(invites) {
|
||||
+ if (invites == null) {
|
||||
+ return []
|
||||
+ }
|
||||
+ return invites.map(invite =>
|
||||
+ _.pick(invite, [
|
||||
+ '_id',
|
||||
+ 'createdAt',
|
||||
+ 'email',
|
||||
+ 'expires',
|
||||
+ 'privileges',
|
||||
+ 'projectId',
|
||||
+ 'sendingUserId',
|
||||
+ ])
|
||||
+ )
|
||||
+ },
|
||||
}
|
13
server-ce/hotfix/4.0.5/Dockerfile
Normal file
13
server-ce/hotfix/4.0.5/Dockerfile
Normal file
|
@ -0,0 +1,13 @@
|
|||
FROM sharelatex/sharelatex:4.0.4
|
||||
|
||||
# Patch: clear invite and invite tokens through the websocket
|
||||
COPY pr_13427.patch .
|
||||
RUN patch -p0 < pr_13427.patch
|
||||
|
||||
# Patch: https://github.com/Automattic/mongoose/commit/f1efabf350522257364aa5c2cb36e441cf08f1a2
|
||||
COPY mongoose_proto.patch .
|
||||
RUN patch -p0 < mongoose_proto.patch
|
||||
|
||||
# Patch: Allow digits in PDF filenames
|
||||
COPY pr_13122.patch .
|
||||
RUN patch -p0 < pr_13122.patch
|
12
server-ce/hotfix/4.0.5/mongoose_proto.patch
Normal file
12
server-ce/hotfix/4.0.5/mongoose_proto.patch
Normal file
|
@ -0,0 +1,12 @@
|
|||
--- services/web/node_modules/mongoose/lib/document.js
|
||||
+++ services/web/node_modules/mongoose/lib/document.js
|
||||
@@ -739,6 +739,10 @@ function init(self, obj, doc, opts, prefix) {
|
||||
|
||||
function _init(index) {
|
||||
i = keys[index];
|
||||
+ // avoid prototype pollution
|
||||
+ if (i === '__proto__' || i === 'constructor') {
|
||||
+ return;
|
||||
+ }
|
||||
path = prefix + i;
|
||||
schemaType = docSchema.path(path);
|
11
server-ce/hotfix/4.0.5/pr_13122.patch
Normal file
11
server-ce/hotfix/4.0.5/pr_13122.patch
Normal file
|
@ -0,0 +1,11 @@
|
|||
--- services/web/app/src/Features/Compile/CompileController.js
|
||||
+++ services/web/app/src/Features/Compile/CompileController.js
|
||||
@@ -371,7 +371,7 @@ module.exports = CompileController = {
|
||||
},
|
||||
|
||||
_getSafeProjectName(project) {
|
||||
- return project.name.replace(/\P{L}/gu, '_')
|
||||
+ return project.name.replace(/[^\p{L}\p{Nd}]/gu, '_')
|
||||
},
|
||||
|
||||
deleteAuxFiles(req, res, next) {
|
92
server-ce/hotfix/4.0.5/pr_13427.patch
Normal file
92
server-ce/hotfix/4.0.5/pr_13427.patch
Normal file
|
@ -0,0 +1,92 @@
|
|||
--- services/web/app/src/Features/Editor/EditorHttpController.js
|
||||
+++ services/web/app/src/Features/Editor/EditorHttpController.js
|
||||
@@ -73,6 +73,7 @@ async function joinProject(req, res, next) {
|
||||
if (isRestrictedUser) {
|
||||
project.owner = { _id: project.owner._id }
|
||||
project.members = []
|
||||
+ project.invites = []
|
||||
}
|
||||
// Only show the 'renamed or deleted' message once
|
||||
if (project.deletedByExternalDataSource) {
|
||||
--- services/web/app/src/Features/Project/ProjectEditorHandler.js
|
||||
+++ services/web/app/src/Features/Project/ProjectEditorHandler.js
|
||||
@@ -48,19 +48,13 @@
|
||||
deletedDocsFromDocstore
|
||||
),
|
||||
members: [],
|
||||
- invites,
|
||||
+ invites: this.buildInvitesView(invites),
|
||||
imageName:
|
||||
project.imageName != null
|
||||
? Path.basename(project.imageName)
|
||||
: undefined,
|
||||
}
|
||||
|
||||
- if (result.invites == null) {
|
||||
- result.invites = []
|
||||
- }
|
||||
- result.invites.forEach(invite => {
|
||||
- delete invite.token
|
||||
- })
|
||||
;({ owner, ownerFeatures, members } =
|
||||
this.buildOwnerAndMembersViews(members))
|
||||
result.owner = owner
|
||||
@@ -99,7 +93,7 @@
|
||||
let owner = null
|
||||
let ownerFeatures = null
|
||||
const filteredMembers = []
|
||||
- for (const member of Array.from(members || [])) {
|
||||
+ for (const member of members || []) {
|
||||
if (member.privilegeLevel === 'owner') {
|
||||
ownerFeatures = member.user.features
|
||||
owner = this.buildUserModelView(member.user, 'owner')
|
||||
@@ -128,24 +122,15 @@
|
||||
},
|
||||
|
||||
buildFolderModelView(folder) {
|
||||
- let file
|
||||
const fileRefs = _.filter(folder.fileRefs || [], file => file != null)
|
||||
return {
|
||||
_id: folder._id,
|
||||
name: folder.name,
|
||||
- folders: Array.from(folder.folders || []).map(childFolder =>
|
||||
+ folders: (folder.folders || []).map(childFolder =>
|
||||
this.buildFolderModelView(childFolder)
|
||||
),
|
||||
- fileRefs: (() => {
|
||||
- const result = []
|
||||
- for (file of Array.from(fileRefs)) {
|
||||
- result.push(this.buildFileModelView(file))
|
||||
- }
|
||||
- return result
|
||||
- })(),
|
||||
- docs: Array.from(folder.docs || []).map(doc =>
|
||||
- this.buildDocModelView(doc)
|
||||
- ),
|
||||
+ fileRefs: fileRefs.map(file => this.buildFileModelView(file)),
|
||||
+ docs: (folder.docs || []).map(doc => this.buildDocModelView(doc)),
|
||||
}
|
||||
},
|
||||
|
||||
@@ -164,4 +149,21 @@
|
||||
name: doc.name,
|
||||
}
|
||||
},
|
||||
+
|
||||
+ buildInvitesView(invites) {
|
||||
+ if (invites == null) {
|
||||
+ return []
|
||||
+ }
|
||||
+ return invites.map(invite =>
|
||||
+ _.pick(invite, [
|
||||
+ '_id',
|
||||
+ 'createdAt',
|
||||
+ 'email',
|
||||
+ 'expires',
|
||||
+ 'privileges',
|
||||
+ 'projectId',
|
||||
+ 'sendingUserId',
|
||||
+ ])
|
||||
+ )
|
||||
+ },
|
||||
}
|
Loading…
Reference in a new issue