fix https://linear.app/tryghost/issue/SLO-95/unexpected-end-of-multipart-data-for-broken-image-upload-request
- in the event the client sends an invalid body to the image or media
upload endpoints, Dicer will throw an error if the boundary data is
malformed
- previously, we've just been bubbling that up as an InternalServerError
and that results in an HTTP 500
- we can capture errors produced by dicer and return a handled
BadRequestError, as it's the client's fault
- also includes breaking tests
fix https://linear.app/tryghost/issue/SLO-94/unexpected-field-when-given-broken-image-upload-request
- in the event the body of an image or media upload request is malformed
(broken metadata / blob or something), we get a MulterError and this
bubbles up as an InternalServerError and spits out a HTTP 500
- we can capture this and return a BadRequestError, as it's the client's
fault for not providing the correct body
- this implements that and adds breaking tests
fix https://linear.app/tryghost/issue/SLO-96/invalid-version-must-be-a-string-got-type-object-an-unexpected-error
- in the event that a non-semver Accept-Version header is given, the
current code will throw an error because the semver lib can't compare null
against a valid version
- the error in question is `Must be a string. Got type "object"`
- to fix this, we can just detect a null and early return with a
BadRequestError
- also adds a breaking test
ref https://linear.app/tryghost/issue/MOM-72
This module handles signing and validating HTTP signatures, which is a core
part of interfacing with ActivityPub enabled servers.
ref
https://linear.app/tryghost/issue/ENG-902/add-an-optional-timeout-in-the-redis-cache-adapter-in-case-redis
- Added an optional timeout parameter to AdapterCacheRedis, so that the
`get(key)` method will return `null` after the timeout if it hasn't
received a response from Redis
- When load testing the `LinkRedirectRepository` with the Redis cache
enabled on staging, we noticed that for some reason Redis stopped
responding to commands for ~30 seconds.
- The `LinkRedirectRepository` was waiting for the Redis cache to
respond and resulted in a drastic increase in response times for link
redirects
- This change will allow us to set a timeout on the `get(key)` method,
so that if Redis doesn't respond within the timeout, the method will
return `null` as if it were a cache miss.
- Then the `LinkRedirectRepository` will fall back to the database and
return the link redirect from the database instead of waiting
indefinitely for Redis to respond
fix https://linear.app/tryghost/issue/SLO-93/undefined-path-error-with-bad-image-upload
- in the event we receive a request to upload an image, that doesn't
contain an image, we still try and unlink the files
- this is a dangling promise, so it doesn't cause an explicit HTTP
error, but it does show up as a console error
- fixed it by checking for the path, and early returning if it doesn't
exist
- also added a test that would fail without this
ref https://linear.app/tryghost/issue/SLO-78
- the `POST /members/api/member` endpoint is solely used by the alpha
feature `membersSpamPrevention` and should not be available otherwise
fix https://linear.app/tryghost/issue/SLO-88/typeerror-cannot-read-properties-of-null-reading-relations
- in the event that we make it through the version mismatch code, but
without a key, which is possible if you send a request like POST
/ghost/api/v2/content/posts/`, then the version mismatch code will try
and look up the API key attached to a null key, which won't work
- we should handle this case and soft return, to avoid trying to read
`.relations` from `null`
- I'm not entirely convinced by how this code works in general, it seems
quite confusing to reason about, but this commit should solve the HTTP
500 we've been seeing from this
- perhaps in the future we can return earlier in the flow if we receive
a `null` key
ref https://linear.app/tryghost/issue/ENG-881/stripe-tax-checkout-instantiation-fails-for-free-members-when-choosing
- For existing customers to be able to upgrade their account with automatic tax enabled, we need to pass in `customer_update[address]:auto` as per Stripe documentation.
- Automatic tax calculation in Checkout requires a valid address on the Customer. Add a valid address to the Customer or set either 'customer_update[address]' to 'auto' or 'customer_update[shipping]' to 'auto' to save the address entered in Checkout to the Customer.
- We update the existing customer details by passing in address `auto` when they upgrade their accounts.
- Stripe captures the billing address information by default when new accounts are created and then that is used to calculate the tax rate.
ref https://linear.app/tryghost/issue/ENG-842/gluster-file-name-length-limit
- when uploading a theme, Admin did not always render errors properly, zip extraction errors for example
- with this change, we do not change the API responses but rather update Admin to handle both types of error responses
fix https://linear.app/tryghost/issue/SLO-82/query-error-unexpected-character-in-filter-at-char-1
- previously, we weren't handling a parsing error, and just bubbling it
back up the chain
- this would result in an InternalServerError somewhere, which caused
500s
- we can handle this, because it's just a bad filter
- this adds handling so we return a 422 upon receiving an invalid filter
fix https://linear.app/tryghost/issue/SLO-79/incorrectusageerror-the-url-httpsblogkongregatecompercentc0-couldnt-be
- we added this Sentry captureException whilst fixing a bug where
decodeUrl could fail, and throw a 500 exception
- we added handling for that case and returned an empty string, but we
also added Sentry error capturing
- at this point, I don't think we need to be capturing errors in Sentry,
because the issue is already handled, and it only usually happens with
malicious/incorrect URLs
- this is our #2 cause of Sentry alerts, so it's good to clean it up
ref https://linear.app/tryghost/issue/ENG-881/stripe-tax-checkout-instantiation-fails-for-free-members-when-choosing
- For existing customers to be able to upgrade their account with automatic tax enabled, we need to pass in `customer_update[address]:auto` as per Stripe documentation.
- Automatic tax calculation in Checkout requires a valid address on the Customer. Add a valid address to the Customer or set either 'customer_update[address]' to 'auto' or 'customer_update[shipping]' to 'auto' to save the address entered in Checkout to the Customer.
- We update the existing customer details by passing in address `auto` when they upgrade their accounts.
- Stripe captures the billing address information by default when new accounts are created and then that is used to calculate the tax rate.
- we don't need to deep require into the library as it exports what we
need on the surface
- this should unblock https://github.com/TryGhost/Ghost/pull/19002, as
it's randomly failing with this require
refs
[ENG-827](https://linear.app/tryghost/issue/ENG-827/🐛-crash-on-resizing-animated-gif)
Added a timeout to the image resizing middleware to prevent crashes when
an image is taking too long to resize. When the timeout is reached and
the image has not been resized, the middleware will return the original
image
closes https://linear.app/tryghost/issue/MOM-60
- when the dropdown opens near the end of the document, clicking the links sometimes did nothing and showed an error in the console
- we have a mousedown event handler on an element that surrounds the main editing element that re-focuses the editor when clicked in order to make the "focus editor" click target larger and more natural-feeling but it was inadvertently re-focusing when the mousedown event fired for an element in the dropdown list when the list was positioned outside of the main editor element. This lead to timing issues with the bookmark node being removed on blur because it was empty followed by an error from the node's component's async event handlers which were trying to set values on the now-removed node
- by switching from `event.target.closest()` to looping over `event.composedPath()` when checking to see if we should skip re-focusing we're more resilient to DOM manipulations occurring between event triggers and function calls because we'll always be given the list of elements that existed at the time the event fired
reduce word size to fit properly within button without making style
changes (_economize_ and _poupe_ have the exact same meaning)
Co-authored-by: Ryan Feigenbaum <48868107+royalfig@users.noreply.github.com>