@adobe/helix-html-pipeline 3.7.5 → 3.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [3.7.7](https://github.com/adobe/helix-html-pipeline/compare/v3.7.6...v3.7.7) (2022-12-08)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * remove og:url meta tag if overridden with "" ([d605625](https://github.com/adobe/helix-html-pipeline/commit/d6056258ab5188362cd6afd94cd860a5dca6880a)), closes [#214](https://github.com/adobe/helix-html-pipeline/issues/214)
7
+
8
+ ## [3.7.6](https://github.com/adobe/helix-html-pipeline/compare/v3.7.5...v3.7.6) (2022-11-29)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * improve custom header handling ([#205](https://github.com/adobe/helix-html-pipeline/issues/205)) ([3867fef](https://github.com/adobe/helix-html-pipeline/commit/3867fef601735ed8dc6921c0391bd0de148f0245)), closes [#204](https://github.com/adobe/helix-html-pipeline/issues/204) [#202](https://github.com/adobe/helix-html-pipeline/issues/202) [#199](https://github.com/adobe/helix-html-pipeline/issues/199)
14
+
1
15
  ## [3.7.5](https://github.com/adobe/helix-html-pipeline/compare/v3.7.4...v3.7.5) (2022-11-18)
2
16
 
3
17
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/helix-html-pipeline",
3
- "version": "3.7.5",
3
+ "version": "3.7.7",
4
4
  "description": "Helix HTML Pipeline",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -50,7 +50,7 @@
50
50
  "hast-util-to-html": "8.0.3",
51
51
  "hast-util-to-string": "2.0.0",
52
52
  "hastscript": "7.1.0",
53
- "jose": "4.11.0",
53
+ "jose": "4.11.1",
54
54
  "mdast-util-gfm-footnote": "1.0.1",
55
55
  "mdast-util-gfm-strikethrough": "1.0.2",
56
56
  "mdast-util-gfm-table": "1.0.6",
@@ -79,20 +79,20 @@
79
79
  "devDependencies": {
80
80
  "@adobe/eslint-config-helix": "1.3.2",
81
81
  "@markedjs/html-differ": "4.0.2",
82
- "@semantic-release/changelog": "6.0.1",
82
+ "@semantic-release/changelog": "6.0.2",
83
83
  "@semantic-release/git": "10.0.1",
84
84
  "@semantic-release/npm": "9.0.1",
85
85
  "c8": "7.12.0",
86
- "eslint": "8.27.0",
86
+ "eslint": "8.29.0",
87
87
  "eslint-import-resolver-exports": "1.0.0-beta.3",
88
88
  "eslint-plugin-header": "3.1.1",
89
89
  "eslint-plugin-import": "2.26.0",
90
- "esmock": "2.0.7",
90
+ "esmock": "2.1.0",
91
91
  "husky": "8.0.2",
92
92
  "js-yaml": "4.1.0",
93
- "jsdom": "20.0.2",
93
+ "jsdom": "20.0.3",
94
94
  "junit-report-builder": "3.0.1",
95
- "lint-staged": "13.0.3",
95
+ "lint-staged": "13.0.4",
96
96
  "mocha": "10.1.0",
97
97
  "mocha-multi-reporters": "1.5.1",
98
98
  "remark-gfm": "3.0.1",
@@ -161,8 +161,6 @@ export default function extractMetaData(state, req) {
161
161
  getLocalMetadata(hast),
162
162
  );
163
163
 
164
- const IGNORED_CUSTOM_META = ['twitter:card'];
165
-
166
164
  // first process supported metadata properties
167
165
  [
168
166
  'title',
@@ -179,19 +177,12 @@ export default function extractMetaData(state, req) {
179
177
  delete metaConfig[name];
180
178
  }
181
179
  });
182
- if (Object.keys(metaConfig).length > 0) {
183
- // add rest to meta.custom
184
- meta.custom = Object.entries(metaConfig)
185
- .filter(([name]) => !IGNORED_CUSTOM_META.includes(name))
186
- .map(([name, value]) => ({
187
- name,
188
- value,
189
- property: name.includes(':'),
190
- }));
191
- }
192
-
193
180
  // default value for twitter:card (mandatory for rendering URLs as cards in tweets)
194
181
  meta['twitter:card'] = metaConfig['twitter:card'] || 'summary_large_image';
182
+ delete metaConfig['twitter:card'];
183
+
184
+ // add rest to meta.custom
185
+ meta.custom = metaConfig;
195
186
 
196
187
  if (meta.keywords) {
197
188
  meta.keywords = toList(meta.keywords).join(', ');
@@ -55,29 +55,51 @@ export default async function render(state, req, res) {
55
55
  ]);
56
56
 
57
57
  // add meta
58
+ // (this is so complicated to keep the order backward compatible to make the diff tests happy)
59
+ const metadata = {
60
+ 'og:title': meta.title,
61
+ 'og:description': meta.description,
62
+ 'og:url': meta.url,
63
+ 'og:image': meta.image,
64
+ 'og:image:secure_url': meta.image,
65
+ 'og:image:alt': meta.imageAlt,
66
+ 'og:updated_time': meta.modified_time,
67
+ 'article:tag': meta.tags || [],
68
+ 'article:section': meta.section,
69
+ 'article:published_time': meta.published_time,
70
+ 'article:modified_time': meta.modified_time,
71
+ 'twitter:card': meta['twitter:card'],
72
+ 'twitter:title': meta.title,
73
+ 'twitter:description': meta.description,
74
+ 'twitter:image': meta.image,
75
+ };
76
+ // remove meta with no values
77
+ for (const name of Object.keys(metadata)) {
78
+ if (!metadata[name]) {
79
+ delete metadata[name];
80
+ }
81
+ }
82
+ // append custom metadata
83
+ Object.assign(metadata, meta.custom);
84
+
85
+ // remove og:url with explicit removal marker
86
+ if (metadata['og:url'] === '""') {
87
+ delete metadata['og:url'];
88
+ }
89
+
58
90
  appendElement($head, createElement('link', 'rel', 'canonical', 'href', content.meta.canonical));
59
91
  appendElement($head, createElement('meta', 'name', 'description', 'content', content.meta.description));
60
92
  appendElement($head, createElement('meta', 'name', 'keywords', 'content', content.meta.keywords));
61
- appendElement($head, createElement('meta', 'property', 'og:title', 'content', content.meta.title));
62
- appendElement($head, createElement('meta', 'property', 'og:description', 'content', content.meta.description));
63
- appendElement($head, createElement('meta', 'property', 'og:url', 'content', content.meta.url));
64
- appendElement($head, createElement('meta', 'property', 'og:image', 'content', content.meta.image));
65
- appendElement($head, createElement('meta', 'property', 'og:image:secure_url', 'content', content.meta.image));
66
- appendElement($head, createElement('meta', 'property', 'og:image:alt', 'content', content.meta.imageAlt));
67
- appendElement($head, createElement('meta', 'property', 'og:updated_time', 'content', content.meta.modified_time));
68
- for (const tag of (meta.tags || [])) {
69
- appendElement($head, createElement('meta', 'property', 'article:tag', 'content', tag));
70
- }
71
- appendElement($head, createElement('meta', 'property', 'article:section', 'content', content.meta.section));
72
- appendElement($head, createElement('meta', 'property', 'article:published_time', 'content', content.meta.published_time));
73
- appendElement($head, createElement('meta', 'property', 'article:modified_time', 'content', content.meta.modified_time));
74
- appendElement($head, createElement('meta', 'name', 'twitter:card', 'content', content.meta['twitter:card']));
75
- appendElement($head, createElement('meta', 'name', 'twitter:title', 'content', content.meta.title));
76
- appendElement($head, createElement('meta', 'name', 'twitter:description', 'content', content.meta.description));
77
- appendElement($head, createElement('meta', 'name', 'twitter:image', 'content', content.meta.image));
78
93
 
79
- for (const custom of (meta.custom || [])) {
80
- appendElement($head, createElement('meta', custom.property ? 'property' : 'name', custom.name, 'content', custom.value));
94
+ for (const [name, value] of Object.entries(metadata)) {
95
+ const attr = name.includes(':') && !name.startsWith('twitter:') ? 'property' : 'name';
96
+ if (Array.isArray(value)) {
97
+ for (const v of value) {
98
+ appendElement($head, createElement('meta', attr, name, 'content', v));
99
+ }
100
+ } else {
101
+ appendElement($head, createElement('meta', attr, name, 'content', value));
102
+ }
81
103
  }
82
104
  appendElement($head, createElement('link', 'rel', 'alternate', 'type', 'application/xml+atom', 'href', meta.feed, 'title', `${meta.title} feed`));
83
105
 
@@ -9,7 +9,43 @@
9
9
  * OF ANY KIND, either express or implied. See the License for the specific language
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
- import { cleanupHeaderValue } from '@adobe/helix-shared-utils';
12
+ function cleanupHeaderValue(value) {
13
+ return value
14
+ .replace(/[^\t\u0020-\u007E\u0080-\u00FF]/g, '')
15
+ .substring(0, 1024 * 64);
16
+ }
17
+
18
+ /**
19
+ * Computes the access-control-allow-origin header value.
20
+ * The value can either be a single value or a comma separated list of origin names or patterns.
21
+ * If only a single static value is given (eg `*` or `https://www.adobe.com`), it is used verbatim.
22
+ * If multiple values are given, the one matching the origin request header is used.
23
+ * If any of the values is a regexp, the origin request header is used, if any match is given.
24
+ *
25
+ * @param {PipelineRequest} req
26
+ * @param {string} value
27
+ * @return {string} the access-control-allow-origin header value.
28
+ */
29
+ function getACAOriginValue(req, value) {
30
+ /** @type string */
31
+ const origin = req.headers.get('origin') || '*';
32
+ const values = value.split(',')
33
+ .map((v) => v.trim());
34
+
35
+ if (values.length === 1 && !values[0].startsWith('/')) {
36
+ return values[0];
37
+ }
38
+
39
+ for (const v of values) {
40
+ if (v.startsWith('/') && v.endsWith('/') && new RegExp(v.substring(1, v.length - 1)).test(origin)) {
41
+ return origin;
42
+ }
43
+ if (v === origin) {
44
+ return origin;
45
+ }
46
+ }
47
+ return '';
48
+ }
13
49
 
14
50
  /**
15
51
  * Decorates the pipeline response object with the headers defined in metadata.json.
@@ -23,7 +59,13 @@ export default function setCustomResponseHeaders(state, req, res) {
23
59
  Object.entries(state.headers.getModifiers(state.info.path)).forEach(([name, value]) => {
24
60
  // only use `link` header for extensionless pipeline
25
61
  if (name !== 'link' || (state.type === 'html' && state.info.selector === '')) {
26
- res.headers.set(name, cleanupHeaderValue(value));
62
+ let val = cleanupHeaderValue(value);
63
+ if (name === 'access-control-allow-origin') {
64
+ val = getACAOriginValue(req, val);
65
+ }
66
+ if (val) {
67
+ res.headers.set(name, val);
68
+ }
27
69
  }
28
70
  });
29
71
  }