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://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.
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
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%
- 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
- 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 ;)
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% 🚀
refs https://github.com/TryGhost/Ghost/issues/13380
- Now that i18n.t has been removed everywhere, we can cleanup the final usages
- Still TODO: merge the i18n logic into themeI18n, and get rid of shared/i18n entirely
refs https://github.com/TryGhost/Team/issues/1138
Portal offer urls use offer id to load offer details UI and stripe checkout in frontend. This endpoint allows portal to fetch offer details from offer id to create Portal UI with relevant details for potential members.
refs https://linear.app/tryghost/issue/CORE-103/decouple-internal-frontend-code-from-url-module
- By becoming a parameter in the routing bootstrap process URL is Service no longer a "require" inside the frontend controllers but rather becomes a part of the "internal API" of the bootstrapper. This is not the end form of it, rather a step closer to decouplint routing from the URL serivce.
- The bootstrap module needs a facelift to have cleaner distinction between init/start methods. This is left for another time
- The helper registration code is "framework" code and very specific
- At the moment the "theme engine" is full of lots of disparate theme related stuff
- I'm trying to make the frontend framework code clearer and also expand it to make it more useful
- The helper system now also exposes 3 methods allowing you to register a directory, a helper or an alias
- I've updated the codebase to use these both for our core helpers and for "apps"
refs https://linear.app/tryghost/issue/CORE-86/fix-failing-site-instance-when-redirects-file-is-invalid
refs 260a47da83
- Added validation logic to catch redirects files having invalid RegEx expressions when they are introduced into the system (on upload)
- This way the error happening in the refed commit would have not happened as the validator would not have passed it through
- Moved up the "Router" declaration in custom-redirects as it needs to happen before any other bit of logic has a chance to throw
refs: #13380
- This is part of the ongoing push to get rid of the deprecated i18n.t calls
- In this case, it highlights just how little work we've done on API errors - we should have a full list of action messages, but there's just 1 :(
- This is initial ground work to enable us to do a full error audit
- We want to prevent Ghost admin from ever showing any unhandled errors
- Additionally we want to ensure all handled errors are well worded & have context+help
refs https://linear.app/tryghost/issue/CORE-35/refactor-route-and-redirect-settings
refs 7528ec8c3b
- The way the custom redirects middleware was organized made it extremely hard to unit test it (had to stub the redirects service methods etc). With a new organization it's possible to provide needed redirects configs to the method which makes the actual redirects Router logic testable and the code less coupled with redirects services
- This was meant to be an attempt to extract more of the slow redirects regression tests, which failed. Instead found this weak spot that could be improved and gained:
- shaved 4s of time as two slow regression test cases are now gone
- there's now a base to build upon when getting more coverage for the custom redirects middleware
refs https://github.com/TryGhost/Team/issues/1070
- bumped `@tryghost/custom-theme-settings-service` for access to `.updateSettings()`
- added `PUT /custom_theme_settings` route that delegates to `customThemeSettingsService.updateSettings()` to perform the db and cache updates
- invalidates the cache in Ghost because a theme setting change will mean the front-end output will change
refs https://linear.app/tryghost/issue/CORE-35/refactor-route-and-redirect-settings
- Frontend is not meant to know about the underlying source of the "routes" configuration, so any reads/edits/validations are being moved into a backend service. This should also simplify the coupling of the backend with the frontend where the latter will get a JSON blob with all needed configuration during the boot
- Nother problem the "get" method had was hiding an underlying function it was doing - reading the file from the filesystem SYNCRONOUSLY. It might be a thing we need to do during the "web" app initialization, but there's no clear need to do this in a sync fassion during the bootup for example. Also having a more explicit name should help :)
refs https://linear.app/tryghost/issue/CORE-35/refactor-route-and-redirect-settings
- 'knowSettings' was based on a "configurable" array of settings that might be configured in Ghost. The multitude never happened! The only setting the frontend takes care of is routes.yaml file (redirects is also kind of a setting but is a separate concept for now).
- Having just one type of file to deal with allows to simplify implementation significantly, which helps before a big refactor
refs https://github.com/TryGhost/Team/issues/1070
- bumped `@tryghost/custom-theme-settings-service` to get access to `.listSettings()` method
- added GET `/api/canary/admin/theme_settings/` route behind `'customThemeSettings'` feature flag that uses the custom theme settings service to return settings resources that are a combination of the theme-provided definition and the saved value
refs https://github.com/TryGhost/Ghost/security/advisories/GHSA-65p7-pjj8-ggmr
This updates the signup/signin flow for members to no longer support the
email address change flow - which had missing authentication. It has
been replaced with a dedicated email change flow, and Portal has been
updated to use it.
refs https://github.com/TryGhost/Team/issues/946
This adds the initial bulk actions endpoint used for the members
filtering feature. The idea is to eventually move bulk destroy into this
endpoint to and provide a consistent interface for applying bulk actions
to members.
The @tryghost/members-api package has been bumped to include the new
bulkEdit method.
The sinon.restore in tests was moved to an afterEach so that stubs did
not effect other tests.
refs 9e2b21578a
Since the ref'd commit the labs middleware was moved to the shared labs module
and this require path no longer exists. This does not break anything as any module
still using this would error when reading the labs property