refs https://github.com/TryGhost/Ghost/security/advisories/GHSA-wfrj-qqc2-83cm
refs https://github.com/advisories/GHSA-48ww-j4fc-435p
- a vulnerability in `nodemailer` means that the `sendmail` transport is
vulnerable to command injection for flags passed to the `sendmail`
binary
- updating to the latest version of Nodemailer required creating
`@tryghost/nodemailer`, which is a wrapper around Nodemailer and
several plugins that used to be in the core
- this commit switches to using that package, and fixes up some small
code + test changes
no-issue
We're seeing problems with large sites taking a long time to run this
migration. The aim here is to refactor it so that it is faster to run.
We've achieved that by reducing the number of database queries needed,
firstly by selecting members with a join to their events (rather than
fetching the events on a member-by-member basis) we also batch the
necessary updates to further reduce db query time.
closes: CORE-34
refs: https://github.com/TryGhost/Team/issues/1044
- this is a super basic fix, it adds a max nodes concept and limits the node in each sub-sitemap to 50k by default
- this will prevent the error in google console
- a better fix is in progress, but we want to at least solve the errors ASAP
refs https://github.com/TryGhost/Team/issues/1053
This table is going to be completely deleted at some point in the
future. It serves as a persistent datastore for a spike into collection
analytic events for members. We've opted for a generic table, rather
than a table for each event, so that we can push the DB to the limit in
terms of the length of the table, and find out performance issues A$AP
closes: CORE-33
Two bugs:
- lodash isEmpty and handlebars util isEmpty are not the same
- I literally had the truthy and falsy cases the wrong way around 🙈
Notes:
- I have, for now, copied the isEmpty util from handlebars. It's so small it doesn't seem worth trying to require the util right now, although in future it'd be nice if that was easier to do
- Adding the management for the conditional being a SafeString allows the match helper to be a subexpression of itself, I can see this pattern being useful later in combo with the any and all helpers
refs https://github.com/TryGhost/Team/issues/1047
Rendering segmented emails uses `cheerio` to parse and re-render the html but this had a side-effect of converting the `$#39;` char code to the more modern `$apos;` code resulting in Outlook not understanding quotes inside inlined CSS and showing the raw char code if it appeared in the email contents.
- extracted our handling of the unsupported char codes from the main email html generation into a function so that it can be re-used when generating segmented html
refs 70627d84a7
refs 44035fd591
refs https://github.com/TryGhost/Team/issues/477
- When v4 Webhook API was changed removing redundant code v3 API code should've been updated as well. Making this change before extracting logic out into a WebhooksService to have clear chain of why the code that doesn't look the same has been substituted
refs https://github.com/TryGhost/Team/issues/694
refs https://linear.app/tryghost/issue/CORE-10/tackle-integrationsjs
- The controller code is not meant to contain complex business logic.
- Added a test case checking 'PUT' endpoint for integrations to ensure
proper 'NotFound' handling. Found that previous implemenation was
buggy - threw a 500 as 'models.Integration.NotFoundError' that was removed
in previous commit didn't catch a needed error.
no issue
It was possible for authenticated/trusted admin users to make GET requests to localhost via the oembed service by crafting a redirect that used 0.0.0.0.
- added the 0.* default route/routing block to the private IP regex used to block requests when we're contacting external sites
- added an additional IP or localhost check in the oembed service when fetching bookmark card data
- as per 5a5a5d162e, the Bookshelf registry plugin is now in core
- we no longer need to explicitly load the plugin, and it displays a
warning if you do
- this change also turns `._models` into `.registry.models`, so our code has
been updated to reflect that
- as per https://github.com/bookshelf/bookshelf/wiki/Migrating-from-0.15.1-to-1.0.0#default-to-require-true-on-modelfetch-and-collectionfetchone, models will now default to `{require:true}` during a fetch, which changes how Bookshelf will respond when a models yields no results
- instead of passing a `null` result, it will reject with an error, so we'd need to switch to `.catch`ing everything
- our code is set up to handle all these null results and switching style is not currently on the cards so we want to use the existing behaviour for now
- to enable this, the `requireFetch` option needs to be added to the model definitions
refs https://github.com/TryGhost/Team/issues/1030
The usage of `setComplimentarySubscription` is for pre-Tiers enabled
sites only. We didn't see this issue before because the `comped` flag
was incorrectly being set to `false` by default. Since it was fixed in
https://github.com/TryGhost/Ghost/commit/ae844db60 the `comped` flag was
then getting sent up, and creating the subscription.
We've moved the usage of `setComplimentarySubscription` to behind the
feature flag so that we do not use old behaviour when Tiers are enabled
refs https://github.com/TryGhost/Ghost/pull/13276
- when removing the labs flag a conditional in the email processor checking for the labs flag being enabled was replaced with a check for a member segment being present. This meant that email batches with `member_segment: null` representing all members that didn't have content specifically aimed at them were not having the segmented content stripped before sending
refs https://github.com/TryGhost/Team/issues/1004
- adds new `{{products}}` helper behind `multipleProducts` flag
- `{{products}}` outputs a string with list of products that have access to specific post when used in a post context in theme
- outputs empty string when used out of a post context and without access to `visibility` property
- uses all available posts for a site via the global products data
- updates {{content}} helper cta to use this new helper to show list of tiers with access to post
refs https://github.com/TryGhost/Team/issues/1026
Tiers is moving up as a beta feature with an early-access opt-in flow. This means site owners can now opt-in for early access to Tiers feature in Ghost, but it's a one way door and its not possible to switch off tiers once enabled. This is to ensure that sites don't break in any unexpected ways once the tiers feature is enabled by switching it off.
refs https://github.com/TryGhost/Team/issues/1006
Moving the logic of disconnecting Stripe into the members-api module
decouples the Ghost API from the Members API internals. This method can
now be updated independently of Ghost, to implement the deletion of
webhooks from Stripe.
refs https://github.com/TryGhost/Team/issues/1000
Some free members were created with a status of 'comped', this resulted
in MemberStatusEvents being created with a `to_status` of 'comped'.
In 4.12 we fixed the status for all free members, but we did not update
the associated member_status_event.
refs https://github.com/TryGhost/Team/issues/995
Since we reintroduced the comped status, we did not update the
subscription handling to correctly set members to a status of comped
when they were on a 'Complimentary' plan. This meant that 'comped' members
had a status of 'paid'. The changes to @tryghost/members-api ensure that
handling subscriptions going forward will not result in this error.
Since we handle the Complimentary plan correctly now, we do not need to
manually check for the existence of one, we can instead rely on the
status to set the `comped` flag.
* Migrated members comped status to reflect subscriptions
refs https://github.com/TryGhost/Team/issues/995
Due to a bug in subscription handling, members with Complimentary stripe
subscriptions were incorrectly given a status of 'paid'.
The goal of this migration is to fix existing broken members, and it
will be accompanied by a fix which prevents the bug for future members.
Since we are updating the status properties for members, we must ensure
that we also update the relevant member_status_events entries too, so
that we do not have incompatible sums between events and statuses.
For example, if we were to use events to graph comped members over time,
we would want the current count to match the query on statuses:
`SELECT COUNT(*) FROM members WHERE status='comped';`
refs https://github.com/TryGhost/Ghost/issues/12942
The function signature of this method has changed, and was only updated
in the canary API, this meant that API requests attempting to link a
stripe customer to a member would error for the v3 API.
closes https://github.com/TryGhost/Team/issues/1024
Our importer would set the default value of all posts_meta keys to
`null`. This is an invalid value for the `email_only` key which only
accepts booleans.
Since we are already looping over the schema to create the default
values, we can use the `defaultTo` property in the schema to use the
intended default, and fall back to `null` if it doesn't exist.
We've used the `Reflect.has` function to determine if the `defaultTo`
key exists, as opposed to a truthy check, because it's possible that a
falsy value (e.g. false, in the case of email_only) can be used as the
default.
closes https://github.com/TryGhost/Team/issues/1024
Our importer would set the default value of all posts_meta keys to
`null`. This is an invalid value for the `email_only` key which only
accepts booleans.
Since we are already looping over the schema to create the default
values, we can use the `defaultTo` property in the schema to use the
intended default, and fall back to `null` if it doesn't exist.
We've used the `Reflect.has` function to determine if the `defaultTo`
key exists, as opposed to a truthy check, because it's possible that a
falsy value (e.g. false, in the case of email_only) can be used as the
default.
refs https://github.com/TryGhost/Team/issues/694
- The canary schedules controller was refactored to use newly introduced post-scheduling service in a previous commit. This is a follow up to match v2/v3 controllers as they had identical code to the canary one.
refs https://github.com/TryGhost/Team/issues/694
- The controller code is not meant to contain complex business logic.
- Kept the pattern used in all modules under services/themes. The install module shold be refactored into a class with DI pattern when touched next.
refs https://github.com/TryGhost/Team/issues/694
- Additional try/catch block needed in async/await implementation increased method complexity and broke the complexity linting rule. This is a dirty way to fix the warning. Ideally the implementation should stay with async/await syntax and instead move the custom error handling logic into some different layer. For example we could introduce a separate "stage" in the API framework's "pipeline" where we'd catch and handle in a generic way all of the "unique" types of errors. It would make sense to have a generic handler because this same code happens in labels, member and few more places.
refs baccbb4942
refs https://github.com/TryGhost/Team/issues/694
- The change is here to remove yet another ESLint method complexity error
- The custom error handling complexity was introduced here in a referenced commit without an obvious reason. The specifics of how the "sendTestEmail" method handles errors should not leak out from the method, if there are errors in the response they should be handled internally and the method would uniformly reject with a single error.
refs https://github.com/TryGhost/Team/issues/694
- The code complexity in the email preview's read controller method was breaking the complexity rule in ESLint. To reduce the complexity extracted common parts into mega service
no refs
- adds refinements to change plan UI in Portal
- adds other UI refinements to Portal for multiple tiers
- updates scrolling behavior in Portal in preview mode
- bumps `@tryghost/portal` to `1.9`
refs https://github.com/TryGhost/Team/issues/694
- async/await has been a standard way to handle async code throughout the codebase. Refactoring it before moving code makes it way easier to reason about similarities between multiple controllers