closes https://github.com/TryGhost/Team/issues/952
- The `/email/` route will be a home for email only posts. We are adding the route preemptively to have the crowlers update their caches before the feature sees the light of The Internet
refs https://github.com/TryGhost/Team/issues/948
- The frontend route `/email/:uuid` is aliased to the preview as a temporary solution. It fulfills the premise of the email-only post anyway - not being accessible publicly and only shared through email.
- The tests for the new route are missing as adding them was way more problematic than I envisoned. They are in the works and will be added as a follow up commit next.
refs https://github.com/TryGhost/Team/issues/949
- When post is marked as "email-only" we can send it out to the selected audience when publishing without making the post publicly available
- The feature is available for experimentation behind "email only" alpha flag available in labs
refs https://github.com/TryGhost/Team/issues/949
- Initializing PostsService with almost identical parameters is burdensome, having a single factory method in create instances is far more maintainable
refs https://github.com/TryGhost/Team/issues/949
- It's relly hard to grasp what's going on in ifs with multiple conditions that are written down in a signle, gazzilion-line format. Having a nice column as way more readable
refs https://github.com/TryGhost/Team/issues/949
- The post model handling related to newsletter sending and email recipient filter logic were duplicating across v3/v4(canary) APIs and it made sense to extract it into a posts service.
- This will allow for a central place to handle about to land logic for email_only newsletter handling.
refs https://github.com/TryGhost/Team/issues/949
- The code is exactly the same in six (!) places. It's beyond unmaintainable to add another line to any of these place, which will be needed for `email_only` handling.
- The newly created posts service is a temporary, slightly better solution that complies with codebase's best practice of extracting new services using class with DI pattern
refs https://github.com/TryGhost/Team/issues/949
refs e64274bb45
- This refactor is needed to bring the code in line with the rest of pages API controllers
- Next step will extract shared code patterns into a separate module
refs https://github.com/TryGhost/Team/issues/949
refs e64274bb45
- This refactor is needed to bring the code in line with the rest of pages API controllers
- Next step will extract shared code patterns into a separate module
refs https://github.com/TryGhost/Team/issues/949
- This refactor is needed to bring the code in line with the rest of post API controllers
- Next step will extract shared code patterns into a separate module
https://github.com/TryGhost/Team/issues/893
- The assignment is not that obvious and might be confusing without wider context, which is why it warrants to have a clarifying comment. This became apparent during code review
refs https://github.com/TryGhost/framework/pull/19
The @tryghost/bookshelf-filter plugin no longer bundles hardcoded
relations and expansion definitions, instead leaving it up to the
library consumer to implement.
This PR adds the preexisting relations and expansions to the relevant
models, in order to preserve our existing filtering functionality.
refs https://github.com/TryGhost/Team/issues/560
refs 69b773d112
The endpoint `/members/api/session/` is used by Portal for fetching member session while setting up and redirecting to Stripe Checkout flow. The status code returned by API for logged out member is changed from 4xx Unauthorized to 204 No Content, which is consistent with the status code returned while fetching member data when logged out. This API is made just before initiating the checkout session, and is not noticable in most cases due to redirect to Stripe Checkout and got missed.
refs https://github.com/TryGhost/Team/issues/928
- applied same darkening of accent color in emails as we use in editor when there's insufficient contrast of accent color against a white background
refs https://github.com/TryGhost/Team/issues/928
- duplicated email template so email-cta changes can go into the labs version
- added `accentContrastColor` to template settings for using white/black depending on the accent color
- added `.gh-btn-accent` styles to the email template (email-cta card already uses those for the button)
refs https://github.com/TryGhost/Team/issues/912
- When the improt acceedes the threshold for the first time we need a way to notify configured escalationAddress to verify the instance owner's email address.
closes https://github.com/TryGhost/Team/issues/913
- Having a limit service rule triggered was a temporary hack to get a basic email blocking version working
- As the freeze value is now persisted in the DB it's possible to read and rely on it to throw an error straight from MEGA.
refs https://github.com/TryGhost/Team/issues/912
- Previous logic was a bit misleading because it prevented from reading the real threshold configured with an instance once the verified flag was present in the config.
- The reshuffle made here allows to check the freeze logic based on the threshold and then process the returned result accordingly instead of having hidden logic behind "importThreshold" config value
refs https://github.com/TryGhost/Team/issues/912
- The email freeze state has to be stored somewhere to make it through the instance restart and settings table is the best place for it.
refs https://github.com/TryGhost/Team/issues/912
- We need a place to persist the email freeze state between instance restarts - settings table record is the best place for it
refs https://github.com/TryGhost/Team/issues/927
- the `email-cta` card can be segmented so only free or paid members can see the content, it should be possible for authors to preview what that will look like in either case
refs https://github.com/TryGhost/Team/issues/912
- The membersApi variable can be in uninitialized state. It should be accessed through membersService getter to make sure it's always correctly referenced
refs https://github.com/TryGhost/Team/issues/935
The problem was incorrect operator precedence when multiple statements existed in the filter original filter when we transform it to enforce `subscribed:true` before sending.
- free only - subscribed:true+status:free - no issue
- paid only - subscribed:true+status:-free - no issue
- all - subscribed:true+status:-free,status:free - the ,status:free part is treated as a separate OR statement meaning the subscribed:true is not applied to it and free members that are unsubscribed will receive the email
- extracted the filter transform into a separate function so it can be unit tested
- updated the transform to use `()` for operator precedence, eg: `subscribed:true+(status:-free,status:free)`
- used transform function in `addEmail()` and `getEmailMemberRows()`
- fixed `sent/send` typo in error message
refs d60d348c88
- When the import triggers a background job the meta response should contain no data otherwise the client can mistake it for completed import
refs a7dd7bb64b
- The error was introduced in the refed commit. Object.assign method only works when the first parameter is an object otherwise it fails.
refs https://github.com/TryGhost/Team/issues/912
- Exposing a single method out of the service makes the API surface smaller - more readable.
- Additionlally having a wrapping method in service will be helpful for other triggers that are going to be executed in later iterations
refs https://github.com/TryGhost/Team/issues/907
The theme middleware makes several calls to the content api in order to
populate global theme data for use in templates. By adding this
middleware after the static theme files, we remove redundant calls.
refs https://github.com/TryGhost/Team/issues/916
- The constructor API should have as small of a surface as possible, there's no need to pass around whole ghostMailer instance
refs https://github.com/TryGhost/Team/issues/916
- The constructor API should have as small of a surface as possible, there's no need to pass around whole settingsCache instance
refs https://github.com/TryGhost/Team/issues/916
- The refactor was done follow the DI Constructor pattern with single options Object parameter
- It didn't make sense to have a "config" object inside of options object containing just one property
issue https://github.com/TryGhost/Team/issues/614
- The feature flag was called `oauthLogin` instead of simply `oauth` to avoid clashes in the frontend `feature` service as it is merging the config and labs properties.
refs https://github.com/TryGhost/Team/issues/916
- While investigating members importer related codebase this legacy module was spotted. It's not used anywhere and doesn't serve any particular purpose.
refs https://github.com/TryGhost/Team/issues/664
The new WellKnownController and middleware handles exposing a JSON Web
Key Set for us.
In order to serve the keys on /members/.well-known/jwks.json without a
trailing slash, we must mount the wellKnown middleware before the
frontend.
refs 2f1123d6ca
Usage of the raw Error class has been deprecated in favour of our own
errors, which are more descriptive and have built in HTTP status codes.
This also updates the same errors to use @tryghost/tpl for the error
messages, which is the new pattern we are following in order for us to
deprecate the i18n module.
no issue
- i18n is deprecated in favour of `tpl`
- normalized method syntax so `add` matches the rest of the controller's methods (fixed a complexity warning but was not the primary intention)
refs 2f1123d6ca
refs 6f1a3e1774
- As per refed commits, we are removing deprecated use of `new Error()` in the codebase
- Exposed few internal from commands module methods for easier testing, otherwise it was turning into neverending mocking show
refs https://github.com/TryGhost/Team/issues/696
The userAuth spam prevention logic is reused, but a new piece of
middleware has to be created so that we can use a custom lookup key to
conatin the member email.
We must also add json parsing middleware to the route so that the brute
middleware can read the email.
The express body-parser middleware handles multiple instances on the
same route, so this doesn't cause problems upstream.
https://github.com/expressjs/body-parser/blob/1.19.0/lib/types/json.js#L99-L103
closes https://github.com/TryGhost/Team/issues/743
Unlike tags, a label has a unique constraint on its `name`. So saving a new label on member with the same name as existing label fails with error due to unique constraint error.
- adds id for new label to match existing label if they are the same name, which avoids creating a new label
refs https://github.com/TryGhost/Team/issues/880
The aggregate for `paid_delta` was incorrect as it did not handle the
case where an event went from paid->comped or from comped->paid. This
resulted in an overcount for paid members.
refs https://github.com/TryGhost/Team/issues/860
- Slow unit tests cause longer waiting time to deliver code to main. Before this fix the test was taking a whooping 6s on average
- The main cause of the delay was a downstream's package (got) default retry logic that was taking up a lot of time bypassing the retry logic present in the default scheduler itself
refs https://github.com/TryGhost/Team/issues/756
When running the tests it was possible for this middleware to be
instantiated before the settings cache, resulting in an undefined
'session_secret' setting being passed. This would cause tests to fail.
Tracking this down proved difficult, so the fix was made here, by
instantiating the express-session middleware only once a request needs
to use it, we can be confident that Ghost has completely started.
refs 2f1123d6ca
refs 6f1a3e1774
- As per refed commits, we are removing deprecated use of `new Error()` in the codebase
- This bit cleans up the rest of `new Error()` usage in MEGA service
no issue
- Exposing internal methods out of the module is a non-standard practice. Adding `_` prefix allows to signal that this method is not for general use.
- When mega is refactored into a proper class this method will become exposed anyways
refs 2f1123d6ca
refs 6f1a3e1774
- As per refed commits, we are removing deprecated use of `new Error()` in the codebase
- This bit cleans up `new Error()` usage in MEGA service
refs 2f1123d6ca
refs 6f1a3e1774
- The use of new Error() has been deprecated. Refactoring the migration to use `createIrreversibleMigration` made most sense to have central error handling for migration which are not meant to be reverted.
no issue
- This mehod has an important `tableSpec` parameter which MUST be present when creating a new table migration. Having a description in form of the JSDoc somewhat helps this cause
- Next best improvement would be throwing an error if the parameter wasn't present, but that would require a bigger refactor backporting all usages of `addTable` method
refs https://github.com/TryGhost/Team/issues/841
When using our development tooling Ghost should always start, instead of
exiting with an error. This check for the WEBHOOK_SECRET env var was the
primary cause of Ghost erroring in development, so it's been switched
with a warning.
refs: f9a3f7d955
- The test for overriding a theme (uploading a theme with the same name as the currently active theme) doesn't test the right codepath
- It incorrectly assumes uploading the same theme twice results in an override, but this is only true for the active theme
- This change splits the override test out into it's own test, and only tests overriding by changing the active theme first
- Also fixed a minor comment type whilst here
refs https://github.com/TryGhost/action-deploy-theme/issues/45
- added missing `throw error` in the `setFromZip()` catch which was hiding the underlying error when a theme uploaded and saved successfully but other code had failed
- fixed incorrect method name `activator.activateFromOverride` -> `activator.activateFromAPIOverride`
refs https://github.com/TryGhost/action-deploy-theme/issues/45
- added missing `throw error` in the `setFromZip()` catch which was hiding the underlying error when a theme uploaded and saved successfully but other code had failed
- fixed incorrect method name `activator.activateFromOverride` -> `activator.activateFromAPIOverride`
no issue
- In the current iteration of the gated email project, we are returning a null segment instead of returning the correct list of segmented users as a temporary measure. The expectation was to clear all segmented cards and it's now the case.
- This isn't really a "service" - it's a set of utilities for working with labs flags
- It's also required all over the place, and doesn't require anything that isn't shared
- Therefore, it should live in shared
- Replaced requiring SafeString all the way from the theme engine, with using express-hbs directly
- This is quite a big require, just for the safe string function, but without this we have to tie labs to our theme layer
- Also removed i18n and updated the jsdoc for enabledHelper
- The labs service can be moved to shared now!
- This isn't really a "service" - it's a set of utilities for working with labs flags
- It's also required all over the place, and doesn't require anything that isn't shared
- Therefore, it should live in shared
- Replaced requiring SafeString all the way from the theme engine, with using express-hbs directly
- This is quite a big require, just for the safe string function, but without this we have to tie labs to our theme layer
- Also removed i18n and updated the jsdoc for enabledHelper
- The labs service can be moved to shared now!
- This stops the mounting of the admin and frontend from being buried deep in express initialisation
- Instead it's explicit, which makes two things almost possible:
1. we can potentially boot the frontend or backend independently
2. we can pass services and settings loaded during boot into the frontend
- This needs more work, but we can start to group all the frontend code together
- Meanwhile we also need to rip apart the routing and url services to decouple the frontend from the backend fully
- BABY STEPS!
closes https://github.com/TryGhost/Team/issues/737
- without an explicit `width: auto` on images Gmail on Android will make not make the image responsive, instead it was keeping the 1200px intrinsic width of the image and shrinking other content around it to match