refs https://github.com/TryGhost/Team/issues/1217
- add `tenorApiKey` to `publicConfig.config()
- update canary config endpoint output serializer to include `tenorApiKey` when the `gifsCard` labs flag is enabled
refs https://github.com/TryGhost/Team/issues/1211
In order to override the default OEmbeds for OpenSea NFT's we need a way
to provide out own OEmbed data. We will want this in future too for
custom Twitter embeds, so this has been built in a way which allows
extension.
refs https://github.com/TryGhost/Team/issues/1212
This now emits the event when the service is reconfigured, rather than
when we issue the reconfigure command, which causes the event and the
action to be run in the wrong order. This would then cause knock on effects
of having the database in an undefined state - with stripe data in not linked
to the current Stripe account.
refs https://github.com/TryGhost/Toolbox/issues/120
- Changed endpoint name as it suits way better to the `/upload` postfix convention we use along with all other endpoints that support file uploads
closes https://github.com/TryGhost/Toolbox/issues/120
- Allows to update and upload brand new thumbnail images for previusly uploaded media resources
- The endpoint is available udner alpa flag as part of Admin API at `PUT /media/thumbnail/`
- As an input accepts following parameters:
- *required* `file` field containing an image file
- *required* `url` field containing parent media file URL
- *optional* `ref` as a field to put in an ID to reference the resource on the client side
- The response has following format:
```
{
media: [{
url: 'http://127.0.0.1:2369/content/images/1991/11/nicevideo_thumb.png'
ref: 'unique-id-420'
}]
}
```
refs https://github.com/TryGhost/Toolbox/issues/120
- When editing an uploaded media thumbnail file there'a need to remove existing thumbnail to keep media files:thumbnails 1:1. - Because the API client only has a public URL under which the resource is served it can only provide that as an API input, the `urlToPath` was also added to the base class of LocalStorageAdapter (it might be moved up to the BaseAdapter in the future if we see a need)
refs https://github.com/TryGhost/Toolbox/issues/114
- Files API is meant to be used for non-executable file uploads of all sorts
- The files are stored and retrieved for download as-is
no issue
- Not sure what the purpose of this test is. Seems like it's kind of like an db integrity check where it makes sure the change is double checked before commiting
- This comment removes the block on themes controlling card assets via config
- It also changes the default behaviour from "false" config (doing nothing) to excluding bookmark and gallery card assets
- This is essentially the same thing, as only bookmark and gallery card assets exist at the moment, but it's being done because it makes this feature future-proof for all theme developers.
- As we add new cards, all themes will automatically get the assets to make them work
- As theme developers want to, they can create their own custom assets and disble assets for any cards they support by adding them to the exclude list
- They can also remove any custom code they currently have to support bookmark and gallery cards, and set card_assets: true in package.json to use the defaults instead
- If we register the serve public file middleware for a file that doesn't exist, this will currently throw an ENOENT error
- Instead, we want to fall back to a standard 404 so that this behaves normally
- This will be useful for the card asset service, where the cards.min.css and cards.min.js files may or may not exist
refs https://github.com/TryGhost/Toolbox/issues/95
- The uploaded media thumbnail name should have a "_thumb" postfix to be able to distinguish thumbnails from other files. This can be handy if we decide to store them in a different location in the future.
refs https://github.com/TryGhost/Team/issues/807
The launch wizard completed flag was previously stored at per user level in accessibility column of user table, so an administrator still got the option to complete the launch wizard even if the owner had completed it previously, which is not expected pattern. This change moves the launch complete flag for Admin to common settings from per user level so a site only needs to complete the launch wizard once irrespective of which user completes it
- adds new `editor_is_launch_complete` setting to track if a site launch steps are completed in Admin
- adds new migration util to easily allow adding new setting
- adds migration to introduce new `editor_is_launch_complete` setting
- adds migration to update launch complete flag for a site if any of the users have already completed the launch steps
- Requires the new @tryghost/minifier package
- Adds a new service that will handle taking config from the theme and optionally including assets for Koenig editor cards
- It supports both css and js as cards may need one or both
- For any given config, the tool can find the matching files to include and concat and minify them into one file per type
- Currently has an override in place so that this is not yet customisable in the theme - will remove this override when we're ready for the feature
closes https://github.com/TryGhost/Toolbox/issues/111
- Just like with invalid JSON redirects files we should return a BadRequestError instead of throwing a generic 500 when the redirects.yaml file fails parsing
refs https://github.com/TryGhost/Toolbox/issues/95
- Each media file quires a thumbnail and these changes provide a capability to upload them along with media files.
- The thumbnail file is always required and has to be the format of already supported image formats
- The thumbnail should be uploaded as a part of "thumbnail" attachment in the request
- The regression tests added with this changeset will be claened up and moved to unit-tests (this is a dirty-but-working version!)
- The thumbnail always gets a name of the uploaded media file and keeps it's own extension.
- The thumbnails is accessible under the url present in the "thumbnail_url" reponse field
refs https://github.com/TryGhost/Team/issues/1190
- The assets were broken in Admin when the frontend and admin urls were different
- Fixed the issue by changing the `asset` helper to output absolute URLs when the frontend/admin urls are differents
refs 91efa4605c
- When the instance is booted without any redirects files configured it's not supposed to error but rather default to an "empty" [] redirects configuration.
- Ideally the logic shoudl not contain try/catch block at all and fail as soon as there's any error during the initialization. This wasn't changed at this time due to possible break of existing Ghost instances
refs refs https://linear.app/tryghost/issue/CORE-84/have-a-look-at-the-eggs-redirects-refactor-branch
- The tests needed to have a clean state with empty redirects file, which was previously ensured through "configUtils". Because configUtils don't play ball with the class initialization pattern this approach was chosen
- It's an end-to-end test with lots of logic and pobably would be enough to run against single API endpoint. Leaving it as is and to be improved in the future
refs https://linear.app/tryghost/issue/CORE-84/have-a-look-at-the-eggs-redirects-refactor-branch
- The problem this change is addressing is inability to override config values once the code is extracted into a class+DI pattern
- The work around is restarting the instance with the configuration testing expected behavior - in this case missing or existing types of redirects files
refs https://github.com/TryGhost/Members/commit/9e59f5a9
Since we have a DynamicRedirectManager for handling adding/removing
redirects at runtime, we no longer need the custom-redirects middleware.
The redirects service does however need an init method now to add the
custom redirects at Ghost boot, so it's been refactored into our Class &
DI pattern.
refs https://linear.app/tryghost/issue/CORE-121/create-a-video-storage-adapter
- This is an experimental implementation of video file upload support (audio is yet to follow)
- The storage adapter still needs more thinking as it's almost the same as the "LocalStorgeAdapter" that stores images.
- Also the output serializer skipped use of url utils in favor of inline implementatoin - this should almost certainly be it's own package
refs https://github.com/TryGhost/Team/issues/1178
The "up" migration that this util generates correctly throws if the
pre-requisite data cannot be found in the database. The "down" migration
however was incorrectly mirroring this behaviour of throwing - which
meant that it wasn't idempotent, as it does not require a permission or
role to existing if it wants to move relations between them.
no issue
The way GA flags were introduced means that they stop existing in the `'labs'` setting in the db and are instead forced to always return `true` when checking the flag in the labs service. However, Admin which uses the flags fetches them via the `/settings/` API endpoint which was only returning the raw labs setting db value meaning GA flags appeared to be disabled unless the flag had previously been enabled and no settings save had occured.
- updated the settings bread service to replace the labs setting value with the JSON stringified output of `labs.getAll()` which is the ultimate source-of-truth for a feature being enabled/disabled
- extracted `browse()` behaviour to an internal `_formatBrowse()` method so we can apply the same filtering/modification for output of `browse()` and `edit()`
Co-authored-by: Fabien O'Carroll <fabien@allou.is>
refs https://github.com/TryGhost/Team/issues/1115
This allows users to create Offers for Tier/Cadence pairs in order to
provide discounted subscriptions to Members! We have support for
percentage based discounts & fixed price discounts, either for the first
payment, all payments, or a number of monthly payments.
Offers also have a code, which can be used as an easy way to share them,
as visiting https://site.com/offer-code will automatically open Portal
with the Offer prepopulated.
closes https://github.com/TryGhost/Team/issues/1164
Themes can now define custom settings via their `package.json` file, and use them in templates via `@custom.{setting}`. Values for custom settings can be changed by site owners through a redesigned "Design settings" area in the admin interface.
Full announcement, documentation, and examples will be made available soon.
Co-authored-by:
- Sanne de Vries (@sanne-san)
- Thibaut Patel (@tpatel)
refs https://github.com/TryGhost/Team/issues/1175
We found the ETag header sent when serving the Admin template for /ghost/ was not changing between versions which after an upgrade could result in out of date cached content being served containing links to JS/CSS files that no longer existed.
The culprit is weak etags served by Node's `send` package, coupled with Admin template filesize not changing between versions and `npm pack` setting a fixed modification date for every file. See https://github.com/pillarjs/send/issues/176 for more details.
- updated the Admin app's controller to read the template and generate an md5 hash of the contents so we can serve a strong ETag header value when serving the `/ghost/` html
refs https://github.com/TryGhost/Team/issues/1163
We want to make the title for Offers optional, our nullable validation
means that we cannot store an empty string, so we must remove the NOT
NULL constraint from the column if we want to store either an empty
value or null.
There is a bug with editing columns in SQLite with `knex` which strips all
the indexes, so we have to manually add them afterwards.
- we're slowly trying to draw the lines between the backend and the frontend correctly
- these files deal only with serving the frontend so they should live there
- there are lots of mixed requires in these files, so having them in the right place makes that clear
refs https://linear.app/tryghost/issue/CORE-1/multiple-adapters-per-type
- There's a need to support multiple adapter variations per given adapter type (storage, sso, etc.)
- With the introduced changes we can specify a version of an adapter that should be fetched based on `:feature` postfix. For example:
`adapterManager.getAdapter('storage')` - would return the default adapter listed under "active" configuration
`adapterManager.getAdapter('storage:videos') - would return an adapter configured for videos *feature*
- Here's an example configuration for a custom video storage:
```
"storage": {
"active": "LocalFileStorage",
"videos": "ghost-storage-custom-video",
"ghost-storage-custom-video": {
"custom": "configHere"
}
}
```
- We were not requiring the full path to our fixture file, and therefore we were testing the fixtures + utility functions
- This updates the test to clearly require the exact files we are checking, except the routes.yaml where we can't
- Also updates the hash to be the correct hash for just the fixture content
closes https://github.com/TryGhost/Team/issues/1150
Our override of the base Bookshelf `insert` operation so that our own `formatOnWrite()` method is called on attributes was working on a false assumption that an `attrs` attribute is passed in as it is for the `update` operation. Instead Bookshelf's base update uses the `model.attributes` values to create an `attrs` object that is then passed through the usual `.format()` method meaning that our `insert` override was not actually doing anything.
- added a failing regression test for the `formatOnWrite()` override behaviour
- adjusted our insert/update overrides to set an internal `_isWriting` property on the model, then if that property is true our `.format()` override (which is called by Bookshelf on a generated `attrs` object during inserts) we manually call our `.formatOnWrite()` method
- updated both overrides even though `update` was working for consistency and less cognitive overhead for reasoning between two different approaches
no-issue
* Removed NOT_NULL constraint from stripe_coupon_id
When handling disconnecting from Stripe - we remove all Stripe data from
our database to ensure we do not have bad/invalid data stored. Removing
this constraint will allow us to set the value to NULL.
* Added created_at column to offer_redemptions
Offer Redemptions are not just a joining table, but an event. A created_at
date allows them to be ordered
Because this is in alpha it is simpler to just drop the tables and
re-add them, due to offer_redemptions depending on offers, we also drop
this table and re-add it.