ghost 5.59.4 → 5.61.0
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/components/tryghost-adapter-cache-memory-ttl-5.61.0.tgz +0 -0
- package/components/tryghost-adapter-cache-redis-5.61.0.tgz +0 -0
- package/components/tryghost-adapter-manager-5.61.0.tgz +0 -0
- package/components/tryghost-announcement-bar-settings-5.61.0.tgz +0 -0
- package/components/tryghost-api-framework-5.61.0.tgz +0 -0
- package/components/tryghost-api-version-compatibility-service-5.61.0.tgz +0 -0
- package/components/tryghost-audience-feedback-5.61.0.tgz +0 -0
- package/components/tryghost-bookshelf-repository-5.61.0.tgz +0 -0
- package/components/tryghost-bootstrap-socket-5.61.0.tgz +0 -0
- package/components/tryghost-collections-5.61.0.tgz +0 -0
- package/components/tryghost-constants-5.61.0.tgz +0 -0
- package/components/tryghost-custom-theme-settings-service-5.61.0.tgz +0 -0
- package/components/{tryghost-data-generator-5.59.4.tgz → tryghost-data-generator-5.61.0.tgz} +0 -0
- package/components/tryghost-domain-events-5.61.0.tgz +0 -0
- package/components/tryghost-donations-5.61.0.tgz +0 -0
- package/components/tryghost-dynamic-routing-events-5.61.0.tgz +0 -0
- package/components/tryghost-email-analytics-provider-mailgun-5.61.0.tgz +0 -0
- package/components/tryghost-email-analytics-service-5.61.0.tgz +0 -0
- package/components/tryghost-email-content-generator-5.61.0.tgz +0 -0
- package/components/tryghost-email-events-5.61.0.tgz +0 -0
- package/components/tryghost-email-service-5.61.0.tgz +0 -0
- package/components/tryghost-email-suppression-list-5.61.0.tgz +0 -0
- package/components/tryghost-event-aware-cache-wrapper-5.61.0.tgz +0 -0
- package/components/tryghost-express-dynamic-redirects-5.61.0.tgz +0 -0
- package/components/tryghost-external-media-inliner-5.61.0.tgz +0 -0
- package/components/tryghost-extract-api-key-5.61.0.tgz +0 -0
- package/components/tryghost-html-to-plaintext-5.61.0.tgz +0 -0
- package/components/tryghost-i18n-5.61.0.tgz +0 -0
- package/components/tryghost-importer-handler-content-files-5.61.0.tgz +0 -0
- package/components/tryghost-importer-revue-5.61.0.tgz +0 -0
- package/components/tryghost-in-memory-repository-5.61.0.tgz +0 -0
- package/components/tryghost-job-manager-5.61.0.tgz +0 -0
- package/components/tryghost-link-redirects-5.61.0.tgz +0 -0
- package/components/tryghost-link-replacer-5.61.0.tgz +0 -0
- package/components/tryghost-link-tracking-5.61.0.tgz +0 -0
- package/components/tryghost-magic-link-5.61.0.tgz +0 -0
- package/components/tryghost-mail-events-5.61.0.tgz +0 -0
- package/components/tryghost-mailgun-client-5.61.0.tgz +0 -0
- package/components/tryghost-member-attribution-5.61.0.tgz +0 -0
- package/components/tryghost-member-events-5.61.0.tgz +0 -0
- package/components/tryghost-members-api-5.61.0.tgz +0 -0
- package/components/tryghost-members-csv-5.61.0.tgz +0 -0
- package/components/{tryghost-members-events-service-5.59.4.tgz → tryghost-members-events-service-5.61.0.tgz} +0 -0
- package/components/tryghost-members-importer-5.61.0.tgz +0 -0
- package/components/tryghost-members-offers-5.61.0.tgz +0 -0
- package/components/tryghost-members-payments-5.61.0.tgz +0 -0
- package/components/tryghost-members-ssr-5.61.0.tgz +0 -0
- package/components/{tryghost-members-stripe-service-5.59.4.tgz → tryghost-members-stripe-service-5.61.0.tgz} +0 -0
- package/components/tryghost-mentions-email-report-5.61.0.tgz +0 -0
- package/components/tryghost-milestones-5.61.0.tgz +0 -0
- package/components/tryghost-minifier-5.61.0.tgz +0 -0
- package/components/tryghost-model-to-domain-event-interceptor-5.61.0.tgz +0 -0
- package/components/tryghost-mw-api-version-mismatch-5.61.0.tgz +0 -0
- package/components/tryghost-mw-cache-control-5.61.0.tgz +0 -0
- package/components/tryghost-mw-error-handler-5.61.0.tgz +0 -0
- package/components/tryghost-mw-session-from-token-5.61.0.tgz +0 -0
- package/components/tryghost-mw-update-user-last-seen-5.61.0.tgz +0 -0
- package/components/tryghost-mw-version-match-5.61.0.tgz +0 -0
- package/components/tryghost-mw-vhost-5.61.0.tgz +0 -0
- package/components/tryghost-nql-filter-expansions-5.61.0.tgz +0 -0
- package/components/tryghost-oembed-service-5.61.0.tgz +0 -0
- package/components/tryghost-package-json-5.61.0.tgz +0 -0
- package/components/tryghost-post-events-5.61.0.tgz +0 -0
- package/components/tryghost-post-revisions-5.61.0.tgz +0 -0
- package/components/tryghost-posts-service-5.61.0.tgz +0 -0
- package/components/tryghost-recommendations-5.61.0.tgz +0 -0
- package/components/tryghost-referrers-5.61.0.tgz +0 -0
- package/components/tryghost-security-5.61.0.tgz +0 -0
- package/components/tryghost-session-service-5.61.0.tgz +0 -0
- package/components/tryghost-settings-path-manager-5.61.0.tgz +0 -0
- package/components/tryghost-slack-notifications-5.61.0.tgz +0 -0
- package/components/tryghost-staff-service-5.61.0.tgz +0 -0
- package/components/tryghost-stats-service-5.61.0.tgz +0 -0
- package/components/{tryghost-tiers-5.59.4.tgz → tryghost-tiers-5.61.0.tgz} +0 -0
- package/components/tryghost-update-check-service-5.61.0.tgz +0 -0
- package/components/tryghost-verification-trigger-5.61.0.tgz +0 -0
- package/components/tryghost-version-notifications-data-service-5.61.0.tgz +0 -0
- package/components/tryghost-webmentions-5.61.0.tgz +0 -0
- package/content/themes/casper/assets/built/casper.js +1 -1
- package/content/themes/casper/assets/built/casper.js.map +1 -1
- package/content/themes/casper/assets/built/screen.css +1 -1
- package/content/themes/casper/assets/built/screen.css.map +1 -1
- package/content/themes/casper/assets/css/screen.css +503 -0
- package/content/themes/casper/assets/images/default-skin.png +0 -0
- package/content/themes/casper/assets/images/default-skin.svg +1 -0
- package/content/themes/casper/assets/images/preloader.gif +0 -0
- package/content/themes/casper/assets/js/lib/photoswipe-ui-default.min.js +4 -0
- package/content/themes/casper/assets/js/lib/photoswipe.min.js +4 -0
- package/content/themes/casper/assets/js/lightbox.js +109 -0
- package/content/themes/casper/default.hbs +3 -0
- package/content/themes/casper/package.json +1 -1
- package/content/themes/casper/partials/lightbox.hbs +41 -0
- package/core/boot.js +6 -1
- package/core/built/admin/assets/{chunk.143.2aa9967c47c24fab0bf5.js → chunk.143.b297dc36977ec0b8aa47.js} +5 -5
- package/core/built/admin/assets/{chunk.178.f4ba7628b006dda9bce3.js → chunk.178.308d80b60fce060ca358.js} +4 -4
- package/core/built/admin/assets/{ghost-24496fd514838a397808c3a992e5818c.js → ghost-4416ac3815c54eac76c2590d1154a628.js} +51 -54
- package/core/built/admin/assets/ghost-8a4e981c272f793157133814ca7c7e84.css +1 -0
- package/core/built/admin/assets/ghost-dark-084169b0e968ef763dfbbf63b253e0c6.css +1 -0
- package/core/built/admin/assets/{vendor-fff5b0b3c122441beb3170947ae27b9d.js → vendor-3631184082d609038638c1e169a002e7.js} +666 -666
- package/core/built/admin/index.html +6 -6
- package/core/frontend/helpers/comments.js +3 -3
- package/core/frontend/src/cards/css/header_v2.css +10 -9
- package/core/frontend/src/cards/css/signup.css +13 -12
- package/core/frontend/utils/frontend-apps.js +3 -0
- package/core/frontend/web/middleware/cors.js +1 -1
- package/core/frontend/web/middleware/handle-image-sizes.js +1 -1
- package/core/frontend/web/middleware/serve-public-file.js +4 -4
- package/core/frontend/web/site.js +5 -2
- package/core/server/api/endpoints/index.js +8 -0
- package/core/server/api/endpoints/recommendations-public.js +24 -0
- package/core/server/api/endpoints/recommendations.js +71 -0
- package/core/server/api/endpoints/utils/serializers/input/settings.js +2 -1
- package/core/server/data/exporter/table-lists.js +2 -1
- package/core/server/data/migrations/versions/5.61/2023-08-29-10-17-add-recommendations-crud-permissions.js +50 -0
- package/core/server/data/migrations/versions/5.61/2023-08-29-11-39-10-add-recommendations-table.js +18 -0
- package/core/server/data/migrations/versions/5.61/2023-08-30-07-37-04-add-recommendations-enabled-settings.js +8 -0
- package/core/server/data/schema/default-settings/default-settings.json +10 -0
- package/core/server/data/schema/fixtures/fixtures.json +35 -5
- package/core/server/data/schema/schema.js +12 -0
- package/core/server/models/base/bookshelf.js +1 -1
- package/core/server/models/base/plugins/raw-knex.js +4 -3
- package/core/server/models/collection.js +33 -0
- package/core/server/models/post.js +1 -1
- package/core/server/models/recommendation.js +10 -0
- package/core/server/services/api-version-compatibility/index.js +2 -2
- package/core/server/services/api-version-compatibility/mw-version-rewrites.js +1 -1
- package/core/server/services/auth/api-key/admin.js +3 -3
- package/core/server/services/collections/BookshelfCollectionsRepository.js +27 -14
- package/core/server/services/collections/service.js +5 -3
- package/core/server/services/members/middleware.js +10 -10
- package/core/server/services/mentions/WebmentionMetadata.js +2 -1
- package/core/server/services/mentions/service.js +4 -0
- package/core/server/services/{collections/intercept-events.js → model-to-domain-event-interceptor/index.js} +9 -1
- package/core/server/services/recommendations/RecommendationServiceWrapper.js +57 -0
- package/core/server/services/recommendations/index.js +3 -0
- package/core/server/web/admin/app.js +2 -2
- package/core/server/web/api/endpoints/admin/middleware.js +1 -1
- package/core/server/web/api/endpoints/admin/routes.js +9 -3
- package/core/server/web/api/endpoints/content/routes.js +3 -0
- package/core/server/web/api/middleware/cors.js +1 -1
- package/core/server/web/api/middleware/upload.js +2 -2
- package/core/server/web/parent/middleware/request-id.js +1 -1
- package/core/server/web/shared/middleware/uncapitalise.js +1 -1
- package/core/server/web/shared/middleware/url-redirects.js +3 -3
- package/core/server/web/well-known.js +1 -1
- package/core/shared/config/defaults.json +1 -2
- package/core/shared/labs.js +2 -1
- package/core/shared/settings-cache/public.js +2 -1
- package/index.js +5 -0
- package/newrelic.js +53 -0
- package/package.json +164 -161
- package/yarn.lock +2568 -1183
- package/components/tryghost-adapter-cache-memory-ttl-5.59.4.tgz +0 -0
- package/components/tryghost-adapter-cache-redis-5.59.4.tgz +0 -0
- package/components/tryghost-adapter-manager-5.59.4.tgz +0 -0
- package/components/tryghost-announcement-bar-settings-5.59.4.tgz +0 -0
- package/components/tryghost-api-framework-5.59.4.tgz +0 -0
- package/components/tryghost-api-version-compatibility-service-5.59.4.tgz +0 -0
- package/components/tryghost-audience-feedback-5.59.4.tgz +0 -0
- package/components/tryghost-bootstrap-socket-5.59.4.tgz +0 -0
- package/components/tryghost-collections-5.59.4.tgz +0 -0
- package/components/tryghost-constants-5.59.4.tgz +0 -0
- package/components/tryghost-custom-theme-settings-service-5.59.4.tgz +0 -0
- package/components/tryghost-domain-events-5.59.4.tgz +0 -0
- package/components/tryghost-donations-5.59.4.tgz +0 -0
- package/components/tryghost-dynamic-routing-events-5.59.4.tgz +0 -0
- package/components/tryghost-email-analytics-provider-mailgun-5.59.4.tgz +0 -0
- package/components/tryghost-email-analytics-service-5.59.4.tgz +0 -0
- package/components/tryghost-email-content-generator-5.59.4.tgz +0 -0
- package/components/tryghost-email-events-5.59.4.tgz +0 -0
- package/components/tryghost-email-service-5.59.4.tgz +0 -0
- package/components/tryghost-email-suppression-list-5.59.4.tgz +0 -0
- package/components/tryghost-event-aware-cache-wrapper-5.59.4.tgz +0 -0
- package/components/tryghost-express-dynamic-redirects-5.59.4.tgz +0 -0
- package/components/tryghost-external-media-inliner-5.59.4.tgz +0 -0
- package/components/tryghost-extract-api-key-5.59.4.tgz +0 -0
- package/components/tryghost-html-to-plaintext-5.59.4.tgz +0 -0
- package/components/tryghost-i18n-5.59.4.tgz +0 -0
- package/components/tryghost-importer-handler-content-files-5.59.4.tgz +0 -0
- package/components/tryghost-importer-revue-5.59.4.tgz +0 -0
- package/components/tryghost-in-memory-repository-5.59.4.tgz +0 -0
- package/components/tryghost-job-manager-5.59.4.tgz +0 -0
- package/components/tryghost-link-redirects-5.59.4.tgz +0 -0
- package/components/tryghost-link-replacer-5.59.4.tgz +0 -0
- package/components/tryghost-link-tracking-5.59.4.tgz +0 -0
- package/components/tryghost-magic-link-5.59.4.tgz +0 -0
- package/components/tryghost-mail-events-5.59.4.tgz +0 -0
- package/components/tryghost-mailgun-client-5.59.4.tgz +0 -0
- package/components/tryghost-member-attribution-5.59.4.tgz +0 -0
- package/components/tryghost-member-events-5.59.4.tgz +0 -0
- package/components/tryghost-members-api-5.59.4.tgz +0 -0
- package/components/tryghost-members-csv-5.59.4.tgz +0 -0
- package/components/tryghost-members-importer-5.59.4.tgz +0 -0
- package/components/tryghost-members-offers-5.59.4.tgz +0 -0
- package/components/tryghost-members-payments-5.59.4.tgz +0 -0
- package/components/tryghost-members-ssr-5.59.4.tgz +0 -0
- package/components/tryghost-mentions-email-report-5.59.4.tgz +0 -0
- package/components/tryghost-milestones-5.59.4.tgz +0 -0
- package/components/tryghost-minifier-5.59.4.tgz +0 -0
- package/components/tryghost-model-to-domain-event-interceptor-5.59.4.tgz +0 -0
- package/components/tryghost-mw-api-version-mismatch-5.59.4.tgz +0 -0
- package/components/tryghost-mw-cache-control-5.59.4.tgz +0 -0
- package/components/tryghost-mw-error-handler-5.59.4.tgz +0 -0
- package/components/tryghost-mw-session-from-token-5.59.4.tgz +0 -0
- package/components/tryghost-mw-update-user-last-seen-5.59.4.tgz +0 -0
- package/components/tryghost-mw-version-match-5.59.4.tgz +0 -0
- package/components/tryghost-mw-vhost-5.59.4.tgz +0 -0
- package/components/tryghost-nql-filter-expansions-5.59.4.tgz +0 -0
- package/components/tryghost-oembed-service-5.59.4.tgz +0 -0
- package/components/tryghost-package-json-5.59.4.tgz +0 -0
- package/components/tryghost-post-events-5.59.4.tgz +0 -0
- package/components/tryghost-post-revisions-5.59.4.tgz +0 -0
- package/components/tryghost-posts-service-5.59.4.tgz +0 -0
- package/components/tryghost-referrers-5.59.4.tgz +0 -0
- package/components/tryghost-security-5.59.4.tgz +0 -0
- package/components/tryghost-session-service-5.59.4.tgz +0 -0
- package/components/tryghost-settings-path-manager-5.59.4.tgz +0 -0
- package/components/tryghost-slack-notifications-5.59.4.tgz +0 -0
- package/components/tryghost-staff-service-5.59.4.tgz +0 -0
- package/components/tryghost-stats-service-5.59.4.tgz +0 -0
- package/components/tryghost-update-check-service-5.59.4.tgz +0 -0
- package/components/tryghost-verification-trigger-5.59.4.tgz +0 -0
- package/components/tryghost-version-notifications-data-service-5.59.4.tgz +0 -0
- package/components/tryghost-webmentions-5.59.4.tgz +0 -0
- package/core/built/admin/assets/chunk.208.c7452bf9df2ebbf93206.js +0 -12510
- package/core/built/admin/assets/chunk.208.c7452bf9df2ebbf93206.js.LICENSE.txt +0 -250
- package/core/built/admin/assets/ghost-92cf97efa3969188bb2bec0155536d1d.css +0 -1
- package/core/built/admin/assets/ghost-dark-64031cd0a165ea4a338ab05129f863ab.css +0 -1
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<title>Ghost Admin</title>
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
<meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.
|
|
11
|
+
<meta name="ghost-admin/config/environment" content="%7B%22modulePrefix%22%3A%22ghost-admin%22%2C%22environment%22%3A%22production%22%2C%22cdnUrl%22%3A%22%22%2C%22rootURL%22%3A%22%22%2C%22locationType%22%3A%22trailing-hash%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%2C%22Array%22%3Atrue%2C%22String%22%3Atrue%2C%22Function%22%3Afalse%7D%2C%22_APPLICATION_TEMPLATE_WRAPPER%22%3Afalse%2C%22_JQUERY_INTEGRATION%22%3Atrue%2C%22_TEMPLATE_ONLY_GLIMMER_COMPONENTS%22%3Atrue%7D%2C%22APP%22%3A%7B%22version%22%3A%225.61%22%2C%22name%22%3A%22ghost-admin%22%7D%2C%22ember-simple-auth%22%3A%7B%7D%2C%22ember-websockets%22%3A%7B%22socketIO%22%3Atrue%7D%2C%22%40sentry%2Fember%22%3A%7B%22disablePerformance%22%3Atrue%2C%22sentry%22%3A%7B%7D%7D%2C%22ember-cli-mirage%22%3A%7B%22usingProxy%22%3Afalse%2C%22useDefaultPassthroughs%22%3Atrue%7D%2C%22exportApplicationGlobal%22%3Afalse%2C%22ember-load%22%3A%7B%22loadingIndicatorClass%22%3A%22ember-load-indicator%22%7D%7D" />
|
|
12
12
|
|
|
13
13
|
<meta name="HandheldFriendly" content="True" />
|
|
14
14
|
<meta name="MobileOptimized" content="320" />
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
</style>
|
|
38
38
|
|
|
39
39
|
<link integrity="" rel="stylesheet" href="assets/vendor-3e6947aa681f0fb82b193090e520dc73.css">
|
|
40
|
-
<link integrity="" rel="stylesheet" href="assets/ghost-
|
|
40
|
+
<link integrity="" rel="stylesheet" href="assets/ghost-8a4e981c272f793157133814ca7c7e84.css" title="light">
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
</head>
|
|
@@ -56,9 +56,9 @@
|
|
|
56
56
|
|
|
57
57
|
<div id="ember-basic-dropdown-wormhole"></div>
|
|
58
58
|
|
|
59
|
-
<script src="assets/vendor-
|
|
60
|
-
<script src="assets/chunk.208.
|
|
61
|
-
<script src="assets/chunk.143.
|
|
62
|
-
<script src="assets/ghost-
|
|
59
|
+
<script src="assets/vendor-3631184082d609038638c1e169a002e7.js"></script>
|
|
60
|
+
<script src="assets/chunk.208.dbf172ad32f72f21a5dc.js"></script>
|
|
61
|
+
<script src="assets/chunk.143.b297dc36977ec0b8aa47.js"></script>
|
|
62
|
+
<script src="assets/ghost-4416ac3815c54eac76c2590d1154a628.js"></script>
|
|
63
63
|
</body>
|
|
64
64
|
</html>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const {SafeString} = require('../services/handlebars');
|
|
2
|
-
const {urlUtils, getFrontendKey, settingsCache} = require('../services/proxy');
|
|
2
|
+
const {labs, urlUtils, getFrontendKey, settingsCache} = require('../services/proxy');
|
|
3
3
|
const {getFrontendAppConfig, getDataAttributes} = require('../utils/frontend-apps');
|
|
4
4
|
|
|
5
5
|
module.exports = async function comments(options) {
|
|
@@ -50,14 +50,14 @@ module.exports = async function comments(options) {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
const frontendKey = await getFrontendKey();
|
|
53
|
-
const {scriptUrl
|
|
53
|
+
const {scriptUrl} = getFrontendAppConfig('comments');
|
|
54
54
|
|
|
55
55
|
const data = {
|
|
56
|
+
locale: labs.isSet('i18n') ? (settingsCache.get('locale') || 'en') : undefined,
|
|
56
57
|
'ghost-comments': urlUtils.getSiteUrl(),
|
|
57
58
|
api: urlUtils.urlFor('api', {type: 'content'}, true),
|
|
58
59
|
admin: urlUtils.urlFor('admin', true),
|
|
59
60
|
key: frontendKey,
|
|
60
|
-
styles: stylesUrl,
|
|
61
61
|
title: title,
|
|
62
62
|
count: count,
|
|
63
63
|
'post-id': this.id,
|
|
@@ -35,30 +35,30 @@
|
|
|
35
35
|
align-items: flex-start;
|
|
36
36
|
justify-content: center;
|
|
37
37
|
height: 100%;
|
|
38
|
-
padding: 6.4vmax 4vmax;
|
|
38
|
+
padding: min(6.4vmax, 120px) min(4vmax, 80px);
|
|
39
39
|
background-size: cover;
|
|
40
40
|
background-position: center;
|
|
41
41
|
text-align: left;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
.kg-width-wide .kg-header-card-text {
|
|
45
|
-
padding: 10vmax 6.4vmax;
|
|
45
|
+
padding: min(10vmax, 220px) min(6.4vmax, 140px);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
.kg-width-full .kg-header-card-text {
|
|
49
|
-
padding: 12vmax 0;
|
|
49
|
+
padding: min(12vmax, 260px) 0;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
.kg-layout-split .kg-header-card-text {
|
|
53
|
-
padding: 12vmax 4vmax;
|
|
53
|
+
padding: min(12vmax, 260px) min(4vmax, 80px);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
.kg-layout-split.kg-content-wide .kg-header-card-text {
|
|
57
|
-
padding: 10vmax 0 10vmax 4vmax;
|
|
57
|
+
padding: min(10vmax, 220px) 0 min(10vmax, 220px) min(4vmax, 80px);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
.kg-layout-split.kg-content-wide.kg-swapped .kg-header-card-text {
|
|
61
|
-
padding: 10vmax 4vmax 10vmax 0;
|
|
61
|
+
padding: min(10vmax, 220px) min(4vmax, 80px) min(10vmax, 220px) 0;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
.kg-swapped .kg-header-card-text {
|
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
/* Split layout image */
|
|
94
94
|
|
|
95
95
|
.kg-header-card-content .kg-header-card-image {
|
|
96
|
+
width: 100%;
|
|
96
97
|
/* this will force the image to follow the signup card height */
|
|
97
98
|
height: 0;
|
|
98
99
|
min-height: 100%;
|
|
@@ -160,7 +161,7 @@
|
|
|
160
161
|
}
|
|
161
162
|
|
|
162
163
|
.kg-header-card.kg-width-full h3.kg-header-card-subheading:not(.kg-layout-split h3.kg-header-card-subheading) {
|
|
163
|
-
max-width: 65vmax;
|
|
164
|
+
max-width: min(65vmax, 1200px);
|
|
164
165
|
font-size: clamp(1.05em, 2vw, 2.6rem);
|
|
165
166
|
}
|
|
166
167
|
|
|
@@ -227,12 +228,12 @@
|
|
|
227
228
|
}
|
|
228
229
|
|
|
229
230
|
.kg-width-wide .kg-header-card-text {
|
|
230
|
-
padding: 6.4vmax 4vmax;
|
|
231
|
+
padding: min(6.4vmax, 120px) min(4vmax, 80px);
|
|
231
232
|
}
|
|
232
233
|
|
|
233
234
|
.kg-layout-split.kg-content-wide .kg-header-card-text,
|
|
234
235
|
.kg-layout-split.kg-content-wide.kg-swapped .kg-header-card-text {
|
|
235
|
-
padding: 9.6vmax 0;
|
|
236
|
+
padding: min(9.6vmax, 180px) 0;
|
|
236
237
|
}
|
|
237
238
|
|
|
238
239
|
.kg-header-card.kg-width-full h3.kg-header-card-subheading:not(.kg-layout-split h3.kg-header-card-subheading) {
|
|
@@ -28,30 +28,30 @@
|
|
|
28
28
|
align-items: flex-start;
|
|
29
29
|
justify-content: center;
|
|
30
30
|
height: 100%;
|
|
31
|
-
padding: 4vmax;
|
|
31
|
+
padding: min(4vmax, 80px);
|
|
32
32
|
background-size: cover;
|
|
33
33
|
background-position: center;
|
|
34
34
|
text-align: left;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
.kg-width-wide .kg-signup-card-text {
|
|
38
|
-
padding: 6.4vmax;
|
|
38
|
+
padding: min(6.4vmax, 120px);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
.kg-width-full .kg-signup-card-text {
|
|
42
|
-
padding: 12vmax 0;
|
|
42
|
+
padding: min(12vmax, 260px) 0;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
.kg-layout-split .kg-signup-card-text {
|
|
46
|
-
padding: 12vmax 4vmax;
|
|
46
|
+
padding: min(12vmax, 260px) min(4vmax, 80px);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
.kg-layout-split.kg-content-wide .kg-signup-card-text {
|
|
50
|
-
padding: 10vmax 0 10vmax 4vmax;
|
|
50
|
+
padding: min(10vmax, 220px) 0 min(10vmax, 220px) min(4vmax, 80px);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
.kg-layout-split.kg-content-wide.kg-swapped .kg-signup-card-text {
|
|
54
|
-
padding: 10vmax 4vmax 10vmax 0;
|
|
54
|
+
padding: min(10vmax, 220px) min(4vmax, 80px) min(10vmax, 220px) 0;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
.kg-swapped .kg-signup-card-text {
|
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
/* Split layout image */
|
|
87
87
|
|
|
88
88
|
.kg-signup-card-content .kg-signup-card-image {
|
|
89
|
+
width: 100%;
|
|
89
90
|
/* this will force the image to follow the signup card height */
|
|
90
91
|
height: 0;
|
|
91
92
|
min-height: 100%;
|
|
@@ -153,7 +154,7 @@
|
|
|
153
154
|
}
|
|
154
155
|
|
|
155
156
|
.kg-signup-card.kg-width-full h3.kg-signup-card-subheading:not(.kg-layout-split h3.kg-signup-card-subheading) {
|
|
156
|
-
max-width: 65vmax;
|
|
157
|
+
max-width: min(65vmax, 1200px);
|
|
157
158
|
font-size: clamp(1.05em, 2vw, 2.6rem);
|
|
158
159
|
}
|
|
159
160
|
|
|
@@ -176,17 +177,17 @@
|
|
|
176
177
|
|
|
177
178
|
.kg-signup-card-heading + .kg-signup-card-form,
|
|
178
179
|
.kg-signup-card-subheading + .kg-signup-card-form {
|
|
179
|
-
margin: 2.4vmax 0 0;
|
|
180
|
+
margin: min(2.4vmax, 48px) 0 0;
|
|
180
181
|
}
|
|
181
182
|
|
|
182
183
|
.kg-width-wide .kg-signup-card-heading + .kg-signup-card-form,
|
|
183
184
|
.kg-width-wide .kg-signup-card-subheading + .kg-signup-card-form {
|
|
184
|
-
margin: 3.2vmax 0 0;
|
|
185
|
+
margin: min(3.2vmax, 64px) 0 0;
|
|
185
186
|
}
|
|
186
187
|
|
|
187
188
|
.kg-width-full .kg-signup-card-heading + .kg-signup-card-form,
|
|
188
189
|
.kg-width-full .kg-signup-card-subheading + .kg-signup-card-form {
|
|
189
|
-
margin: 4vmax 0 0;
|
|
190
|
+
margin: min(4vmax, 80px) 0 0;
|
|
190
191
|
}
|
|
191
192
|
|
|
192
193
|
.kg-signup-card-fields {
|
|
@@ -338,12 +339,12 @@
|
|
|
338
339
|
}
|
|
339
340
|
|
|
340
341
|
.kg-width-wide .kg-signup-card-text {
|
|
341
|
-
padding: 6.4vmax 4vmax;
|
|
342
|
+
padding: min(6.4vmax, 120px) min(4vmax, 80px);
|
|
342
343
|
}
|
|
343
344
|
|
|
344
345
|
.kg-layout-split.kg-content-wide .kg-signup-card-text,
|
|
345
346
|
.kg-layout-split.kg-content-wide.kg-swapped .kg-signup-card-text {
|
|
346
|
-
padding: 9.6vmax 0;
|
|
347
|
+
padding: min(9.6vmax, 180px) 0;
|
|
347
348
|
}
|
|
348
349
|
|
|
349
350
|
.kg-signup-card.kg-width-full h3.kg-signup-card-subheading:not(.kg-layout-split h3.kg-signup-card-subheading) {
|
|
@@ -60,7 +60,7 @@ function corsOptionsDelegate(req, callback) {
|
|
|
60
60
|
* @param {Express.Response} res
|
|
61
61
|
* @param {Function} next
|
|
62
62
|
*/
|
|
63
|
-
const handleCaching = (req, res, next)
|
|
63
|
+
const handleCaching = function handleCachingCors(req, res, next) {
|
|
64
64
|
const method = req.method && req.method.toUpperCase && req.method.toUpperCase();
|
|
65
65
|
if (method === 'OPTIONS') {
|
|
66
66
|
// @NOTE: try to add native support for dynamic 'vary' header value in 'cors' module
|
|
@@ -12,7 +12,7 @@ const FORMAT_PATH_REGEX = /^\/format\/([^./]+)\//;
|
|
|
12
12
|
|
|
13
13
|
const TRAILING_SLASH_REGEX = /\/+$/;
|
|
14
14
|
|
|
15
|
-
module.exports = function (req, res, next) {
|
|
15
|
+
module.exports = function handleImageSizes(req, res, next) {
|
|
16
16
|
// In admin we need to read images and calculate the average color (blocked by CORS otherwise)
|
|
17
17
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
18
18
|
|
|
@@ -26,7 +26,7 @@ function matchCacheKey(req, cache) {
|
|
|
26
26
|
return true;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function createPublicFileMiddleware(location, file, mime, maxAge) {
|
|
29
|
+
function createPublicFileMiddleware(location, file, mime, maxAge, options = {}) {
|
|
30
30
|
let cache;
|
|
31
31
|
// These files are provided by Ghost, and therefore live inside of the core folder
|
|
32
32
|
const staticFilePath = config.get('paths').publicFilePath;
|
|
@@ -45,7 +45,7 @@ function createPublicFileMiddleware(location, file, mime, maxAge) {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
// send image files directly and let express handle content-length, etag, etc
|
|
48
|
-
if (mime.match(/^image/)) {
|
|
48
|
+
if (mime.match(/^image/) || options.disableServerCache) {
|
|
49
49
|
return res.sendFile(filePath, (err) => {
|
|
50
50
|
if (err && err.status === 404) {
|
|
51
51
|
// ensure we're triggering basic asset 404 and not a templated 404
|
|
@@ -101,8 +101,8 @@ function createPublicFileMiddleware(location, file, mime, maxAge) {
|
|
|
101
101
|
|
|
102
102
|
// ### servePublicFile Middleware
|
|
103
103
|
// Handles requests to robots.txt and favicon.ico (and caches them)
|
|
104
|
-
function servePublicFile(location, file, type, maxAge) {
|
|
105
|
-
const publicFileMiddleware = createPublicFileMiddleware(location, file, type, maxAge);
|
|
104
|
+
function servePublicFile(location, file, type, maxAge, options = {}) {
|
|
105
|
+
const publicFileMiddleware = createPublicFileMiddleware(location, file, type, maxAge, options);
|
|
106
106
|
|
|
107
107
|
return function servePublicFileMiddleware(req, res, next) {
|
|
108
108
|
if (req.path === '/' + file) {
|
|
@@ -98,6 +98,9 @@ module.exports = function setupSiteApp(routerConfig) {
|
|
|
98
98
|
(req, res, next) => membersService.api.middleware.wellKnown(req, res, next)
|
|
99
99
|
);
|
|
100
100
|
|
|
101
|
+
// Recommendations well-known
|
|
102
|
+
siteApp.use(mw.servePublicFile('built', '.well-known/recommendations.json', 'application/json', config.get('caching:publicAssets:maxAge'), {disableServerCache: true}));
|
|
103
|
+
|
|
101
104
|
// setup middleware for internal apps
|
|
102
105
|
// @TODO: refactor this to be a proper app middleware hook for internal apps
|
|
103
106
|
config.get('apps:internal').forEach((appName) => {
|
|
@@ -129,7 +132,7 @@ module.exports = function setupSiteApp(routerConfig) {
|
|
|
129
132
|
siteApp.use(shared.middleware.prettyUrls);
|
|
130
133
|
|
|
131
134
|
// ### Caching
|
|
132
|
-
siteApp.use(function (req, res, next) {
|
|
135
|
+
siteApp.use(function frontendCaching(req, res, next) {
|
|
133
136
|
// Site frontend is cacheable UNLESS request made by a member or site is in private mode
|
|
134
137
|
if (req.member || res.isPrivateBlog) {
|
|
135
138
|
return shared.middleware.cacheControl('private')(req, res, next);
|
|
@@ -138,7 +141,7 @@ module.exports = function setupSiteApp(routerConfig) {
|
|
|
138
141
|
}
|
|
139
142
|
});
|
|
140
143
|
|
|
141
|
-
siteApp.use(function (req, res, next) {
|
|
144
|
+
siteApp.use(function memberPageViewMiddleware(req, res, next) {
|
|
142
145
|
if (req.member) {
|
|
143
146
|
// This event needs memberLastSeenAt to avoid doing un-necessary database queries when updating `last_seen_at`
|
|
144
147
|
DomainEvents.dispatch(MemberPageViewEvent.create({url: req.url, memberId: req.member.id, memberLastSeenAt: req.member.last_seen_at}, new Date()));
|
|
@@ -205,6 +205,10 @@ module.exports = {
|
|
|
205
205
|
return apiFramework.pipeline(require('./mail-events'), localUtils);
|
|
206
206
|
},
|
|
207
207
|
|
|
208
|
+
get recommendations() {
|
|
209
|
+
return apiFramework.pipeline(require('./recommendations'), localUtils);
|
|
210
|
+
},
|
|
211
|
+
|
|
208
212
|
/**
|
|
209
213
|
* Content API Controllers
|
|
210
214
|
*
|
|
@@ -255,5 +259,9 @@ module.exports = {
|
|
|
255
259
|
|
|
256
260
|
get feedbackMembers() {
|
|
257
261
|
return apiFramework.pipeline(require('./feedback-members'), localUtils, 'members');
|
|
262
|
+
},
|
|
263
|
+
|
|
264
|
+
get recommendationsPublic() {
|
|
265
|
+
return apiFramework.pipeline(require('./recommendations-public'), localUtils, 'content');
|
|
258
266
|
}
|
|
259
267
|
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const recommendations = require('../../services/recommendations');
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
docName: 'recommendations',
|
|
5
|
+
|
|
6
|
+
browse: {
|
|
7
|
+
headers: {
|
|
8
|
+
cacheInvalidate: false
|
|
9
|
+
},
|
|
10
|
+
options: [
|
|
11
|
+
'limit',
|
|
12
|
+
'fields',
|
|
13
|
+
'filter',
|
|
14
|
+
'order',
|
|
15
|
+
'debug',
|
|
16
|
+
'page'
|
|
17
|
+
],
|
|
18
|
+
permissions: true,
|
|
19
|
+
validation: {},
|
|
20
|
+
async query() {
|
|
21
|
+
return await recommendations.controller.listRecommendations();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const recommendations = require('../../services/recommendations');
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
docName: 'recommendations',
|
|
5
|
+
|
|
6
|
+
browse: {
|
|
7
|
+
headers: {
|
|
8
|
+
cacheInvalidate: false
|
|
9
|
+
},
|
|
10
|
+
options: [],
|
|
11
|
+
permissions: true,
|
|
12
|
+
validation: {},
|
|
13
|
+
async query() {
|
|
14
|
+
return await recommendations.controller.listRecommendations();
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
add: {
|
|
19
|
+
statusCode: 201,
|
|
20
|
+
headers: {
|
|
21
|
+
cacheInvalidate: true
|
|
22
|
+
},
|
|
23
|
+
options: [],
|
|
24
|
+
validation: {},
|
|
25
|
+
permissions: true,
|
|
26
|
+
async query(frame) {
|
|
27
|
+
return await recommendations.controller.addRecommendation(frame);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
edit: {
|
|
32
|
+
headers: {
|
|
33
|
+
cacheInvalidate: true
|
|
34
|
+
},
|
|
35
|
+
options: [
|
|
36
|
+
'id'
|
|
37
|
+
],
|
|
38
|
+
validation: {
|
|
39
|
+
options: {
|
|
40
|
+
id: {
|
|
41
|
+
required: true
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
permissions: true,
|
|
46
|
+
async query(frame) {
|
|
47
|
+
return await recommendations.controller.editRecommendation(frame);
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
destroy: {
|
|
52
|
+
statusCode: 204,
|
|
53
|
+
headers: {
|
|
54
|
+
cacheInvalidate: true
|
|
55
|
+
},
|
|
56
|
+
options: [
|
|
57
|
+
'id'
|
|
58
|
+
],
|
|
59
|
+
validation: {
|
|
60
|
+
options: {
|
|
61
|
+
id: {
|
|
62
|
+
required: true
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
permissions: true,
|
|
67
|
+
query(frame) {
|
|
68
|
+
return recommendations.controller.deleteRecommendation(frame);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
@@ -50,7 +50,8 @@ const BACKUP_TABLES = [
|
|
|
50
50
|
'email_spam_complaint_events',
|
|
51
51
|
'milestones',
|
|
52
52
|
'collections',
|
|
53
|
-
'collections_posts'
|
|
53
|
+
'collections_posts',
|
|
54
|
+
'recommendations'
|
|
54
55
|
];
|
|
55
56
|
|
|
56
57
|
// NOTE: exposing only tables which are going to be included in a "default" export file
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const {combineTransactionalMigrations, addPermissionWithRoles} = require('../../utils');
|
|
2
|
+
|
|
3
|
+
module.exports = combineTransactionalMigrations(
|
|
4
|
+
addPermissionWithRoles({
|
|
5
|
+
name: 'Browse recommendations',
|
|
6
|
+
action: 'browse',
|
|
7
|
+
object: 'recommendation'
|
|
8
|
+
}, [
|
|
9
|
+
'Administrator',
|
|
10
|
+
'Admin Integration',
|
|
11
|
+
'Editor',
|
|
12
|
+
'Author',
|
|
13
|
+
'Contributor'
|
|
14
|
+
]),
|
|
15
|
+
addPermissionWithRoles({
|
|
16
|
+
name: 'Read recommendations',
|
|
17
|
+
action: 'read',
|
|
18
|
+
object: 'recommendation'
|
|
19
|
+
}, [
|
|
20
|
+
'Administrator',
|
|
21
|
+
'Admin Integration',
|
|
22
|
+
'Editor',
|
|
23
|
+
'Author',
|
|
24
|
+
'Contributor'
|
|
25
|
+
]),
|
|
26
|
+
addPermissionWithRoles({
|
|
27
|
+
name: 'Edit recommendations',
|
|
28
|
+
action: 'edit',
|
|
29
|
+
object: 'recommendation'
|
|
30
|
+
}, [
|
|
31
|
+
'Administrator',
|
|
32
|
+
'Admin Integration'
|
|
33
|
+
]),
|
|
34
|
+
addPermissionWithRoles({
|
|
35
|
+
name: 'Add recommendations',
|
|
36
|
+
action: 'add',
|
|
37
|
+
object: 'recommendation'
|
|
38
|
+
}, [
|
|
39
|
+
'Administrator',
|
|
40
|
+
'Admin Integration'
|
|
41
|
+
]),
|
|
42
|
+
addPermissionWithRoles({
|
|
43
|
+
name: 'Delete recommendations',
|
|
44
|
+
action: 'destroy',
|
|
45
|
+
object: 'recommendation'
|
|
46
|
+
}, [
|
|
47
|
+
'Administrator',
|
|
48
|
+
'Admin Integration'
|
|
49
|
+
])
|
|
50
|
+
);
|
package/core/server/data/migrations/versions/5.61/2023-08-29-11-39-10-add-recommendations-table.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const {addTable} = require('../../utils');
|
|
2
|
+
|
|
3
|
+
module.exports = addTable('recommendations', {
|
|
4
|
+
id: {type: 'string', maxlength: 24, nullable: false, primary: true},
|
|
5
|
+
|
|
6
|
+
url: {type: 'string', maxlength: 2000, nullable: false},
|
|
7
|
+
title: {type: 'string', maxlength: 2000, nullable: false},
|
|
8
|
+
|
|
9
|
+
excerpt: {type: 'string', maxlength: 2000, nullable: true},
|
|
10
|
+
featured_image: {type: 'string', maxlength: 2000, nullable: true},
|
|
11
|
+
favicon: {type: 'string', maxlength: 2000, nullable: true},
|
|
12
|
+
|
|
13
|
+
reason: {type: 'string', maxlength: 2000, nullable: true},
|
|
14
|
+
one_click_subscribe: {type: 'boolean', nullable: false, defaultTo: false},
|
|
15
|
+
|
|
16
|
+
created_at: {type: 'dateTime', nullable: false},
|
|
17
|
+
updated_at: {type: 'dateTime', nullable: true}
|
|
18
|
+
});
|
|
@@ -565,5 +565,15 @@
|
|
|
565
565
|
},
|
|
566
566
|
"type": "number"
|
|
567
567
|
}
|
|
568
|
+
},
|
|
569
|
+
"recommendations": {
|
|
570
|
+
"recommendations_enabled": {
|
|
571
|
+
"defaultValue": "false",
|
|
572
|
+
"validations": {
|
|
573
|
+
"isEmpty": false,
|
|
574
|
+
"isIn": [["true", "false"]]
|
|
575
|
+
},
|
|
576
|
+
"type": "boolean"
|
|
577
|
+
}
|
|
568
578
|
}
|
|
569
579
|
}
|
|
@@ -686,6 +686,31 @@
|
|
|
686
686
|
"name": "Delete collections",
|
|
687
687
|
"action_type": "destroy",
|
|
688
688
|
"object_type": "collection"
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
"name": "Browse recommendations",
|
|
692
|
+
"action_type": "browse",
|
|
693
|
+
"object_type": "recommendation"
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
"name": "Read recommendations",
|
|
697
|
+
"action_type": "read",
|
|
698
|
+
"object_type": "recommendation"
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
"name": "Edit recommendations",
|
|
702
|
+
"action_type": "edit",
|
|
703
|
+
"object_type": "recommendation"
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
"name": "Add recommendations",
|
|
707
|
+
"action_type": "add",
|
|
708
|
+
"object_type": "recommendation"
|
|
709
|
+
},
|
|
710
|
+
{
|
|
711
|
+
"name": "Delete recommendations",
|
|
712
|
+
"action_type": "destroy",
|
|
713
|
+
"object_type": "recommendation"
|
|
689
714
|
}
|
|
690
715
|
]
|
|
691
716
|
},
|
|
@@ -831,7 +856,8 @@
|
|
|
831
856
|
"comment": "all",
|
|
832
857
|
"link": "all",
|
|
833
858
|
"mention": "browse",
|
|
834
|
-
"collection": "all"
|
|
859
|
+
"collection": "all",
|
|
860
|
+
"recommendation": "all"
|
|
835
861
|
},
|
|
836
862
|
"DB Backup Integration": {
|
|
837
863
|
"db": "all"
|
|
@@ -873,7 +899,8 @@
|
|
|
873
899
|
"comment": "all",
|
|
874
900
|
"link": "all",
|
|
875
901
|
"mention": "browse",
|
|
876
|
-
"collection": "all"
|
|
902
|
+
"collection": "all",
|
|
903
|
+
"recommendation": "all"
|
|
877
904
|
},
|
|
878
905
|
"Editor": {
|
|
879
906
|
"notification": "all",
|
|
@@ -891,7 +918,8 @@
|
|
|
891
918
|
"label": ["browse", "read"],
|
|
892
919
|
"product": ["browse", "read"],
|
|
893
920
|
"newsletter": ["browse", "read"],
|
|
894
|
-
"collection": "all"
|
|
921
|
+
"collection": "all",
|
|
922
|
+
"recommendation": ["browse", "read"]
|
|
895
923
|
},
|
|
896
924
|
"Author": {
|
|
897
925
|
"post": ["browse", "read", "add"],
|
|
@@ -907,7 +935,8 @@
|
|
|
907
935
|
"label": ["browse", "read"],
|
|
908
936
|
"product": ["browse", "read"],
|
|
909
937
|
"newsletter": ["browse", "read"],
|
|
910
|
-
"collection": ["browse", "read", "add"]
|
|
938
|
+
"collection": ["browse", "read", "add"],
|
|
939
|
+
"recommendation": ["browse", "read"]
|
|
911
940
|
},
|
|
912
941
|
"Contributor": {
|
|
913
942
|
"post": ["browse", "read", "add"],
|
|
@@ -920,7 +949,8 @@
|
|
|
920
949
|
"email_preview": "read",
|
|
921
950
|
"email": "read",
|
|
922
951
|
"snippet": ["browse", "read"],
|
|
923
|
-
"collection": ["browse", "read"]
|
|
952
|
+
"collection": ["browse", "read"],
|
|
953
|
+
"recommendation": ["browse", "read"]
|
|
924
954
|
}
|
|
925
955
|
}
|
|
926
956
|
},
|
|
@@ -1067,5 +1067,17 @@ module.exports = {
|
|
|
1067
1067
|
collection_id: {type: 'string', maxlength: 24, nullable: false, references: 'collections.id', cascadeDelete: true},
|
|
1068
1068
|
post_id: {type: 'string', maxlength: 24, nullable: false, references: 'posts.id', cascadeDelete: true},
|
|
1069
1069
|
sort_order: {type: 'integer', nullable: false, unsigned: true, defaultTo: 0}
|
|
1070
|
+
},
|
|
1071
|
+
recommendations: {
|
|
1072
|
+
id: {type: 'string', maxlength: 24, nullable: false, primary: true},
|
|
1073
|
+
url: {type: 'string', maxlength: 2000, nullable: false},
|
|
1074
|
+
title: {type: 'string', maxlength: 2000, nullable: false},
|
|
1075
|
+
excerpt: {type: 'string', maxlength: 2000, nullable: true},
|
|
1076
|
+
featured_image: {type: 'string', maxlength: 2000, nullable: true},
|
|
1077
|
+
favicon: {type: 'string', maxlength: 2000, nullable: true},
|
|
1078
|
+
reason: {type: 'string', maxlength: 2000, nullable: true},
|
|
1079
|
+
one_click_subscribe: {type: 'boolean', nullable: false, defaultTo: false},
|
|
1080
|
+
created_at: {type: 'dateTime', nullable: false},
|
|
1081
|
+
updated_at: {type: 'dateTime', nullable: true}
|
|
1070
1082
|
}
|
|
1071
1083
|
};
|
|
@@ -80,7 +80,7 @@ ghostBookshelf.plugin('bookshelf-relations', {
|
|
|
80
80
|
};
|
|
81
81
|
|
|
82
82
|
// CASE: disable after hook for specific relations
|
|
83
|
-
if (['permissions_roles', 'members_newsletters'
|
|
83
|
+
if (['permissions_roles', 'members_newsletters'].indexOf(existing.relatedData.joinTableName) !== -1) {
|
|
84
84
|
return Promise.resolve();
|
|
85
85
|
}
|
|
86
86
|
|