ghost 5.7.0 → 5.8.1
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.904e017ad397bb681e9d.js +41 -0
- package/core/built/admin/assets/chunk.174.eec7f6398cef4c3e2485.js +239 -0
- package/core/built/admin/assets/chunk.178.9541bdb92bded29cd60d.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-ff9ba089fd81cb40831f4b62e63a2ca9.js → admin/assets/ghost-a66a04418efe85083a3adca0fb16bb52.js} +320 -306
- package/core/built/admin/assets/ghost-b469423d0fbe5e40af17b560f7e3cead.css +1 -0
- package/core/built/admin/assets/ghost-dark-bcb6f4517a2dfe23a0a280632bfca00c.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/title.js +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/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/index.js +1 -1
- package/core/server/api/endpoints/integrations.js +12 -8
- package/core/server/api/endpoints/utils/index.js +4 -0
- package/core/server/api/endpoints/utils/serializers/input/tiers.js +5 -0
- package/core/server/api/endpoints/utils/serializers/output/mappers/comments.js +8 -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 +47 -15
- 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/service.js +3 -3
- 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 +1 -1
- 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 +1 -1
- 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 +33 -38
- package/yarn.lock +14494 -3715
- package/core/built/assets/chunk.3.33097bb5eb150719bdd2.js +0 -197
- package/core/built/assets/ghost-dark-1bdd57aba1fa4a23388121740454dab2.css +0 -1
- package/core/built/assets/ghost.min-8f5c061e0892b93adecc2b9e37ad2f3a.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
|
@@ -2,13 +2,30 @@ 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
|
-
notYourCommentToDestroy: 'You may only delete your own comments'
|
|
11
|
+
notYourCommentToDestroy: 'You may only delete your own comments',
|
|
12
|
+
cannotEditDeletedComment: 'You may only edit published comments'
|
|
10
13
|
};
|
|
11
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Remove empty paragraps from the start and end
|
|
17
|
+
* + remove duplicate empty paragrapsh (only one empty line allowed)
|
|
18
|
+
*/
|
|
19
|
+
function trimParagraphs(str) {
|
|
20
|
+
const paragraph = '<p></p>';
|
|
21
|
+
const escapedParagraph = '<p>\\s*?</p>';
|
|
22
|
+
|
|
23
|
+
const startReg = new RegExp('^(' + escapedParagraph + ')+');
|
|
24
|
+
const endReg = new RegExp('(' + escapedParagraph + ')+$');
|
|
25
|
+
const duplicates = new RegExp('(' + escapedParagraph + ')+');
|
|
26
|
+
return str.replace(startReg, '').replace(endReg, '').replace(duplicates, paragraph);
|
|
27
|
+
}
|
|
28
|
+
|
|
12
29
|
const Comment = ghostBookshelf.Model.extend({
|
|
13
30
|
tableName: 'comments',
|
|
14
31
|
|
|
@@ -46,23 +63,38 @@ const Comment = ghostBookshelf.Model.extend({
|
|
|
46
63
|
onSaving() {
|
|
47
64
|
ghostBookshelf.Model.prototype.onSaving.apply(this, arguments);
|
|
48
65
|
|
|
66
|
+
if (this.hasChanged('html') && this.get('status') !== 'published') {
|
|
67
|
+
throw new ValidationError({
|
|
68
|
+
message: tpl(messages.cannotEditDeletedComment)
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
49
72
|
if (this.hasChanged('html')) {
|
|
50
73
|
const sanitizeHtml = require('sanitize-html');
|
|
51
74
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
75
|
+
const html = trimParagraphs(
|
|
76
|
+
sanitizeHtml(this.get('html'), {
|
|
77
|
+
allowedTags: ['p', 'br', 'a', 'blockquote'],
|
|
78
|
+
allowedAttributes: {
|
|
79
|
+
a: ['href', 'target', 'rel']
|
|
80
|
+
},
|
|
81
|
+
selfClosing: ['br'],
|
|
82
|
+
// Enforce _blank and safe URLs
|
|
83
|
+
transformTags: {
|
|
84
|
+
a: sanitizeHtml.simpleTransform('a', {
|
|
85
|
+
target: '_blank',
|
|
86
|
+
rel: 'ugc noopener noreferrer nofollow'
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
).trim();
|
|
91
|
+
|
|
92
|
+
if (html.length === 0) {
|
|
93
|
+
throw new ValidationError({
|
|
94
|
+
message: tpl(messages.emptyComment)
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
this.set('html', html);
|
|
66
98
|
}
|
|
67
99
|
},
|
|
68
100
|
|
|
@@ -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
|
|
|
@@ -10,7 +10,8 @@ const messages = {
|
|
|
10
10
|
alreadyLiked: 'This comment was liked already',
|
|
11
11
|
replyToReply: 'Can not reply to a reply',
|
|
12
12
|
commentsNotEnabled: 'Comments are not enabled for this site.',
|
|
13
|
-
cannotCommentOnPost: 'You do not have permission to comment on this post.'
|
|
13
|
+
cannotCommentOnPost: 'You do not have permission to comment on this post.',
|
|
14
|
+
cannotEditComment: 'You do not have permission to edit comments'
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
class CommentsService {
|
|
@@ -285,8 +286,7 @@ class CommentsService {
|
|
|
285
286
|
|
|
286
287
|
if (existingComment.get('member_id') !== member) {
|
|
287
288
|
throw new errors.NoPermissionError({
|
|
288
|
-
|
|
289
|
-
message: tpl(messages.memberNotFound)
|
|
289
|
+
message: tpl(messages.cannotEditComment)
|
|
290
290
|
});
|
|
291
291
|
}
|
|
292
292
|
|
|
@@ -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);
|
|
@@ -8,7 +8,7 @@ const api = require('../../api').endpoints;
|
|
|
8
8
|
const apiShared = require('../../api').shared;
|
|
9
9
|
const {URL} = require('url');
|
|
10
10
|
const mobiledocLib = require('../../lib/mobiledoc');
|
|
11
|
-
const htmlToPlaintext = require('
|
|
11
|
+
const htmlToPlaintext = require('@tryghost/html-to-plaintext');
|
|
12
12
|
const membersService = require('../members');
|
|
13
13
|
const {isUnsplashImage, isLocalContentImage} = require('@tryghost/kg-default-cards/lib/utils');
|
|
14
14
|
const {textColorForBackgroundColor, darkenToContrastThreshold} = require('@tryghost/color-utils');
|
|
@@ -116,7 +116,7 @@ const updateMemberNewsletters = async function (req, res) {
|
|
|
116
116
|
|
|
117
117
|
const updateMemberData = async function (req, res) {
|
|
118
118
|
try {
|
|
119
|
-
const data = _.pick(req.body, 'name', 'subscribed', 'newsletters', 'enable_comment_notifications');
|
|
119
|
+
const data = _.pick(req.body, 'name', 'bio', 'subscribed', 'newsletters', 'enable_comment_notifications');
|
|
120
120
|
const member = await membersService.ssr.getMemberDataFromSession(req, res);
|
|
121
121
|
if (member) {
|
|
122
122
|
const options = {
|
|
@@ -13,6 +13,7 @@ module.exports.formattedMemberResponse = function formattedMemberResponse(member
|
|
|
13
13
|
email: member.email,
|
|
14
14
|
name: member.name,
|
|
15
15
|
firstname: member.name && member.name.split(' ')[0],
|
|
16
|
+
bio: member.bio,
|
|
16
17
|
avatar_image: member.avatar_image,
|
|
17
18
|
subscribed: !!member.subscribed,
|
|
18
19
|
subscriptions: member.subscriptions || [],
|
|
@@ -9,6 +9,7 @@ const events = require('../../lib/common/events');
|
|
|
9
9
|
const models = require('../../models');
|
|
10
10
|
const labs = require('../../../shared/labs');
|
|
11
11
|
const config = require('../../../shared/config');
|
|
12
|
+
const adapterManager = require('../adapter-manager');
|
|
12
13
|
const SettingsCache = require('../../../shared/settings-cache');
|
|
13
14
|
const SettingsBREADService = require('./settings-bread-service');
|
|
14
15
|
const {obfuscatedSetting, isSecretSetting, hideValueIfSecret} = require('./settings-utils');
|
|
@@ -66,8 +67,9 @@ module.exports = {
|
|
|
66
67
|
* Initialize the cache, used in boot and in testing
|
|
67
68
|
*/
|
|
68
69
|
async init() {
|
|
70
|
+
const cacheStore = adapterManager.getAdapter('cache');
|
|
69
71
|
const settingsCollection = await models.Settings.populateDefaults();
|
|
70
|
-
SettingsCache.init(events, settingsCollection, this.getCalculatedFields());
|
|
72
|
+
SettingsCache.init(events, settingsCollection, this.getCalculatedFields(), cacheStore);
|
|
71
73
|
},
|
|
72
74
|
|
|
73
75
|
/**
|
|
@@ -159,7 +159,7 @@ class Resources {
|
|
|
159
159
|
* @description Call the model layer to fetch a single resource via raw knex queries.
|
|
160
160
|
*
|
|
161
161
|
* This function was invented, because the model event is a generic event, which is independent of any
|
|
162
|
-
* api version
|
|
162
|
+
* api version behavior. We have to ensure that a model matches the conditions of the configured api version
|
|
163
163
|
* in the theme.
|
|
164
164
|
*
|
|
165
165
|
* See https://github.com/TryGhost/Ghost/issues/10124.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const debug = require('@tryghost/debug')('web:admin:app');
|
|
2
|
+
const path = require('path');
|
|
2
3
|
const express = require('../../../shared/express');
|
|
3
4
|
const serveStatic = express.static;
|
|
4
5
|
const config = require('../../../shared/config');
|
|
@@ -17,7 +18,7 @@ module.exports = function setupAdminApp() {
|
|
|
17
18
|
// @TODO ensure this gets a local 404 error handler
|
|
18
19
|
const configMaxAge = config.get('caching:admin:maxAge');
|
|
19
20
|
adminApp.use('/assets', serveStatic(
|
|
20
|
-
config.get('paths').adminAssets,
|
|
21
|
+
path.join(config.get('paths').adminAssets, 'assets'),
|
|
21
22
|
{maxAge: (configMaxAge || configMaxAge === 0) ? configMaxAge : constants.ONE_YEAR_MS, fallthrough: false}
|
|
22
23
|
));
|
|
23
24
|
|
|
@@ -29,8 +29,7 @@ module.exports = function adminController(req, res) {
|
|
|
29
29
|
// CASE: trigger update check unit and let it run in background, don't block the admin rendering
|
|
30
30
|
updateCheck();
|
|
31
31
|
|
|
32
|
-
const
|
|
33
|
-
const templatePath = path.resolve(config.get('paths').adminViews, defaultTemplate);
|
|
32
|
+
const templatePath = path.resolve(config.get('paths').adminAssets, 'index.html');
|
|
34
33
|
const headers = {};
|
|
35
34
|
|
|
36
35
|
try {
|