Commit Graph

9619 Commits

Author SHA1 Message Date
Daniel Lockyer
6d9ee79ad8 Updated Admin to v4.20.2 2021-10-25 08:19:06 +01:00
Daniel Lockyer
85911658b3 Updated Admin to v4.20.1 2021-10-22 20:08:55 +01:00
Kevin Ansfield
a485509a2f
🐛 Fixed GA labs flags not appearing enabled in settings API (#13681)
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>
2021-10-22 19:59:13 +01:00
Daniel Lockyer
0e844989f1 Updated Admin to v4.20.0 2021-10-22 17:19:47 +01:00
Fabien O'Carroll
f3bb6b43a5 Added Offers feature to Ghost
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.
2021-10-22 17:55:34 +02:00
Fabien O'Carroll
696d8e3c49 Added 404 handling for edit Offer
no-issue

This was also missing as part of the Offers API.
2021-10-22 16:16:39 +02:00
Kevin Ansfield
a6982d5606
Added ability for themes to define custom settings (#13661)
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)
2021-10-22 15:02:16 +01:00
Kevin Ansfield
0c6cd37679 Fixed missing space between authors in emails
no issue

- author line was appearing as "Author One,Author Two,..." with no space
- fixed the generation of `post.authors` when serializing a post before it's rendered for email
2021-10-22 14:41:15 +01:00
Daniel Lockyer
e834904125
Fixed verification threshold when set to 0
no issue

- if the verification threshold is 0, `_.get(..)` becomes falsy so we
  fallback to Infinity
- this is not correct - we only want to default to Infinity if the value
  is not set
- this commit explicitly compares the config value to `undefined` and sets
  the fallback accordingly
2021-10-22 15:33:59 +02:00
Kevin Ansfield
d7fbf94d91
Fixed ETag header for admin templates not changing between versions (#13680)
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
2021-10-22 14:25:58 +01:00
Fabien O'Carroll
363eb94aee Handled 404 for Offer not found
no-issue

This was missing handling! We need to throw a NotFoundError so we
return with the correct response.
2021-10-22 14:22:33 +02:00
Fabien 'egg' O'Carroll
d962f0e18e
Removed NOT NULL constraint from portal_title (#13659)
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.
2021-10-22 14:14:49 +02:00
Daniel Lockyer
ed6a8dca76 Inlined package requires to save boot time and memory
no issue

- following on from f4fb0fcbaa,
  this commit moves around some package requires in Ghost
- these are often niche packages that do something in a subsystem of
  Ghost, and are not necessarily be needed to boot the application
- these packages use non-negligible CPU and memory when they are
  required, so it makes sense to lazy-require them
- the concern here is that we obscure the code too much by moving
  random requires further into code, but the changes are small and the
  improvements big
- this commit bring the boot time since 4.19.0 down ~31% and initial
  memory usage down by a total of ~12%
2021-10-22 09:57:59 +02:00
Hannah Wolfe
2d0b5c872f
Renamed frontend/web/app to site
- This leaves us room to bring the frontend app in as app.js
2021-10-21 19:54:50 +01:00
Hannah Wolfe
faea2da596
Moved server/web/site to frontend/web
- 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
2021-10-21 19:28:18 +01:00
Fabien O'Carroll
8c9b4d18bf Fixed error when enabling Offers via labs
no-issue

The listOffers method requires an options object. This was missed during
the update.
2021-10-21 20:05:42 +02:00
Hannah Wolfe
2777093c76
Refactored model init to be implicit
- no more need to explictly add a model file to be loaded!
- this makes building Ghost just the tiniest smidge easier
2021-10-21 17:01:26 +01:00
Hannah Wolfe
99fde5154f
Fixed dependency on the order of models
- this has been a niggle for ages, we shouldn't need to care what order our models are loaded in
- this is stopping us from having a built-in model loader and "frameworkizing" models
2021-10-21 16:57:36 +01:00
Kevin Ansfield
1708f0c3a4 Fixed custom theme settings not being available when expected
closes https://github.com/TryGhost/Team/issues/1172

Custom theme settings sync and cache population had been left to complete in the background as it wasn't essential for it to be complete for the front-end to start. However that was causing problems for the API where theme activation and custom theme settings list requests happen very close together, with the latter often not containing the theme settings data when it is expected to.

- changed `activationBridge.*` methods to `async` so they can `await` the completion of custom theme settings sync before activating a theme
2021-10-21 15:02:52 +01:00
Fabien O'Carroll
39160fc794 Passed Offer model to MembersAPI
refs https://github.com/TryGhost/Team/issues/1166

The MembersAPI needs access to the Offer model so that we can remove all
the Stripe related data when Stripe is disconnected.
2021-10-21 15:39:26 +02:00
Fabien O'Carroll
03d4561a5f Added relation between Member & OfferRedemption
refs https://github.com/TryGhost/Team/issues/1135

This will allow us to fetch the OfferRedemptions for a Member so that we
can display them on the Member details page.
2021-10-21 15:39:26 +02:00
Iuri Mendes
7debc28832
Removed "The team at X" from member emails (#13615)
closes: https://github.com/TryGhost/Ghost/issues/13613

- The language "The team at X" didn't suit all Ghost users. The language is more appropriate without it.
2021-10-21 13:58:34 +01:00
Hannah Wolfe
a1ad9f2870
Reworked init migrations to use async/await (#13635)
- use async/await and fat arrow syntax
- makes it easier to refactor later as "this" context is then reliable
2021-10-21 11:19:59 +01:00
Naz
07afb08875 Made storage calls related to images use "images" feature
refs https://linear.app/tryghost/issue/CORE-1/multiple-adapters-per-type

- Having this preemptive change allows to separate implementation of "image" storage from future usecases like "videos", "audios" etc. Even if the "image" adapter is not configured the default behavior will fallback to use the "active" storage adapter. If there's a need to handle "images" differently through a custom apapter that'll work out of the box ;)
2021-10-21 20:22:45 +13:00
Naz
f890d8d4cd Enabled passing through a feature name to utilize with a storage adapter
refs https://linear.app/tryghost/issue/CORE-1/multiple-adapters-per-type

- When the storage is requested the caller can now specify a "feature" they want to use the storage for. For example there could be different configurations for "images" or "vidoes" storages and the caller would not necessarily have to know about the details of how the feature is implemented.
2021-10-21 20:22:45 +13:00
Naz
98c27b5555 Added multiple adapters capability to adapter manager
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"
    }
}
```
2021-10-21 20:22:45 +13:00
Naz
e90c4217e5 Added a doc to adapter service coinfig mapper 2021-10-21 20:22:45 +13:00
Hannah Wolfe
360f7490dd
Refactored fixture utils scout style
- This is a minor refactor to reorder functions, use async/await & fat arrows
- It will make the coming bigger refactor slightly easier to read :D
- This should not make any functional changes
2021-10-20 19:54:14 +01:00
Kevin Ansfield
256f16a01f
🐛 Fixed URLs not being correctly transformed during insert operations (#13618)
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
2021-10-20 15:22:46 +01:00
Kevin Ansfield
59a6f040d2 Fixed custom theme settings being clobbered with duplicate-named themes
refs https://github.com/TryGhost/Team/issues/1149

Ghost allows different themes to have the same `name` value in `package.json` but gives them a custom name based on the zip file used to upload it. The custom theme settings service however was always using the package.json name meaning that when syncing a theme with a duplicate name it was overwriting the settings for all other themes.

- bumped `@tryghost/custom-theme-settings-service` which changes the `.activateTheme()` signature to accept a theme name as the first argument
- updated our calls to `.activateTheme()` to pass Ghost's known theme name as the first argument so we're always syncing with the correct `theme` field value in the `custom_theme_settings` table
2021-10-20 13:25:02 +01:00
Fabien 'egg' O'Carroll
4e326123d3
Updated Offers related tables (#13609)
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.
2021-10-20 14:22:37 +02:00
Daniel Lockyer
1fd980ee9b Set global Luxon timezone override to UTC
refs https://linear.app/tryghost/issue/CORE-113/start-off-luxon-refactor

- we're planning on switching to Luxon for our date/timezone library,
  eventually replacing `moment` and `moment-timezone`
- the first step is to set the global timezone override to UTC, which is
  done in `core/server/overrides.js`
- also adds a test to ensure we're setting the timezone correctly
- this was mostly pulled from https://moment.github.io/luxon/#/zones?id=changing-the-default-zone
2021-10-20 09:19:29 +02:00
Naz
393280b6ae Reworked LocalFileStore methods to use async syntax
refs https://linear.app/tryghost/issue/CORE-1/multiple-adapters-per-type

- While digging around this area refactored the code to use more readable async/await syntax instead of chaining then's
- Dropped unneeded "catch" block in save method as all it was doing was rethrowing an error with out additional handling
2021-10-20 10:29:46 +04:00
Naz
eb261120fa Clened up routing module API from unused exports
refs https://linear.app/tryghost/issue/CORE-104/decouple-frontend-routing-events-from-urlserver-events

- CollectionRouter and TaxonomyRouter getters were exposed for no good reason. The less we expose the cleaner it is to understand possible dependencies the mocule creates
2021-10-19 07:29:09 +13:00
Naz
51b78211c5 Renamed bootstrap to routerManager
refs https://linear.app/tryghost/issue/CORE-104/decouple-frontend-routing-events-from-urlserver-events

- A follow up rename after bootstrap module was transformed into class
2021-10-19 07:29:09 +13:00
Naz
979474a8cc Refactored bootstrap module into RouterManager class
refs https://linear.app/tryghost/issue/CORE-104/decouple-frontend-routing-events-from-urlserver-events

- The "bootstrap" didn't give enough credit to everything this module was doing - it's responsible for managing correct initialization and reinitialization of the frontend Routes as well as passing router creation information back to the frontend's URL service
- The refactor is done in two steps - the "bootstrap.js" will be renamed in the follow-up commit to have a clean history of how the file evolved
2021-10-19 07:29:09 +13:00
Naz
098891ee9a Removed bootstrap module dependency from frontend routers
refs https://linear.app/tryghost/issue/CORE-104/decouple-frontend-routing-events-from-urlserver-events

- "routerCreated" call was causing a need to create a dependency on the frontend Router level which didn't fit nicely with the refactor of the bootstrap into a class, it's also makes way more sense having it as an independent parameter instead of a call on a module (makes testing way more readable too!)
2021-10-19 07:29:09 +13:00
Naz
edd7b09909 Fixed typos 2021-10-19 07:29:09 +13:00
Naz
6e075c78bf Moved URL service to backend
refs https://linear.app/tryghost/issue/CORE-104/decouple-frontend-routing-events-from-urlserver-events

- URL module is part of the backend heavily dependent on the model and fits perfectly here. Frontend should get the data it needs by passing a URL manager instance to it
2021-10-19 07:29:09 +13:00
Naz
4034194ad3 Added comment about leftover emited event in the routes module
refs https://linear.app/tryghost/issue/CORE-104/decouple-frontend-routing-events-from-urlserver-events

- The note says it all, adding a memo for future us when we get around cleaning up all events
2021-10-19 07:29:09 +13:00
Naz
ced6119fc1 Moved route checking logic closer to the origin
refs https://linear.app/tryghost/issue/CORE-104/decouple-frontend-routing-events-from-urlserver-events

- The URL Service should not be filled with preventative logic and know about internal methods of the routers (e.g. getPermalinks). Because it's only called through a single place the logic can now live in the routing package and not leak outside it
2021-10-19 07:29:09 +13:00
Naz
048b1102ad Removed EventEmitter inheritance in frontend routers
refs https://linear.app/tryghost/issue/CORE-104/decouple-frontend-routing-events-from-urlserver-events

- Now that routers don't emit any events there's no need to extend EventEmitter in the router's base class
- Less inheritance the lighter the runtime and the cleaner the code!
2021-10-19 07:29:09 +13:00
Naz
18344a16e2 Removed event chain caused by settings date update
refs https://linear.app/tryghost/issue/CORE-104/decouple-frontend-routing-events-from-urlserver-events

- The 'settings.timezone.edited' event triggers a roundtrip chain of calls in the frontend routing to the url services. It was all handled by event listeners and handler that clearly don't belong there.
- Extracted event realted listeners/handlers into methods and moved most of the logic to the "bootstrap" module, which soon is going to become a "RoutesManger"
- The result of this refactor - no more events going back and forth between frontend routing and the backend!
2021-10-19 07:29:09 +13:00
Naz
597ec51afb Removed 'router.created' event emmision from forntend routers
refs https://linear.app/tryghost/issue/CORE-104/decouple-frontend-routing-events-from-urlserver-events

- The 'router.created' event should eventually be killed. For now the aim is to create a clear communication pathway between frontend's routing module and the URL service (similar to the frontend bridge concept on the "server" side)
2021-10-19 07:29:09 +13:00
Daniel Lockyer
f9f0fb34f2
Merged v4.19.1 into main
v4.19.1
2021-10-18 15:10:22 +02:00
Daniel Lockyer
c78ebabb83 Updated Admin to v4.19.1 2021-10-18 14:09:17 +01:00
Hannah Wolfe
ae33c89707
Moved public folder to frontend
- The files in the public folder are all specific to the frontend:
  - ghost.css / ghost.min.css contains styles for default templates like unsubscribe, private and error
  - favicon is the default for the frontend
  - robots.txt is the default robots.txt for the frontend
  - sitemap.xsl is the stylesheet for the sitemap
- Therefore, they should live in the frontend!
2021-10-16 19:27:34 +01:00
Hannah Wolfe
17e4d89a79
Removed unused public assets
refs: a482c547ae

- This image hasn't been used for a very long time!
2021-10-16 13:58:29 +01:00
Hannah Wolfe
7280f82722
Moved core/shared/i18n to theme-engine/i18n
- core/shared/i18n is no longer used. Remove it to prevent temptation!
- this class needs merging with the one in themes, but for now just co-locate them as that's quicker and easier
2021-10-15 20:25:56 +01:00
Daniel Lockyer
f4fb0fcbaa Improved Ghost boot time and memory usage by lazy loading routes
no issue

- right now, we mount all API endpoints (v2, v3 and canary), alongside some
  other routes, when Ghost is booting. This is wasteful because we don't
  necessarily need any of the endpoints to get Ghost up and running
- even when Admin is used, it uses `canary` so `v2` and `v3` sit in memory
- the better approach here is to lazy load these endpoints, so they only
  get mounted when needed
- this commit adds the `lazyUse` function into our Express lib,
  which takes a mount path and a module function to execute down the
  line. This gets passed to the wonderful `express-lazy-router` lib which
  detects when we're calling an unmounted module and will mount it for
  us
- from local testing, this speeds up boot time by about 18% and reduces
  initial memory usage by about 6% 🚀
2021-10-15 17:52:07 +02:00