ghost 4.48.0 → 4.48.3
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/core/frontend/helpers/date.js +3 -1
- package/core/server/services/mega/template.js +44 -16
- package/package.json +3 -3
- package/yarn.lock +27 -11
|
@@ -45,7 +45,9 @@ module.exports = function (...attrs) {
|
|
|
45
45
|
// i18n: Making dates, including month names, translatable to any language.
|
|
46
46
|
// Documentation: http://momentjs.com/docs/#/i18n/
|
|
47
47
|
// Locales: https://github.com/moment/moment/tree/develop/locale
|
|
48
|
-
|
|
48
|
+
if (locale && locale.match('^[^/\\\\]*$') !== null) {
|
|
49
|
+
dateMoment.locale(locale);
|
|
50
|
+
}
|
|
49
51
|
|
|
50
52
|
if (timeago) {
|
|
51
53
|
date = dateMoment.tz(timezone).from(timeNow);
|
|
@@ -1,15 +1,43 @@
|
|
|
1
1
|
/* eslint indent: warn, no-irregular-whitespace: warn */
|
|
2
2
|
const iff = (cond, yes, no) => (cond ? yes : no);
|
|
3
|
+
const sanitizeHtml = require('sanitize-html');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @template {Object.<string, any>} Input
|
|
7
|
+
* @param {Input} obj
|
|
8
|
+
* @param {string[]} [keys]
|
|
9
|
+
* @returns {Input}
|
|
10
|
+
*/
|
|
11
|
+
const sanitizeKeys = (obj, keys) => {
|
|
12
|
+
const sanitized = Object.assign({}, obj);
|
|
13
|
+
const keysToSanitize = keys || Object.keys(obj);
|
|
14
|
+
|
|
15
|
+
for (const key of keysToSanitize) {
|
|
16
|
+
if (typeof sanitized[key] === 'string') {
|
|
17
|
+
// @ts-ignore
|
|
18
|
+
sanitized[key] = sanitizeHtml(sanitized[key], {
|
|
19
|
+
allowedTags: false,
|
|
20
|
+
allowedAttributes: false
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return sanitized;
|
|
26
|
+
};
|
|
27
|
+
|
|
3
28
|
module.exports = ({post, site, newsletter, templateSettings}) => {
|
|
4
29
|
const date = new Date();
|
|
5
30
|
const hasFeatureImageCaption = templateSettings.showFeatureImage && post.feature_image && post.feature_image_caption;
|
|
31
|
+
const cleanPost = sanitizeKeys(post, ['title', 'excerpt', 'html', 'feature_image_alt', 'feature_image_caption']);
|
|
32
|
+
const cleanSite = sanitizeKeys(site, ['title']);
|
|
33
|
+
const cleanNewsletter = sanitizeKeys(newsletter, ['name']);
|
|
6
34
|
return `<!doctype html>
|
|
7
35
|
<html>
|
|
8
36
|
|
|
9
37
|
<head>
|
|
10
38
|
<meta name="viewport" content="width=device-width" />
|
|
11
39
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
12
|
-
<title>${
|
|
40
|
+
<title>${cleanPost.title}</title>
|
|
13
41
|
<style>
|
|
14
42
|
/* -------------------------------------
|
|
15
43
|
GLOBAL RESETS
|
|
@@ -1137,7 +1165,7 @@ ${ templateSettings.showBadge ? `
|
|
|
1137
1165
|
</head>
|
|
1138
1166
|
|
|
1139
1167
|
<body>
|
|
1140
|
-
<span class="preheader">${
|
|
1168
|
+
<span class="preheader">${ cleanPost.excerpt ? cleanPost.excerpt : `${cleanPost.title} – ` }</span>
|
|
1141
1169
|
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="body" width="100%">
|
|
1142
1170
|
|
|
1143
1171
|
<!-- Outlook doesn't respect max-width so we need an extra centered table -->
|
|
@@ -1172,24 +1200,24 @@ ${ templateSettings.showBadge ? `
|
|
|
1172
1200
|
<tr>
|
|
1173
1201
|
<td class="${templateSettings.showHeaderTitle ? `site-info-bordered` : `site-info`}" width="100%" align="center">
|
|
1174
1202
|
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
|
|
1175
|
-
${ templateSettings.showHeaderIcon &&
|
|
1203
|
+
${ templateSettings.showHeaderIcon && cleanSite.iconUrl ? `
|
|
1176
1204
|
<tr>
|
|
1177
|
-
<td class="site-icon"><a href="${
|
|
1205
|
+
<td class="site-icon"><a href="${cleanSite.url}"><img src="${cleanSite.iconUrl}" alt="${cleanSite.title}" border="0"></a></td>
|
|
1178
1206
|
</tr>
|
|
1179
1207
|
` : ``}
|
|
1180
1208
|
${ templateSettings.showHeaderTitle ? `
|
|
1181
1209
|
<tr>
|
|
1182
|
-
<td class="site-url ${!templateSettings.showHeaderName ? 'site-url-bottom-padding' : ''}"><div style="width: 100% !important;"><a href="${
|
|
1210
|
+
<td class="site-url ${!templateSettings.showHeaderName ? 'site-url-bottom-padding' : ''}"><div style="width: 100% !important;"><a href="${cleanSite.url}" class="site-title">${cleanSite.title}</a></div></td>
|
|
1183
1211
|
</tr>
|
|
1184
1212
|
` : ``}
|
|
1185
1213
|
${ templateSettings.showHeaderName && templateSettings.showHeaderTitle ? `
|
|
1186
1214
|
<tr>
|
|
1187
|
-
<td class="site-url site-url-bottom-padding"><div style="width: 100% !important;"><a href="${
|
|
1215
|
+
<td class="site-url site-url-bottom-padding"><div style="width: 100% !important;"><a href="${cleanSite.url}" class="site-subtitle">${cleanNewsletter.name}</a></div></td>
|
|
1188
1216
|
</tr>
|
|
1189
1217
|
` : ``}
|
|
1190
1218
|
${ templateSettings.showHeaderName && !templateSettings.showHeaderTitle ? `
|
|
1191
1219
|
<tr>
|
|
1192
|
-
<td class="site-url site-url-bottom-padding"><div style="width: 100% !important;"><a href="${
|
|
1220
|
+
<td class="site-url site-url-bottom-padding"><div style="width: 100% !important;"><a href="${cleanSite.url}" class="site-title">${cleanNewsletter.name}</a></div></td>
|
|
1193
1221
|
</tr>
|
|
1194
1222
|
` : ``}
|
|
1195
1223
|
|
|
@@ -1201,7 +1229,7 @@ ${ templateSettings.showBadge ? `
|
|
|
1201
1229
|
|
|
1202
1230
|
<tr>
|
|
1203
1231
|
<td class="post-title ${templateSettings.titleFontCategory === 'serif' ? `post-title-serif` : `` } ${templateSettings.titleAlignment === 'left' ? `post-title-left` : ``}">
|
|
1204
|
-
<a href="${
|
|
1232
|
+
<a href="${cleanPost.url}" class="post-title-link ${templateSettings.titleAlignment === 'left' ? `post-title-link-left` : ``}">${cleanPost.title}</a>
|
|
1205
1233
|
</td>
|
|
1206
1234
|
</tr>
|
|
1207
1235
|
<tr>
|
|
@@ -1209,28 +1237,28 @@ ${ templateSettings.showBadge ? `
|
|
|
1209
1237
|
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%">
|
|
1210
1238
|
<tr>
|
|
1211
1239
|
<td class="post-meta ${templateSettings.titleAlignment === 'left' ? `post-meta-left` : ``}">
|
|
1212
|
-
By ${
|
|
1213
|
-
${
|
|
1214
|
-
<a href="${
|
|
1240
|
+
By ${cleanPost.authors} –
|
|
1241
|
+
${cleanPost.published_at} –
|
|
1242
|
+
<a href="${cleanPost.url}" class="view-online-link">View online →</a>
|
|
1215
1243
|
</td>
|
|
1216
1244
|
</tr>
|
|
1217
1245
|
</table>
|
|
1218
1246
|
</td>
|
|
1219
1247
|
</tr>
|
|
1220
|
-
${ templateSettings.showFeatureImage &&
|
|
1248
|
+
${ templateSettings.showFeatureImage && cleanPost.feature_image ? `
|
|
1221
1249
|
<tr>
|
|
1222
|
-
<td class="feature-image ${hasFeatureImageCaption ? 'feature-image-with-caption' : ''}"><img src="${
|
|
1250
|
+
<td class="feature-image ${hasFeatureImageCaption ? 'feature-image-with-caption' : ''}"><img src="${cleanPost.feature_image}"${cleanPost.feature_image_width ? ` width="${cleanPost.feature_image_width}"` : ''}${cleanPost.feature_image_alt ? ` alt="${cleanPost.feature_image_alt}"` : ''}></td>
|
|
1223
1251
|
</tr>
|
|
1224
1252
|
` : ``}
|
|
1225
1253
|
${ hasFeatureImageCaption ? `
|
|
1226
1254
|
<tr>
|
|
1227
|
-
<td class="feature-image-caption" align="center">${
|
|
1255
|
+
<td class="feature-image-caption" align="center">${cleanPost.feature_image_caption}</td>
|
|
1228
1256
|
</tr>
|
|
1229
1257
|
` : ``}
|
|
1230
1258
|
<tr>
|
|
1231
1259
|
<td class="${(templateSettings.bodyFontCategory === 'sans_serif') ? `post-content-sans-serif` : `post-content` }">
|
|
1232
1260
|
<!-- POST CONTENT START -->
|
|
1233
|
-
${
|
|
1261
|
+
${cleanPost.html}
|
|
1234
1262
|
<!-- POST CONTENT END -->
|
|
1235
1263
|
</td>
|
|
1236
1264
|
</tr>
|
|
@@ -1245,7 +1273,7 @@ ${ templateSettings.showBadge ? `
|
|
|
1245
1273
|
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="padding-top: 40px; padding-bottom: 30px;">
|
|
1246
1274
|
${iff(!!templateSettings.footerContent, `<tr><td class="footer">${templateSettings.footerContent}</td></tr>`, '')}
|
|
1247
1275
|
<tr>
|
|
1248
|
-
<td class="footer">${
|
|
1276
|
+
<td class="footer">${cleanSite.title} © ${date.getFullYear()} – <a href="%recipient.unsubscribe_url%">Unsubscribe</a></td>
|
|
1249
1277
|
</tr>
|
|
1250
1278
|
|
|
1251
1279
|
${ templateSettings.showBadge ? `
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ghost",
|
|
3
|
-
"version": "4.48.
|
|
3
|
+
"version": "4.48.3",
|
|
4
4
|
"description": "The professional publishing platform",
|
|
5
5
|
"author": "Ghost Foundation",
|
|
6
6
|
"homepage": "https://ghost.org",
|
|
@@ -152,8 +152,8 @@
|
|
|
152
152
|
"jsonwebtoken": "8.5.1",
|
|
153
153
|
"juice": "8.0.0",
|
|
154
154
|
"keypair": "1.0.4",
|
|
155
|
-
"knex": "2.
|
|
156
|
-
"knex-migrator": "4.2.
|
|
155
|
+
"knex": "2.1.0",
|
|
156
|
+
"knex-migrator": "4.2.11",
|
|
157
157
|
"lodash": "4.17.21",
|
|
158
158
|
"luxon": "2.3.2",
|
|
159
159
|
"mailgun-js": "0.22.0",
|
package/yarn.lock
CHANGED
|
@@ -1876,6 +1876,11 @@
|
|
|
1876
1876
|
resolved "https://registry.yarnpkg.com/@tryghost/database-info/-/database-info-0.3.3.tgz#dbe27b1fd8d97d5ac4a867eb0accd6d7229048b0"
|
|
1877
1877
|
integrity sha512-nEJYo2RLS7FJoXIaWWpgT3h6N/4FsTtAz2Wm5wvMxk6dVx8LKbZ0D25H069IsrVqqEItJ9kBYcCLmv+6qoPSmw==
|
|
1878
1878
|
|
|
1879
|
+
"@tryghost/database-info@0.3.5":
|
|
1880
|
+
version "0.3.5"
|
|
1881
|
+
resolved "https://registry.yarnpkg.com/@tryghost/database-info/-/database-info-0.3.5.tgz#81b77dc976142a8bbbec81f58d56e89c05a1ecdc"
|
|
1882
|
+
integrity sha512-pRWpmQmdg/KOQdkEHDpOAwYvNNc4nrhQ5X8HEVmvqC5ALEKMS6ghKavQGXSnCfUn6Bu8+GXEZ789mE7YOk32jQ==
|
|
1883
|
+
|
|
1879
1884
|
"@tryghost/debug@0.1.11":
|
|
1880
1885
|
version "0.1.11"
|
|
1881
1886
|
resolved "https://registry.yarnpkg.com/@tryghost/debug/-/debug-0.1.11.tgz#cc21e55ac610190426c366a7c69067c5d53117ad"
|
|
@@ -8061,31 +8066,31 @@ kind-of@^6.0.0, kind-of@^6.0.2:
|
|
|
8061
8066
|
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
|
|
8062
8067
|
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
|
|
8063
8068
|
|
|
8064
|
-
knex-migrator@4.2.
|
|
8065
|
-
version "4.2.
|
|
8066
|
-
resolved "https://registry.yarnpkg.com/knex-migrator/-/knex-migrator-4.2.
|
|
8067
|
-
integrity sha512-
|
|
8069
|
+
knex-migrator@4.2.11:
|
|
8070
|
+
version "4.2.11"
|
|
8071
|
+
resolved "https://registry.yarnpkg.com/knex-migrator/-/knex-migrator-4.2.11.tgz#8e80098039f92210840f9932a024b13db7322bbb"
|
|
8072
|
+
integrity sha512-eQDFuiF645g3qL9UyA2kl8V4oOJfn0Kn6o7vNXj/YA/3Z64BHBzw1syparYKzNhxkb+Cl/VepOXt+1wtaQSv+A==
|
|
8068
8073
|
dependencies:
|
|
8069
|
-
"@tryghost/database-info" "0.3.
|
|
8074
|
+
"@tryghost/database-info" "0.3.5"
|
|
8070
8075
|
"@tryghost/logging" "2.1.8"
|
|
8071
8076
|
bluebird "3.7.2"
|
|
8072
8077
|
commander "5.1.0"
|
|
8073
8078
|
compare-ver "2.0.2"
|
|
8074
8079
|
debug "4.3.4"
|
|
8075
8080
|
ghost-ignition "4.6.3"
|
|
8076
|
-
knex "2.
|
|
8081
|
+
knex "2.1.0"
|
|
8077
8082
|
lodash "4.17.21"
|
|
8078
8083
|
moment "2.24.0"
|
|
8079
8084
|
mysql2 "2.3.3"
|
|
8080
8085
|
nconf "0.12.0"
|
|
8081
8086
|
resolve "1.22.0"
|
|
8082
8087
|
optionalDependencies:
|
|
8083
|
-
sqlite3 "5.0.
|
|
8088
|
+
sqlite3 "5.0.8"
|
|
8084
8089
|
|
|
8085
|
-
knex@2.
|
|
8086
|
-
version "2.
|
|
8087
|
-
resolved "https://registry.yarnpkg.com/knex/-/knex-2.
|
|
8088
|
-
integrity sha512-
|
|
8090
|
+
knex@2.1.0:
|
|
8091
|
+
version "2.1.0"
|
|
8092
|
+
resolved "https://registry.yarnpkg.com/knex/-/knex-2.1.0.tgz#9348aace3a08ff5be26eb1c8e838416ddf1aa216"
|
|
8093
|
+
integrity sha512-vVsnD6UJdSJy55TvCXfFF9syfwyXNxfE9mvr2hJL/4Obciy2EPGoqjDpgRSlMruHuPWDOeYAG25nyrGvU+jJog==
|
|
8089
8094
|
dependencies:
|
|
8090
8095
|
colorette "2.0.16"
|
|
8091
8096
|
commander "^9.1.0"
|
|
@@ -11599,6 +11604,17 @@ sqlite3@5.0.6:
|
|
|
11599
11604
|
optionalDependencies:
|
|
11600
11605
|
node-gyp "8.x"
|
|
11601
11606
|
|
|
11607
|
+
sqlite3@5.0.8:
|
|
11608
|
+
version "5.0.8"
|
|
11609
|
+
resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.0.8.tgz#b4b7eab7156debec80866ef492e01165b4688272"
|
|
11610
|
+
integrity sha512-f2ACsbSyb2D1qFFcqIXPfFscLtPVOWJr5GmUzYxf4W+0qelu5MWrR+FAQE1d5IUArEltBrzSDxDORG8P/IkqyQ==
|
|
11611
|
+
dependencies:
|
|
11612
|
+
"@mapbox/node-pre-gyp" "^1.0.0"
|
|
11613
|
+
node-addon-api "^4.2.0"
|
|
11614
|
+
tar "^6.1.11"
|
|
11615
|
+
optionalDependencies:
|
|
11616
|
+
node-gyp "8.x"
|
|
11617
|
+
|
|
11602
11618
|
sqlstring@^2.3.2:
|
|
11603
11619
|
version "2.3.3"
|
|
11604
11620
|
resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.3.3.tgz#2ddc21f03bce2c387ed60680e739922c65751d0c"
|