ghost 5.6.0 → 5.8.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-custom-theme-settings-service-0.0.0.tgz +0 -0
- package/components/tryghost-email-analytics-service-0.0.0.tgz +0 -0
- package/components/tryghost-html-to-plaintext-0.0.0.tgz +0 -0
- package/components/tryghost-job-manager-0.0.0.tgz +0 -0
- package/components/tryghost-magic-link-0.0.0.tgz +0 -0
- package/components/tryghost-members-api-0.0.0.tgz +0 -0
- package/components/tryghost-members-offers-0.0.0.tgz +0 -0
- package/components/tryghost-members-ssr-0.0.0.tgz +0 -0
- package/components/tryghost-members-stripe-service-0.0.0.tgz +0 -0
- package/components/tryghost-minifier-0.0.0.tgz +0 -0
- package/components/tryghost-security-0.0.0.tgz +0 -0
- 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 +21 -0
- package/content/themes/casper/package.json +1 -1
- package/core/built/admin/assets/chunk.143.85b848fc430f289d64b8.js +41 -0
- package/core/built/admin/assets/chunk.174.eec7f6398cef4c3e2485.js +239 -0
- package/core/built/admin/assets/chunk.178.11b2d387c027bafd815d.js +11 -0
- package/core/built/admin/assets/chunk.351.cbc224ca65c14ef5322d.js +9272 -0
- package/core/built/admin/assets/chunk.351.cbc224ca65c14ef5322d.js.LICENSE.txt +138 -0
- package/core/built/{assets/codemirror/codemirror-30201ab2cff61db847193fc9f5ed922d.js → admin/assets/codemirror/codemirror-1b460af155bb0ecaab9591678ac8c942.js} +1 -1
- package/core/built/{assets → admin/assets}/fonts/Inter.ttf +0 -0
- package/core/built/{assets/ghost.min-b0576e0e36343533e70992f3e5bb02bb.css → admin/assets/ghost-365d87dc3d1d5ee26cba6d952dc52d5b.css} +1 -1
- package/core/built/{assets/ghost.min-31bd482d1bcfe706448bc6f401481a28.js → admin/assets/ghost-50d38cd0f3736f23fc59ca91bb176d54.js} +368 -340
- package/core/built/admin/assets/ghost-dark-92b1e3544fb91e071fe3db40f0acae31.css +1 -0
- package/core/built/{assets → admin/assets}/icons/account-group.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/activity-placeholder.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/add-stroke.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/add-view.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/add.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/align-center.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/align-left.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/ambulance.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/analytics.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/arrow-down-small.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/arrow-down-stroke.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/arrow-down.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/arrow-left-small.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/arrow-left-stroke.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/arrow-left-tail.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/arrow-left.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/arrow-right-small.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/arrow-right-stroke.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/arrow-right-tail.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/arrow-right.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/arrow-up-small.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/arrow-up-stroke.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/arrow-up.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/arrow2-down.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/arrow2-right.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/audio-file.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/audio-upload.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/book-open.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/bookmark-article.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/box-hands.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/box.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/boxes.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/brackets.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/button.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/calendar.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/cash.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/chat-double-bubble.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/check-2.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/check-circle-stroke.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/check-circle.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/check.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/cheeseburger.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/circle-ellipsis.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/clock.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/clockface.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/close-stroke.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/close.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/cloud.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/compass-2.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/compass.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/computer.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/confetti.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/content-bold.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/content.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/copy.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/credit-card.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/cross-circle.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/cycle.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/default-favicon.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/desert.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/desktop.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/diamond.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/discount-bubble.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/dividers.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/dotdotdot.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/download-circle.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/download.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/eco-globe.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/eco-lightbulb.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/edit-view.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/ellipsis.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/email-at.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/email-body.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/email-footer.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/email-header.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/email-love-letter.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/email-member.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/email-name.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/email-send.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/email-stroke.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/email-unread.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/email.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/event-canceled-subscription.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/event-comment.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/event-email-delivery-failed.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/event-logged-in.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/event-made-a-payment.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/event-opened-email.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/event-received-email.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/event-signed-up.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/event-subscribed-to-email.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/event-subscriptions.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/event-unsubscribed-from-email.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/expand.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/external.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/eye.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/facebook-heart.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/facebook-like.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/facebook.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/feature-image.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/file-download.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/file-tabular-data.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/file-text-document.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/file-upload.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/film-camera.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/filter.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/firstpromoter-ce8b5219e5b5ebda463bd60396c6ab81.png +0 -0
- package/core/built/{assets → admin/assets}/icons/folder.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/gallery-placeholder.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/get-started-import.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/get-started-members.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/get-started-migrations.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/get-started.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/ghost-logo-orb.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/ghost-logo.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/ghost-orb.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/ghost-squircle.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/gift.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/github-outline.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/github-star.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/github.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/globe.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/google-favicon.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/google-search.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/google.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/grab.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/graph-line.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/heart-beat.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/heart-circle.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/heart.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/help.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/hotspot.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/house-bold.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/house.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/icon.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/id-card.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/idea.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/info.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/instagram.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/integration.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/labs.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/laptop.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/line.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/link.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/list-bullet.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/list-number.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/lock.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/lock2.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/loop-infinite.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/lotus.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/markdown.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/member-add.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/member.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/members-all.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/members-bold.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/members-outline.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/members-paid.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/members-placeholder.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/members-post.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/members-segment.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/members.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/mobile-phone-heart.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/mobile-phone.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/module.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/modules.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/monitor-labs.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/moon.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/mountains.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/mute.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/navigation.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/network.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/news-article.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/nightshift.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/no-data-line-chart.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/no-data-list.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/no-data-subscription.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/no-email.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/no-members.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/offer.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/page-bold.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/page.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/pages-placeholder.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/paint-palette.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/paintbrush.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/pause.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/pen.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/pencil-circle.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/pencil.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/percentage.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/photos-people.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/photos.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/piggy-bank.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/pin.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/plane.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/play.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/plus.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/portal-icon-1.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/portal-icon-2.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/portal-icon-3.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/portal-icon-4.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/portal-icon-5.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/portal-logo-stroke.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/portal-logo.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/post.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/posts-placeholder.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/posts.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/powered-by-stripe.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/powered-by-tenor.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/presentation-code.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/published-post.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/recycle.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/reload.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/repo.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/retry.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/satellite.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/search.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/send-email.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/server.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/settings.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/shield-lock.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/shield.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/sidemenu-open.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/sidemenu.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/signal-tower.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/signout.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/smiley.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/social-facebook.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/social-share.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/social-twitter.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/spinner.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/staff.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/star-filled.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/store.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/stripe-verified-partner-badge.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/summer.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/sun.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/support.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/sync.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/tag.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/tags-placeholder.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/tenor.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/terminal.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/text-vector.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/text.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/theme.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/ticket.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/trash.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/trophy.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/tumbleweed.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/twitter-comment.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/twitter-like.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/twitter-link.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/twitter-logo.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/twitter-retweet.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/twitter-share.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/twitter.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/ufo-attack.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/unmute.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/unsplash-heart.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/unsplash.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/unsubscribed.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/upload-fill.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/upload.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/user-circle.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/user-group.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/user-group2.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/v-ellipsis.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/view-site.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/warning-stroke.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/warning.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/window-app.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/window-pulse.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/wrench-double.svg +0 -0
- package/core/built/{assets → admin/assets}/icons/zap.svg +0 -0
- package/core/built/{assets → admin/assets}/img/404-ghost-e112dbfadde79cf30dbca8e8cfe7a21a.png +0 -0
- package/core/built/{assets → admin/assets}/img/404-ghost@2x-34c1119ed15cc3ea71e4406f80c8e810.png +0 -0
- package/core/built/{assets → admin/assets}/img/abstract-2-2937e2902b64360d0cbe4cec8bd8479b.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/abstract-c52b2f4208e7fd2e7b8abd8b1eec4f7b.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/amp.svg +0 -0
- package/core/built/{assets → admin/assets}/img/apple-touch-icon-74680e326a7e87b159d366c7d4fb3d4b.png +0 -0
- package/core/built/{assets → admin/assets}/img/buffer-db31f6b5dc27a298050e16312619c586.png +0 -0
- package/core/built/{assets → admin/assets}/img/community-background-3f501ff1d764d0cb81f7c2cbacfc6503.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/community-be8c1dcecfb157f2bfba5cababc8e686.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/dashboard/bp1-03a13253453b372d0bbd5e6a19b20fca.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/dashboard/bp2-ed14f9f48c56d5d6fe997dc637a8b1ad.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/dashboard/join-community-bb5478f7dca6c04a2d0baf2b02f880fb.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/dashboard-feature-image-8949197550decb94a8f1dea57ad47819.jpeg +0 -0
- package/core/built/{assets → admin/assets}/img/disqus.svg +0 -0
- package/core/built/{assets → admin/assets}/img/favicon.ico +0 -0
- package/core/built/{assets → admin/assets}/img/firstpromoter-ce8b5219e5b5ebda463bd60396c6ab81.png +0 -0
- package/core/built/{assets → admin/assets}/img/footer-marketplace-bg-572b6c6486a7e26316954d599eaa9f30.png +0 -0
- package/core/built/{assets → admin/assets}/img/get-started-995c36b9ede90bb3777c83751e798ef7.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/github.svg +0 -0
- package/core/built/{assets → admin/assets}/img/google-analytics-e05fc1327377939663407200d4978eba.png +0 -0
- package/core/built/{assets → admin/assets}/img/google-docs.svg +0 -0
- package/core/built/{assets → admin/assets}/img/install-welcome-ff3912d18bf8949df89c83b1c3b8bb66.png +0 -0
- package/core/built/{assets → admin/assets}/img/invite-placeholder-4b3731d47c6c8f6cb3aaa6bc4d870c9f.png +0 -0
- package/core/built/{assets → admin/assets}/img/large-ac90af7c93a4b47e8d956fa9fef31d9d.png +0 -0
- package/core/built/{assets → admin/assets}/img/launch-wizard-bg-13b995b1f02bce34b269db3190897384.png +0 -0
- package/core/built/{assets → admin/assets}/img/loadingcat-5f501b7a8c7bd54b253463e261c99634.gif +0 -0
- package/core/built/{assets → admin/assets}/img/logos/ghost-logo-black-1-fb561a374422b405ec90fa586b05ebdf.png +0 -0
- package/core/built/{assets → admin/assets}/img/logos/orb-black-1-32b72766be2164fdea6ab2565fb1c137.png +0 -0
- package/core/built/{assets → admin/assets}/img/logos/orb-black-2-4b0baef1ec34816af6f3fbede7ab191d.png +0 -0
- package/core/built/{assets → admin/assets}/img/logos/orb-black-3-9780c5e9991b69ed2303b526aa3e3252.png +0 -0
- package/core/built/{assets → admin/assets}/img/logos/orb-black-4-d9c3caacb8d2ba98a52517ff2971433c.png +0 -0
- package/core/built/{assets → admin/assets}/img/logos/orb-black-5-063a200f749e09c587b9443ffd2c4cfa.png +0 -0
- package/core/built/{assets → admin/assets}/img/mailchimp.svg +0 -0
- package/core/built/{assets → admin/assets}/img/marketing/members-1-8b89a1f48fe7b336754e91a429531f65.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/marketing/members-2-791205c82d5cf221f8c99a74f9ee1739.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/marketing/offers-1-f2e1b653c4d5bb90eea9d7a2862530f9.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/marketing/offers-2-28a225d34cc39d133748431536961d00.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/marketing/offers-3-2094c91ab21a16c37fbe6ec16c140160.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/medium-fef07013cffd5c45a655a250912a0ad7.png +0 -0
- package/core/built/{assets → admin/assets}/img/more-fe5480ab76c7be7aec28bcfe844f41c1.png +0 -0
- package/core/built/{assets → admin/assets}/img/newsletter-1-197ae8063dfb2e22278d355198029c9e.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/newsletter-2-5a2c7693ea9380d4282061302c01267a.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/orb-squircle-645fd62e92a80557905c0cb60874b699.png +0 -0
- package/core/built/{assets → admin/assets}/img/patreon.svg +0 -0
- package/core/built/{assets → admin/assets}/img/paypal.svg +0 -0
- package/core/built/{assets → admin/assets}/img/plausible-1b754a95e19a6d935e0bc8bf6790ba56.png +0 -0
- package/core/built/{assets → admin/assets}/img/resource-1-722f202795856e4a5596c8a3b7bedc43.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/slackicon-406aadea8994ca2ddee9c1d7157208db.png +0 -0
- package/core/built/{assets → admin/assets}/img/small-b90396925485f17b2ca82c31be42de5f.png +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Alto-a5172a42994782321d8c9f268928d987.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Alto-cut-c667d9d6457c5e981aa7bdc8946b215a.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Alto-f4db5af43ca9771c7ac1f754de3ddf2f.png +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Bulletin-57d45b992ff0e26e0acdce7ed4cccd67.png +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Casper-19b7267aac5acc6abfaaed7e41eddae8.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Dawn-be81aa8c8caae8fcfb5d5fbec823fdcc.png +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Digest-d3467ac22a290e1ad3a543014758286e.png +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Dope-6f8e0bbc199ce4af9a60859e9e6a74ad.png +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Ease-7cfb8f06f9b66b1aa04b92493a471fef.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Ease-9c279ea6cec3c0f1823f81c9dd24b116.png +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Ease-cut-78d5aa00682bee6a4cf22155f09e49e8.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Edge-0258906309e11fd075a1d9880aa09b20.png +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Edition-b94372eb5c88fce0f4befba39148ff28.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Edition-cut-e6545bab2768aafa1996100774f310ff.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Edition-d8f508e93bc24bdf2716ae6f8b3d44f8.png +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Headline-c5070cf549e797a6a72b87237caa1617.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Journal-accf0031bbae0919900a049061e65a04.png +0 -0
- package/core/built/{assets → admin/assets}/img/themes/London-3f07efcee9e5bfb9a33827064eb77e70.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/themes/London-cut-599cba221f81a15ad37fe395cf4e572c.jpg +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Ruby-11a53c62015612f4b3aca8f503121225.png +0 -0
- package/core/built/{assets → admin/assets}/img/themes/Wave-86e8044c2d76cb57a9030e4c24ac9520.png +0 -0
- package/core/built/{assets → admin/assets}/img/touch-icon-ipad-2e78629d62ad05746f980f14623dfadb.png +0 -0
- package/core/built/{assets → admin/assets}/img/touch-icon-iphone-93ed4382d391be9180093fd77ce8f410.png +0 -0
- package/core/built/{assets → admin/assets}/img/twitter.svg +0 -0
- package/core/built/{assets → admin/assets}/img/typeform.svg +0 -0
- package/core/built/{assets → admin/assets}/img/ulysses-3c66b59fb45c285bf336b4b613dc86e4.png +0 -0
- package/core/built/{assets → admin/assets}/img/unsplash-404-71ab3705c9920a9706bb822c3d7e34d1.png +0 -0
- package/core/built/{assets → admin/assets}/img/user-cover-e8f42b12b5fcba292a8b5dfa81e13dd2.png +0 -0
- package/core/built/{assets → admin/assets}/img/user-image-639a88b784fb5f10964be8b975ca9fdf.png +0 -0
- package/core/built/{assets → admin/assets}/img/users-33427addfe0f11c78b42cccaf83be073.png +0 -0
- package/core/built/{assets → admin/assets}/img/whats-new-header-bg.svg +0 -0
- package/core/built/{assets → admin/assets}/img/zapier-logo.svg +0 -0
- package/core/built/{assets → admin/assets}/img/zapier.svg +0 -0
- package/core/built/{assets → admin/assets}/img/zero-bounce-ee799eddb1f88e33ab8c462858cbfed9.png +0 -0
- package/core/built/{assets/simplemde/simplemde-fb4527da6e489b34dc24b28ea870b286.js → admin/assets/simplemde/simplemde-0cd04dbb388ed0cf571a6808464ea57e.js} +1 -1
- package/core/built/admin/assets/vendor-46baf13852f545c6c89756c8e0ccbff2.js +13821 -0
- package/core/built/{assets/vendor.min-4a6661c574707ceca220aa2e76558995.css → admin/assets/vendor-bc9d2c9e5c8a33f0c92e81189d48e04c.css} +17 -9
- package/core/{server/web/admin/views/default.html → built/admin/index.html} +13 -15
- package/core/frontend/helpers/comment_count.js +15 -9
- package/core/frontend/helpers/img_url.js +67 -6
- package/core/frontend/helpers/title.js +1 -1
- package/core/frontend/public/ghost.min.css +1 -1
- package/core/frontend/services/admin-auth-assets/service.js +19 -3
- package/core/frontend/src/admin-auth/message-handler.js +7 -3
- package/core/frontend/src/comment-counts/js/comment-counts.js +17 -2
- package/core/frontend/web/middleware/handle-image-sizes.js +7 -11
- package/core/server/adapters/cache/Base.js +12 -0
- package/core/server/adapters/cache/Memory.js +36 -0
- package/core/server/adapters/cache/index.js +17 -0
- package/core/server/api/endpoints/comments-members.js +2 -19
- package/core/server/api/endpoints/integrations.js +12 -8
- package/core/server/api/endpoints/utils/serializers/input/tiers.js +5 -0
- package/core/server/api/endpoints/utils/serializers/output/mappers/comments.js +1 -1
- package/core/server/api/endpoints/utils/serializers/output/tiers.js +5 -0
- package/core/server/api/endpoints/utils/serializers/output/utils/post-gating.js +1 -1
- package/core/server/data/migrations/versions/4.0/23-regenerate-posts-html.js +1 -1
- package/core/server/data/migrations/versions/4.9/05-fix-missed-mobiledoc-url-transforms.js +1 -1
- package/core/server/data/migrations/versions/5.0/2022-05-21-00-00-regenerate-posts-html.js +1 -1
- package/core/server/data/migrations/versions/5.8/2022-08-02-06-09-add-trial-period-days-column-to-tiers.js +8 -0
- package/core/server/data/migrations/versions/5.8/2022-08-03-15-28-add-trial-start-column-to-stripe-subscriptions.js +6 -0
- package/core/server/data/migrations/versions/5.8/2022-08-03-15-29-add-trial-end-column-to-stripe-subscriptions.js +6 -0
- package/core/server/data/schema/schema.js +3 -0
- package/core/server/ghost-server.js +7 -0
- package/core/server/models/base/index.js +1 -1
- package/core/server/models/base/plugins/filtered-collection.js +3 -3
- package/core/server/models/comment.js +39 -14
- package/core/server/models/post.js +1 -1
- package/core/server/models/product.js +2 -1
- package/core/server/models/tag.js +1 -1
- package/core/server/models/user.js +2 -2
- package/core/server/services/adapter-manager/index.js +2 -1
- package/core/server/services/comments/controller.js +11 -1
- package/core/server/services/comments/email-templates/new-comment-reply.hbs +9 -11
- package/core/server/services/comments/email-templates/new-comment-reply.txt.js +1 -1
- package/core/server/services/comments/email-templates/new-comment.hbs +8 -10
- package/core/server/services/comments/email-templates/new-comment.txt.js +1 -1
- package/core/server/services/comments/email-templates/report.hbs +7 -9
- package/core/server/services/comments/email-templates/report.txt.js +1 -1
- package/core/server/services/comments/emails.js +4 -4
- package/core/server/services/comments/index.js +5 -1
- package/core/server/services/comments/stats.js +44 -0
- package/core/server/services/mega/mega.js +1 -1
- package/core/server/services/mega/post-email-serializer.js +3 -3
- package/core/server/services/members/middleware.js +1 -1
- package/core/server/services/members/utils.js +1 -0
- package/core/server/services/settings/settings-service.js +3 -1
- package/core/server/services/url/Resources.js +1 -1
- package/core/server/web/admin/app.js +2 -1
- package/core/server/web/admin/controller.js +1 -2
- package/core/shared/config/defaults.json +7 -4
- package/core/shared/config/overrides.json +1 -2
- package/core/shared/labs.js +4 -3
- package/core/shared/settings-cache/cache.js +124 -87
- package/core/shared/settings-cache/index.js +6 -9
- package/loggingrc.js +1 -1
- package/package.json +30 -33
- package/yarn.lock +13987 -3229
- package/core/built/assets/chunk.3.33097bb5eb150719bdd2.js +0 -197
- package/core/built/assets/ghost-dark-1bdd57aba1fa4a23388121740454dab2.css +0 -1
- package/core/built/assets/vendor.min-3dd40d3052381526f38fd290d13baa47.js +0 -22339
- package/core/server/web/admin/views/default-prod.html +0 -63
- package/core/shared/html-to-plaintext.js +0 -80
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const membersService = require('../../../../../../services/members');
|
|
2
|
-
const htmlToPlaintext = require('
|
|
2
|
+
const htmlToPlaintext = require('@tryghost/html-to-plaintext');
|
|
3
3
|
|
|
4
4
|
// @TODO: reconsider the location of this - it's part of members and adds a property to the API
|
|
5
5
|
const forPost = (attrs, frame) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
2
|
const {createIrreversibleMigration} = require('../../utils');
|
|
3
3
|
const mobiledocLib = require('../../../../lib/mobiledoc');
|
|
4
|
-
const htmlToPlaintext = require('
|
|
4
|
+
const htmlToPlaintext = require('@tryghost/html-to-plaintext');
|
|
5
5
|
|
|
6
6
|
module.exports = createIrreversibleMigration(async (knex) => {
|
|
7
7
|
logging.info('Starting re-generation of posts html.');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
2
|
const urlUtils = require('../../../../../shared/url-utils');
|
|
3
|
-
const htmlToPlaintext = require('
|
|
3
|
+
const htmlToPlaintext = require('@tryghost/html-to-plaintext');
|
|
4
4
|
const mobiledocLib = require('../../../../lib/mobiledoc');
|
|
5
5
|
const {createTransactionalMigration} = require('../../utils');
|
|
6
6
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
2
|
const {createIrreversibleMigration} = require('../../utils');
|
|
3
3
|
const mobiledocLib = require('../../../../lib/mobiledoc');
|
|
4
|
-
const htmlToPlaintext = require('
|
|
4
|
+
const htmlToPlaintext = require('@tryghost/html-to-plaintext');
|
|
5
5
|
|
|
6
6
|
module.exports = createIrreversibleMigration(async (knex) => {
|
|
7
7
|
logging.info(`Starting regeneration of posts HTML`);
|
|
@@ -422,6 +422,7 @@ module.exports = {
|
|
|
422
422
|
defaultTo: 'none',
|
|
423
423
|
validations: {isIn: [['public', 'none']]}
|
|
424
424
|
},
|
|
425
|
+
trial_days: {type: 'integer', unsigned: true, nullable: false, defaultTo: 0},
|
|
425
426
|
monthly_price_id: {type: 'string', maxlength: 24, nullable: true},
|
|
426
427
|
yearly_price_id: {type: 'string', maxlength: 24, nullable: true},
|
|
427
428
|
description: {type: 'string', maxlength: 191, nullable: true},
|
|
@@ -584,6 +585,8 @@ module.exports = {
|
|
|
584
585
|
updated_by: {type: 'string', maxlength: 24, nullable: true},
|
|
585
586
|
mrr: {type: 'integer', unsigned: true, nullable: false, defaultTo: 0},
|
|
586
587
|
offer_id: {type: 'string', maxlength: 24, nullable: true, unique: false, references: 'offers.id'},
|
|
588
|
+
trial_start_at: {type: 'dateTime', nullable: true},
|
|
589
|
+
trial_end_at: {type: 'dateTime', nullable: true},
|
|
587
590
|
/* Below fields are now redundant as we link prie_id to stripe_prices table */
|
|
588
591
|
plan_id: {type: 'string', maxlength: 255, nullable: false, unique: false},
|
|
589
592
|
plan_nickname: {type: 'string', maxlength: 50, nullable: false},
|
|
@@ -137,7 +137,14 @@ class GhostServer {
|
|
|
137
137
|
* Called on SIGINT or SIGTERM
|
|
138
138
|
*/
|
|
139
139
|
async shutdown(code = 0) {
|
|
140
|
+
// Prevent this function being run multiple times by checking whether we're
|
|
141
|
+
// already shutting down
|
|
142
|
+
if (this.isShuttingDown) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
140
146
|
try {
|
|
147
|
+
this.isShuttingDown = true;
|
|
141
148
|
logging.warn(tpl(messages.ghostIsShuttingDown));
|
|
142
149
|
await this.stop();
|
|
143
150
|
setTimeout(() => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// # Base Model
|
|
2
2
|
// This is the model from which all other Ghost models extend. The model is based on Bookshelf.Model, and provides
|
|
3
|
-
// several basic
|
|
3
|
+
// several basic behaviors such as UUIDs, as well as a set of Data methods for accessing information from the database.
|
|
4
4
|
//
|
|
5
5
|
// The models are internal to Ghost, only the API and some internal functions such as migration and import/export
|
|
6
6
|
// accesses the models directly.
|
|
@@ -6,13 +6,13 @@ module.exports = function (Bookshelf) {
|
|
|
6
6
|
getFilteredCollection: function getFilteredCollection(options) {
|
|
7
7
|
const filteredCollection = this.forge();
|
|
8
8
|
|
|
9
|
-
// Apply model-specific query
|
|
9
|
+
// Apply model-specific query behavior
|
|
10
10
|
filteredCollection.applyCustomQuery(options);
|
|
11
11
|
|
|
12
|
-
// Add Filter
|
|
12
|
+
// Add Filter behavior
|
|
13
13
|
filteredCollection.applyDefaultAndCustomFilters(options);
|
|
14
14
|
|
|
15
|
-
// Apply model-specific search
|
|
15
|
+
// Apply model-specific search behavior
|
|
16
16
|
filteredCollection.applySearchQuery(options);
|
|
17
17
|
|
|
18
18
|
return filteredCollection;
|
|
@@ -2,13 +2,29 @@ const ghostBookshelf = require('./base');
|
|
|
2
2
|
const _ = require('lodash');
|
|
3
3
|
const errors = require('@tryghost/errors');
|
|
4
4
|
const tpl = require('@tryghost/tpl');
|
|
5
|
+
const {ValidationError} = require('@tryghost/errors');
|
|
5
6
|
|
|
6
7
|
const messages = {
|
|
8
|
+
emptyComment: 'The body of a comment cannot be empty',
|
|
7
9
|
commentNotFound: 'Comment could not be found',
|
|
8
10
|
notYourCommentToEdit: 'You may only edit your own comments',
|
|
9
11
|
notYourCommentToDestroy: 'You may only delete your own comments'
|
|
10
12
|
};
|
|
11
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Remove empty paragraps from the start and end
|
|
16
|
+
* + remove duplicate empty paragrapsh (only one empty line allowed)
|
|
17
|
+
*/
|
|
18
|
+
function trimParagraphs(str) {
|
|
19
|
+
const paragraph = '<p></p>';
|
|
20
|
+
const escapedParagraph = '<p>\\s*?</p>';
|
|
21
|
+
|
|
22
|
+
const startReg = new RegExp('^(' + escapedParagraph + ')+');
|
|
23
|
+
const endReg = new RegExp('(' + escapedParagraph + ')+$');
|
|
24
|
+
const duplicates = new RegExp('(' + escapedParagraph + ')+');
|
|
25
|
+
return str.replace(startReg, '').replace(endReg, '').replace(duplicates, paragraph);
|
|
26
|
+
}
|
|
27
|
+
|
|
12
28
|
const Comment = ghostBookshelf.Model.extend({
|
|
13
29
|
tableName: 'comments',
|
|
14
30
|
|
|
@@ -49,20 +65,29 @@ const Comment = ghostBookshelf.Model.extend({
|
|
|
49
65
|
if (this.hasChanged('html')) {
|
|
50
66
|
const sanitizeHtml = require('sanitize-html');
|
|
51
67
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
68
|
+
const html = trimParagraphs(
|
|
69
|
+
sanitizeHtml(this.get('html'), {
|
|
70
|
+
allowedTags: ['p', 'br', 'a', 'blockquote'],
|
|
71
|
+
allowedAttributes: {
|
|
72
|
+
a: ['href', 'target', 'rel']
|
|
73
|
+
},
|
|
74
|
+
selfClosing: ['br'],
|
|
75
|
+
// Enforce _blank and safe URLs
|
|
76
|
+
transformTags: {
|
|
77
|
+
a: sanitizeHtml.simpleTransform('a', {
|
|
78
|
+
target: '_blank',
|
|
79
|
+
rel: 'ugc noopener noreferrer nofollow'
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
).trim();
|
|
84
|
+
|
|
85
|
+
if (html.length === 0) {
|
|
86
|
+
throw new ValidationError({
|
|
87
|
+
message: tpl(messages.emptyComment)
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
this.set('html', html);
|
|
66
91
|
}
|
|
67
92
|
},
|
|
68
93
|
|
|
@@ -7,7 +7,7 @@ const {sequence} = require('@tryghost/promise');
|
|
|
7
7
|
const tpl = require('@tryghost/tpl');
|
|
8
8
|
const errors = require('@tryghost/errors');
|
|
9
9
|
const nql = require('@tryghost/nql');
|
|
10
|
-
const htmlToPlaintext = require('
|
|
10
|
+
const htmlToPlaintext = require('@tryghost/html-to-plaintext');
|
|
11
11
|
const ghostBookshelf = require('./base');
|
|
12
12
|
const config = require('../../shared/config');
|
|
13
13
|
const settingsCache = require('../../shared/settings-cache');
|
|
@@ -103,7 +103,7 @@ Tag = ghostBookshelf.Model.extend({
|
|
|
103
103
|
// Support tag creation with `posts: [{..., tags: [{slug: 'new'}]}]`
|
|
104
104
|
// In that situation we have a slug but no name so validation will fail
|
|
105
105
|
// unless we set one automatically. Re-using slug for name matches our
|
|
106
|
-
// opposite name->slug
|
|
106
|
+
// opposite name->slug behavior.
|
|
107
107
|
if (!newTag.get('name') && newTag.get('slug')) {
|
|
108
108
|
this.set('name', newTag.get('slug'));
|
|
109
109
|
}
|
|
@@ -234,7 +234,7 @@ User = ghostBookshelf.Model.extend({
|
|
|
234
234
|
* - we do some pre-validation checks, because onValidate is called AFTER onSaving
|
|
235
235
|
* - when importing, we set the password to a random uid and don't validate, just hash it and lock the user
|
|
236
236
|
* - when importing with `importPersistUser` we check if the password is a bcrypt hash already and fall back to
|
|
237
|
-
* normal
|
|
237
|
+
* normal behavior if not (set random password, lock user, and hash password)
|
|
238
238
|
* - no validations should run, when importing
|
|
239
239
|
*/
|
|
240
240
|
if (self.hasChanged('password')) {
|
|
@@ -242,7 +242,7 @@ User = ghostBookshelf.Model.extend({
|
|
|
242
242
|
|
|
243
243
|
// CASE: import with `importPersistUser` should always be an bcrypt password already,
|
|
244
244
|
// and won't re-hash or overwrite it.
|
|
245
|
-
// In case the password is not bcrypt hashed we fall back to the standard
|
|
245
|
+
// In case the password is not bcrypt hashed we fall back to the standard behavior.
|
|
246
246
|
if (options.importPersistUser && this.get('password').match(/^\$2[ayb]\$.{56}$/i)) {
|
|
247
247
|
return;
|
|
248
248
|
}
|
|
@@ -15,11 +15,12 @@ const adapterManager = new AdapterManager({
|
|
|
15
15
|
adapterManager.registerAdapter('storage', require('ghost-storage-base'));
|
|
16
16
|
adapterManager.registerAdapter('scheduling', require('../../adapters/scheduling/SchedulingBase'));
|
|
17
17
|
adapterManager.registerAdapter('sso', require('../../adapters/sso/Base'));
|
|
18
|
+
adapterManager.registerAdapter('cache', require('../../adapters/cache/Base'));
|
|
18
19
|
|
|
19
20
|
module.exports = {
|
|
20
21
|
/**
|
|
21
22
|
*
|
|
22
|
-
* @param {String} name - one of 'storage', 'scheduling', 'sso' etc. Or can contain a "resource" extension like "storage:image"
|
|
23
|
+
* @param {String} name - one of 'storage', 'scheduling', 'sso', 'cache' etc. Or can contain a "resource" extension like "storage:image"
|
|
23
24
|
* @returns {Object} instance of an adapter
|
|
24
25
|
*/
|
|
25
26
|
getAdapter(name) {
|
|
@@ -12,9 +12,11 @@ const messages = {
|
|
|
12
12
|
module.exports = class CommentsController {
|
|
13
13
|
/**
|
|
14
14
|
* @param {import('./service')} service
|
|
15
|
+
* @param {import('./stats')} stats
|
|
15
16
|
*/
|
|
16
|
-
constructor(service) {
|
|
17
|
+
constructor(service, stats) {
|
|
17
18
|
this.service = service;
|
|
19
|
+
this.stats = stats;
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
/**
|
|
@@ -79,4 +81,12 @@ module.exports = class CommentsController {
|
|
|
79
81
|
message: tpl(messages.cannotDestroyComments)
|
|
80
82
|
});
|
|
81
83
|
}
|
|
84
|
+
|
|
85
|
+
async count(frame) {
|
|
86
|
+
if (!frame?.data?.ids) {
|
|
87
|
+
return await this.stats.getAllCounts();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return await this.stats.getCountsByPost(frame.data.ids);
|
|
91
|
+
}
|
|
82
92
|
};
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
<div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; max-width: 600px; padding: 30px 20px;">
|
|
107
107
|
|
|
108
108
|
<!-- START CENTERED CONTAINER -->
|
|
109
|
-
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">Someone
|
|
109
|
+
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">Someone just replied to your comment</span>
|
|
110
110
|
<table class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background: #ffffff; border-radius: 8px;">
|
|
111
111
|
|
|
112
112
|
<!-- START MAIN CONTENT AREA -->
|
|
@@ -116,20 +116,18 @@
|
|
|
116
116
|
<tr>
|
|
117
117
|
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top;">
|
|
118
118
|
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 20px; color: #15212A; font-weight: bold; line-height: 25px; margin: 0; margin-bottom: 15px;">Hey there,</p>
|
|
119
|
-
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 32px;">Someone just replied to your comment on <a href="{{postUrl}}" target="_blank">{{postTitle}}</a>.</p>
|
|
119
|
+
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 32px;">Someone just replied to your comment on <a href="{{postUrl}}" target="_blank" style="font-weight: bold; text-decoration: underline;">{{postTitle}}</a>.</p>
|
|
120
120
|
|
|
121
|
-
<table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; box-sizing: border-box; background: #F9F9FA; border-radius: 7px;">
|
|
121
|
+
<table width="100" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; table-layout: fixed; width: 100%; min-width: 100%; box-sizing: border-box; background: #F9F9FA; border-radius: 7px;">
|
|
122
122
|
<tbody>
|
|
123
123
|
<tr>
|
|
124
124
|
<td align="left" style="padding: 16px;">
|
|
125
125
|
<table border="0" cellpadding="0" cellspacing="0">
|
|
126
126
|
<tr>
|
|
127
|
-
<td style="
|
|
128
|
-
<
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
</tr>
|
|
132
|
-
</table>
|
|
127
|
+
<td style="padding-right: 8px;">
|
|
128
|
+
<div style="width: 44px; height: 44px; background-color: #15171A; border-radius: 999px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #FFFFFF; text-align: center; vertical-align: center; font-weight: 500; line-height: 42px;">
|
|
129
|
+
{{memberInitials}}
|
|
130
|
+
</div>
|
|
133
131
|
</td>
|
|
134
132
|
<td style="padding-right: 8px;">
|
|
135
133
|
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; padding-right: 8px; padding: 0; margin: 0; color: #15171A; font-weight: 600;">{{memberName}}</p>
|
|
@@ -154,7 +152,7 @@
|
|
|
154
152
|
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: auto;">
|
|
155
153
|
<tbody>
|
|
156
154
|
<tr>
|
|
157
|
-
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; vertical-align: top; background-color: {{accentColor}}; border-radius: 5px; text-align: center;"> <a href="{{postUrl}}#ghost-comments
|
|
155
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; vertical-align: top; background-color: {{accentColor}}; border-radius: 5px; text-align: center;"> <a href="{{postUrl}}#ghost-comments" target="_blank" style="display: inline-block; color: #ffffff; background-color: {{accentColor}}; border: solid 1px {{accentColor}}; border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 16px; font-weight: normal; margin: 0; padding: 9px 22px 10px; border-color: {{accentColor}};">View comments</a> </td>
|
|
158
156
|
</tr>
|
|
159
157
|
</tbody>
|
|
160
158
|
</table>
|
|
@@ -164,7 +162,7 @@
|
|
|
164
162
|
</table>
|
|
165
163
|
<hr/>
|
|
166
164
|
<p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 5px;">You can also copy & paste this URL into your browser:</p>
|
|
167
|
-
<p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 25px; margin-top:0; color: #3A464C;">{{postUrl}}#ghost-comments
|
|
165
|
+
<p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 25px; margin-top:0; color: #3A464C;">{{postUrl}}#ghost-comments</p>
|
|
168
166
|
</td>
|
|
169
167
|
</tr>
|
|
170
168
|
|
|
@@ -116,20 +116,18 @@
|
|
|
116
116
|
<tr>
|
|
117
117
|
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top;">
|
|
118
118
|
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 20px; color: #15212A; font-weight: bold; line-height: 25px; margin: 0; margin-bottom: 15px;">Hey there,</p>
|
|
119
|
-
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 32px;">Someone just left a comment on your post <a href="{{postUrl}}" target="_blank">{{postTitle}}</a>.</p>
|
|
119
|
+
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 32px;">Someone just left a comment on your post <a href="{{postUrl}}" target="_blank" style="font-weight: bold; text-decoration: underline;">{{postTitle}}</a>.</p>
|
|
120
120
|
|
|
121
|
-
<table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; box-sizing: border-box; background: #F9F9FA; border-radius: 7px;">
|
|
121
|
+
<table width="100" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; table-layout: fixed; width: 100%; min-width: 100%; box-sizing: border-box; background: #F9F9FA; border-radius: 7px;">
|
|
122
122
|
<tbody>
|
|
123
123
|
<tr>
|
|
124
124
|
<td align="left" style="padding: 16px;">
|
|
125
125
|
<table border="0" cellpadding="0" cellspacing="0">
|
|
126
126
|
<tr>
|
|
127
|
-
<td style="
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
</tr>
|
|
132
|
-
</table>
|
|
127
|
+
<td style="padding-right: 8px;">
|
|
128
|
+
<div style="width: 44px; height: 44px; background-color: #15171A; border-radius: 999px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #FFFFFF; text-align: center; vertical-align: center; font-weight: 500; line-height: 42px;">
|
|
129
|
+
{{memberInitials}}
|
|
130
|
+
</div>
|
|
133
131
|
</td>
|
|
134
132
|
<td style="padding-right: 8px;">
|
|
135
133
|
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; padding-right: 8px; padding: 0; margin: 0; color: #15171A; font-weight: 600;">{{memberName}}</p>
|
|
@@ -154,7 +152,7 @@
|
|
|
154
152
|
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: auto;">
|
|
155
153
|
<tbody>
|
|
156
154
|
<tr>
|
|
157
|
-
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; vertical-align: top; background-color: {{accentColor}}; border-radius: 5px; text-align: center;"> <a href="{{postUrl}}#ghost-comments
|
|
155
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; vertical-align: top; background-color: {{accentColor}}; border-radius: 5px; text-align: center;"> <a href="{{postUrl}}#ghost-comments" target="_blank" style="display: inline-block; color: #ffffff; background-color: {{accentColor}}; border: solid 1px {{accentColor}}; border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 16px; font-weight: normal; margin: 0; padding: 9px 22px 10px; border-color: {{accentColor}};">View comments</a> </td>
|
|
158
156
|
</tr>
|
|
159
157
|
</tbody>
|
|
160
158
|
</table>
|
|
@@ -164,7 +162,7 @@
|
|
|
164
162
|
</table>
|
|
165
163
|
<hr/>
|
|
166
164
|
<p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 5px;">You can also copy & paste this URL into your browser:</p>
|
|
167
|
-
<p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 25px; margin-top:0; color: #3A464C;">{{postUrl}}#ghost-comments
|
|
165
|
+
<p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 25px; margin-top:0; color: #3A464C;">{{postUrl}}#ghost-comments</p>
|
|
168
166
|
</td>
|
|
169
167
|
</tr>
|
|
170
168
|
|
|
@@ -118,18 +118,16 @@
|
|
|
118
118
|
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 20px; color: #15212A; font-weight: bold; line-height: 25px; margin: 0; margin-bottom: 15px;">Hey there,</p>
|
|
119
119
|
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 32px;">{{reporter}} has reported the comment below on <a href="{{postUrl}}" target="_blank">{{postTitle}}</a>. This comment will remain visible until you choose to remove it, which can be done directly on the post.</p>
|
|
120
120
|
|
|
121
|
-
<table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; box-sizing: border-box; background: #F9F9FA; border-radius: 7px;">
|
|
121
|
+
<table width="100" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; table-layout: fixed; width: 100%; min-width: 100%; box-sizing: border-box; background: #F9F9FA; border-radius: 7px;">
|
|
122
122
|
<tbody>
|
|
123
123
|
<tr>
|
|
124
124
|
<td align="left" style="padding: 16px;">
|
|
125
125
|
<table border="0" cellpadding="0" cellspacing="0">
|
|
126
126
|
<tr>
|
|
127
|
-
<td style="
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
</tr>
|
|
132
|
-
</table>
|
|
127
|
+
<td style="padding-right: 8px;">
|
|
128
|
+
<div style="width: 44px; height: 44px; background-color: #15171A; border-radius: 999px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #FFFFFF; text-align: center; vertical-align: center; font-weight: 500; line-height: 42px;">
|
|
129
|
+
{{memberInitials}}
|
|
130
|
+
</div>
|
|
133
131
|
</td>
|
|
134
132
|
<td style="padding-right: 8px;">
|
|
135
133
|
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; padding-right: 8px; padding: 0; margin: 0; color: #15171A; font-weight: 600;">{{memberName}}</p>
|
|
@@ -154,7 +152,7 @@
|
|
|
154
152
|
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: auto;">
|
|
155
153
|
<tbody>
|
|
156
154
|
<tr>
|
|
157
|
-
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; vertical-align: top; background-color: {{accentColor}}; border-radius: 5px; text-align: center;"> <a href="{{postUrl}}#ghost-comments
|
|
155
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; vertical-align: top; background-color: {{accentColor}}; border-radius: 5px; text-align: center;"> <a href="{{postUrl}}#ghost-comments" target="_blank" style="display: inline-block; color: #ffffff; background-color: {{accentColor}}; border: solid 1px {{accentColor}}; border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 16px; font-weight: normal; margin: 0; padding: 9px 22px 10px; border-color: {{accentColor}};">View comment</a> </td>
|
|
158
156
|
</tr>
|
|
159
157
|
</tbody>
|
|
160
158
|
</table>
|
|
@@ -164,7 +162,7 @@
|
|
|
164
162
|
</table>
|
|
165
163
|
<hr/>
|
|
166
164
|
<p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 5px;">You can also copy & paste this URL into your browser:</p>
|
|
167
|
-
<p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 25px; margin-top:0; color: #3A464C;">{{postUrl}}#ghost-comments
|
|
165
|
+
<p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 25px; margin-top:0; color: #3A464C;">{{postUrl}}#ghost-comments</p>
|
|
168
166
|
</td>
|
|
169
167
|
</tr>
|
|
170
168
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const {promises: fs} = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const moment = require('moment');
|
|
4
|
-
const htmlToPlaintext = require('
|
|
4
|
+
const htmlToPlaintext = require('@tryghost/html-to-plaintext');
|
|
5
5
|
|
|
6
6
|
class CommentsServiceEmails {
|
|
7
7
|
constructor({config, logging, models, mailer, settingsCache, urlService, urlUtils}) {
|
|
@@ -26,7 +26,7 @@ class CommentsServiceEmails {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
const to = author.get('email');
|
|
29
|
-
const subject = '💬
|
|
29
|
+
const subject = '💬 New comment on your post: ' + post.get('title');
|
|
30
30
|
|
|
31
31
|
const memberName = member.get('name') || 'Anonymous';
|
|
32
32
|
|
|
@@ -72,7 +72,7 @@ class CommentsServiceEmails {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
const to = parentMember.get('email');
|
|
75
|
-
const subject = '
|
|
75
|
+
const subject = '↪️ New reply to your comment on ' + this.settingsCache.get('title');
|
|
76
76
|
|
|
77
77
|
const post = await this.models.Post.findOne({id: reply.get('post_id')});
|
|
78
78
|
const member = await this.models.Member.findOne({id: reply.get('member_id')});
|
|
@@ -129,7 +129,7 @@ class CommentsServiceEmails {
|
|
|
129
129
|
postTitle: post.get('title'),
|
|
130
130
|
postUrl: this.urlService.getUrlByResourceId(post.get('id'), {absolute: true}),
|
|
131
131
|
commentHtml: comment.get('html'),
|
|
132
|
-
commentText: htmlToPlaintext.
|
|
132
|
+
commentText: htmlToPlaintext.comment(comment.get('html')),
|
|
133
133
|
commentDate: moment(comment.get('created_at')).tz(this.settingsCache.get('timezone')).format('D MMM YYYY'),
|
|
134
134
|
|
|
135
135
|
reporterName: reporter.name,
|
|
@@ -2,6 +2,7 @@ class CommentsServiceWrapper {
|
|
|
2
2
|
init() {
|
|
3
3
|
const CommentsService = require('./service');
|
|
4
4
|
const CommentsController = require('./controller');
|
|
5
|
+
const CommentsStats = require('./stats');
|
|
5
6
|
|
|
6
7
|
const config = require('../../../shared/config');
|
|
7
8
|
const logging = require('@tryghost/logging');
|
|
@@ -12,6 +13,7 @@ class CommentsServiceWrapper {
|
|
|
12
13
|
const urlService = require('../url');
|
|
13
14
|
const urlUtils = require('../../../shared/url-utils');
|
|
14
15
|
const membersService = require('../members');
|
|
16
|
+
const db = require('../../data/db');
|
|
15
17
|
|
|
16
18
|
this.api = new CommentsService({
|
|
17
19
|
config,
|
|
@@ -24,7 +26,9 @@ class CommentsServiceWrapper {
|
|
|
24
26
|
contentGating: membersService.contentGating
|
|
25
27
|
});
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
const stats = new CommentsStats({db});
|
|
30
|
+
|
|
31
|
+
this.controller = new CommentsController(this.api, stats);
|
|
28
32
|
}
|
|
29
33
|
}
|
|
30
34
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module.exports = class CommentsStatsService {
|
|
2
|
+
constructor(deps) {
|
|
3
|
+
this.db = deps.db;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {string[]} ids - List of post ids to fetch counts for
|
|
8
|
+
* @returns {Promise<Object<string, number>>}
|
|
9
|
+
*/
|
|
10
|
+
async getCountsByPost(ids) {
|
|
11
|
+
const results = await this.db.knex('comments')
|
|
12
|
+
.select(this.db.knex.raw(`COUNT(*) AS count, post_id`))
|
|
13
|
+
.groupBy('post_id')
|
|
14
|
+
.whereIn('post_id', ids);
|
|
15
|
+
|
|
16
|
+
const counts = ids.reduce((memo, id) => {
|
|
17
|
+
const result = results.find(x => x.post_id === id);
|
|
18
|
+
return {
|
|
19
|
+
...memo,
|
|
20
|
+
[id]: result?.count || 0
|
|
21
|
+
};
|
|
22
|
+
}, {});
|
|
23
|
+
|
|
24
|
+
return counts;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @returns {Promise<Object<string, number>>}
|
|
29
|
+
*/
|
|
30
|
+
async getAllCounts() {
|
|
31
|
+
const results = await this.db.knex('comments')
|
|
32
|
+
.select(this.db.knex.raw(`COUNT(*) AS count, post_id`))
|
|
33
|
+
.groupBy('post_id');
|
|
34
|
+
|
|
35
|
+
/** @type Object<string, number> */
|
|
36
|
+
let counts = {};
|
|
37
|
+
|
|
38
|
+
for (const row of results) {
|
|
39
|
+
counts[row.post_id] = row.count;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return counts;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
@@ -104,7 +104,7 @@ const sendTestEmail = async (postModel, toEmails, memberSegment) => {
|
|
|
104
104
|
};
|
|
105
105
|
}));
|
|
106
106
|
|
|
107
|
-
// enable tracking for previews to match real-world
|
|
107
|
+
// enable tracking for previews to match real-world behavior
|
|
108
108
|
emailData.track_opens = !!settingsCache.get('email_track_opens');
|
|
109
109
|
|
|
110
110
|
const response = await bulkEmailService.send(emailData, recipients, memberSegment);
|