From e00fcd93a18d8577b5f6aca873e26b4d02cb7bdb Mon Sep 17 00:00:00 2001 From: zadam Date: Tue, 22 Mar 2022 23:17:47 +0100 Subject: [PATCH] added #shareDisallowRobotIndexing label and reworked how the child-image exclusion works --- .../attribute_widgets/attribute_detail.js | 1 + src/services/attributes.js | 5 -- src/services/builtin_attributes.js | 1 + src/share/routes.js | 57 ++++++++++++------- src/share/shaca/entities/attribute.js | 4 +- src/share/shaca/entities/branch.js | 2 + src/share/shaca/entities/note.js | 7 ++- src/views/share/page.ejs | 3 + src/views/share/tree_item.ejs | 4 +- 9 files changed, 52 insertions(+), 32 deletions(-) diff --git a/src/public/app/widgets/attribute_widgets/attribute_detail.js b/src/public/app/widgets/attribute_widgets/attribute_detail.js index 9f85945fb..01c6b80a2 100644 --- a/src/public/app/widgets/attribute_widgets/attribute_detail.js +++ b/src/public/app/widgets/attribute_widgets/attribute_detail.js @@ -216,6 +216,7 @@ const ATTR_HELP = { "shareOmitDefaultCss": "default share page CSS will be omitted. Use when you make extensive styling changes.", "shareRoot": "marks note which is served on /share root.", "shareRaw": "note will be served in its raw format, without HTML wrapper", + "shareDisallowRobotIndexing": `will forbid robot indexing of this note via X-Robots-Tag: noindex header`, "displayRelations": "comma delimited names of relations which should be displayed. All other ones will be hidden.", "hideRelations": "comma delimited names of relations which should be hidden. All other ones will be displayed.", }, diff --git a/src/services/attributes.js b/src/services/attributes.js index 3ddd41223..5c6d309a0 100644 --- a/src/services/attributes.js +++ b/src/services/attributes.js @@ -128,10 +128,6 @@ function isAttributeDangerous(type, name) { ); } -function getBuiltinAttributeNames() { - return BUILTIN_ATTRIBUTES; -} - function sanitizeAttributeName(origName) { let fixedName; @@ -156,6 +152,5 @@ module.exports = { getAttributeNames, isAttributeType, isAttributeDangerous, - getBuiltinAttributeNames, sanitizeAttributeName }; diff --git a/src/services/builtin_attributes.js b/src/services/builtin_attributes.js index ed8a61a27..51243aa0b 100644 --- a/src/services/builtin_attributes.js +++ b/src/services/builtin_attributes.js @@ -47,6 +47,7 @@ module.exports = [ { type: 'label', name: 'shareOmitDefaultCss' }, { type: 'label', name: 'shareRoot' }, { type: 'label', name: 'shareRaw' }, + { type: 'label', name: 'shareDisallowRobotIndexing' }, { type: 'label', name: 'displayRelations' }, { type: 'label', name: 'hideRelations' }, diff --git a/src/share/routes.js b/src/share/routes.js index 27ec655f7..609028597 100644 --- a/src/share/routes.js +++ b/src/share/routes.js @@ -20,30 +20,39 @@ function getSharedSubTreeRoot(note) { return getSharedSubTreeRoot(parentNote); } +function addNoIndexHeader(note, res) { + if (note.hasLabel('shareDisallowRobotIndexing')) { + res.setHeader('X-Robots-Tag', 'noindex'); + } +} + function register(router) { function renderNote(note, res) { - if (note) { - if (note.hasLabel('shareRaw')) { - res.setHeader('Content-Type', note.mime); - - res.send(note.getContent()); - return; - } - - const {header, content, isEmpty} = contentRenderer.getContent(note); - - const subRoot = getSharedSubTreeRoot(note); - - res.render("share/page", { - note, - header, - content, - isEmpty, - subRoot - }); - } else { + if (!note) { res.status(404).render("share/404"); + return; } + + addNoIndexHeader(note, res); + + if (note.hasLabel('shareRaw') || ['image', 'file'].includes(note.type)) { + res.setHeader('Content-Type', note.mime); + + res.send(note.getContent()); + return; + } + + const {header, content, isEmpty} = contentRenderer.getContent(note); + + const subRoot = getSharedSubTreeRoot(note); + + res.render("share/page", { + note, + header, + content, + isEmpty, + subRoot + }); } router.get(['/share', '/share/'], (req, res, next) => { @@ -70,6 +79,8 @@ function register(router) { return res.status(404).send(`Note ${noteId} not found`); } + addNoIndexHeader(note, res); + res.json(note.getPojoWithAttributes()); }); @@ -81,6 +92,8 @@ function register(router) { return res.status(404).send(`Note ${noteId} not found`); } + addNoIndexHeader(note, res); + const utils = require("../services/utils"); const filename = utils.formatDownloadTitle(note.title, note.type, note.mime); @@ -103,6 +116,8 @@ function register(router) { return res.status(400).send("Requested note is not an image"); } + addNoIndexHeader(image, res); + res.set('Content-Type', image.mime); res.send(image.getContent()); @@ -117,6 +132,8 @@ function register(router) { return res.status(404).send(`Note ${noteId} not found`); } + addNoIndexHeader(note, res); + res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); res.setHeader('Content-Type', note.mime); diff --git a/src/share/shaca/entities/attribute.js b/src/share/shaca/entities/attribute.js index 471a3793e..ac87c4ddc 100644 --- a/src/share/shaca/entities/attribute.js +++ b/src/share/shaca/entities/attribute.js @@ -34,9 +34,9 @@ class Attribute extends AbstractEntity { const linkedChildNote = this.note.getChildNotes().find(childNote => childNote.noteId === this.value); if (linkedChildNote) { - this.note.children = this.note.children.filter(childNote => childNote.noteId !== this.value); + const branch = this.shaca.getBranchFromChildAndParent(this.noteId, linkedChildNote.noteId); - linkedChildNote.parents = linkedChildNote.parents.filter(parentNote => parentNote.noteId !== this.noteId); + branch.isHidden = true; } } diff --git a/src/share/shaca/entities/branch.js b/src/share/shaca/entities/branch.js index 1f84d83a9..a1b55538e 100644 --- a/src/share/shaca/entities/branch.js +++ b/src/share/shaca/entities/branch.js @@ -16,6 +16,8 @@ class Branch extends AbstractEntity { this.prefix = prefix; /** @param {boolean} */ this.isExpanded = !!isExpanded; + /** @param {boolean} */ + this.isHidden = false; const childNote = this.childNote; const parentNote = this.parentNote; diff --git a/src/share/shaca/entities/note.js b/src/share/shaca/entities/note.js index 95b3d1f83..d19548760 100644 --- a/src/share/shaca/entities/note.js +++ b/src/share/shaca/entities/note.js @@ -59,7 +59,10 @@ class Note extends AbstractEntity { } getVisibleChildNotes() { - return this.children.filter(childNote => !childNote.hasLabel('shareHiddenFromTree') && !childNote.isProtected); + return this.getChildBranches() + .filter(branch => !branch.isHidden) + .map(branch => branch.getNote()) + .filter(childNote => !childNote.hasLabel('shareHiddenFromTree') && !childNote.isProtected); } hasChildren() { @@ -67,7 +70,7 @@ class Note extends AbstractEntity { } hasVisibleChildren() { - return this.children && !!this.children.find(childNote => !childNote.hasLabel('shareHiddenFromTree') && !childNote.isProtected); + return this.getVisibleChildNotes().length > 0; } getChildBranches() { diff --git a/src/views/share/page.ejs b/src/views/share/page.ejs index ed52d218b..38b4955c9 100644 --- a/src/views/share/page.ejs +++ b/src/views/share/page.ejs @@ -21,6 +21,9 @@ <% for (const jsRelation of note.getRelations("shareJs")) { %> <% } %> + <% if (note.hasLabel('shareDisallowRobotIndexing')) { %> + + <% } %> <%- header %> <%= note.title %> diff --git a/src/views/share/tree_item.ejs b/src/views/share/tree_item.ejs index 12dc9f11a..9d310f003 100644 --- a/src/views/share/tree_item.ejs +++ b/src/views/share/tree_item.ejs @@ -8,12 +8,10 @@ <% if (note.hasChildren()) { %> <% } %>