- This fits more closely, as this service is to so with rendering helpers and small parts
- Whereas we want to use "rendering" for things concerned with rendering pages
refs https://github.com/TryGhost/Team/issues/1469
- wires newsletter preferences for a member in Portal to view/edit real data
- allows members to control their subscription to multiple newsletters
refs https://github.com/TryGhost/Team/issues/1469
We have an after hook to update `sort_order` for pivot tables after update as base bookshelf plugin. Since new `members_newsletters` table doesn't has a `sort_order` column on it, this change disables the after hook for it to avoid errors.
refs https://github.com/TryGhost/Team/issues/1469
- allows Portal access to multiple newsletters on a site
- allows Portal to update member's newsletter subscription preference
refs https://github.com/TryGhost/Team/issues/1469
- updates member model to add relation to newsletter via pivot table
- updates member api serializer to include newsletter data
- updates tests
refs: https://github.com/TryGhost/Ghost/commit/11867ab43
- These checks live in the wrong place. They are mostly a frontend thing
- The only server place they were used was slack and that was fixed in 11867ab43
- Moving these to the frontend they fit neatly into the frontend data service
- This is the only piece of server code that relies on the schema.checks, the rest are all frontend
- IMO this code should actually check for the post properties that the slack message needs
- OR it should switch based on the event type
- either way there's no need to have a shared util for this simple use case
- especially becaue it's confusing the use case for it and creating cross-coupling between server and frontend
- Some of the helpers inside the routing service would be better suited to their own service
- These two helpers fetchData and entryLookup talk to the API to get data & so make a decent start for a data service
- The data service would be the single point of contact with the API for the frontend
- Doing this now cos I'm moving some files around ahead of deleting things for 5.0
- We had an incident where a migration file was misnamed.
- This is caused by using slimer with spaces rather than hyphens
- We didn't imagine this case when writing the regex for matching filenames
- However, now we know it, it's easy to tweak the regex to match this case
- This requires adding an override to the one badly named file
- Keeping overrides inside the file means the context of why a rule isn't firing is present inline when modifying a file
- This makes it easier to maintain files, at the cost of needing to search to find all overrides
refs 2fa3985d42
- Running tests with error logging set to "error" lever, produced a massive amounts of errors related to failed Stripe keys. Making it hard to look through the output.
- When Ghost is running in teste environment by default it is configured with an invalid Stripe key that looks like `sk_test***`. In this case the Members migrations runs creating requiest to Stripe, which fail.
refs https://github.com/TryGhost/Team/issues/1469
With multiple newsletters, members will now be able to subscribe to one or more newsletters on the site. Previously, the subscription to default newsletter for a member was controlled via a single boolean `subscribed` column on the member table.
This change allows mapping multiple newsletters to a member via new pivot table that stores relation between a member and newsletter.
- adds new `members_newsletters` pivot table
- update tests
- if we add a column with a foreign key reference, the `down` migration
will try to remove that column
- you can't remove a column without deleting the foreign key reference
first
- our migration utils didn't take that into account and there's nothing
in Knex to do this for us
- this commit deletes the foreign key before removing the column if we
have one referenced in the column spec
- also updates the code to pass the column spec into the util
refs 7172db74b0 (r70370252)
- The changes referenced above changed fixtures without taking "test fixtures" in "test/utils/fixtures/fixtures.json" into account. This fix is only cosmetical to unlutter the test output with logging level set to "error". Once the referenced comment is answered a proper fix should be applied here
- this commit removes the colons from the log messages to make each
line flow easier when you're reading it
- also removes a couple of superfluous words that aren't needed
refs https://github.com/TryGhost/Team/issues/449
- Once we deprecate site.lang use in favor of site.locale this helper will need inspection for potentially breaking change. Left a note to come back to it once it's time
refs https://github.com/TryGhost/Team/issues/1463
- Allow admins to perform all newsletter operations
- We can adjust and be more permissive in the future if needed
- Added the tests back as permissions are configured correctly now
refs TryGhost/Team#1458
refs TryGhost/Team#1459
refs TryGhost/Team#1372
- Added a new stats service, which is divided into several categories. Currently only the 'members' category for member related stats.
- When there are missing or corrupt members status events in the DB, the totals returned by the old member stats endpoint (`/members/stats/count`) were wrong. This is fixed in the new service by counting in reverse order and starting with the actual totals.
- New Stats API, with the new `/stats/members/count-history` endpoint.
- This new endpoint also returns the paid deltas -> dashboard 5.0 will show subscribed and canceled paid members for each day
- Includes tests for the new stats service and endpoint
refs https://github.com/TryGhost/Team/issues/1463
- This enables listing, creating and editing newsletters
- The tests are commented out as the permissions will be added in a follow-up commit
refs https://github.com/TryGhost/Toolbox/issues/213
- our `knex` dependency has been out of date for a while so my aim was
to bring it up to date
- this required also switching `sqlite3` to `@vscode/sqlite3` because
knex switched the default sqlite driver
- this commit also bumps knex-migrator and switches to a mock-knex fork
until Knex 1.0 support has been merged
- also updates an error message to handle a new code in SQLite
refs: https://github.com/TryGhost/Toolbox/issues/245
- The default behaviour of a serializer is to call a mapper for each object
- Instead of all the boilerplate code we had in the snippets serializer, all we need is a single mapper function
- Added tests for the mapper function as well
refs https://github.com/TryGhost/Team/issues/1433
- The `default` property stores whether a newsletter is set as default by the admin
- The `status` property stores whether a newsletter is archived or not
- The `recipient_filter` property is only storing whether a newsletter is "paid-only" or not for now, although it can be expanded to more specific filters in the future
- The `subscribe_on_signup` property stores whether a new member should be automatically signed up to the newsletter
- The `sort_order` property enables displaying the newsletter list in an order chosen by the admins
refs: https://github.com/TryGhost/Team/issues/1446
- These endpoints are unused, so they are safe to remove
- We're starting to remove as much unused & unnecessary code as possible to try to reduce the codebase and increase test coverage
refs: https://github.com/TryGhost/Toolbox/issues/245
refs: https://github.com/TryGhost/Ghost/commit/73f91a524
- we don't need this serializer because the default serializer will do the same thing
- commit 73f91a524 fixes the logic so that the default serializer is called as a fallback
even though the email_preview serialzier exists, as there's no matching method name
- sadly the route name here is wrong, it should be email_previews plural, but the response format is correct
to make this work we have to fix the docName and rename the serializer
refs: https://github.com/TryGhost/Toolbox/issues/245
- .all methods are fallback serializers not to be run as well as a custom serializer
- The default serializer is also a fallback
- The "All" file with before and after are global hooks that _always_ get run as well as other serializers
- There's a lot of room for further improvement here especially with naming but this logic makes more sense
for the usecases AND doesn't affect v2 & v3 etc. We can do another pass after 5.0
refs: https://github.com/TryGhost/Toolbox/issues/245
- There are several serializers which are "passthroughs" that return the response from the query
function as-is.
- The intention here is to make them all look consistent so they're easy to spot and understand what they do
refs: 0ef5a5c97a
- As per the previous commit, our mixed filename casing inadvertently resulted in a bug
- The casing in the codebase is meant to be kebab-case always, so fixing this everywhere that's relevant to the API whilst there's a good reason
refs: https://github.com/TryGhost/Toolbox/issues/245
refs: https://github.com/TryGhost/Team/issues/1360
- As a result of my changes in https://github.com/TryGhost/Ghost/commit/3bd4d098 the members connect endpoint had started returning JSON
- This is because the members connect endpoint relied on the old default behaviour of the serializer being to return no response, whereas now it does our default JSON response format
- I had written a tool to iterate over all endpoints and ensure that they all had explicit serializers before changing the default behaviour, but it missed this endpoint due to the snake case naming
- I have double checked and this was the only missed endpoint, the only other one was member_signin_urls.permissions but that was not a true endpoint and was removed in https://github.com/TryGhost/Ghost/commit/202696382
- Note: the snapshot file for this test was generated from running the test against https://github.com/TryGhost/Ghost/commit/e6b92aed9 - one commit before I added the new default behaviour.
- Without the new serializer this test fails on main
- With the new serialzier, this test passes again, showing the response format has gone back to what we expect
- This doesn't affect permissions, only permissions inside an endpoint config block does that
- Rather it creates an extra unused "endpoint" called member_signin_urls.permissions
- same as https://github.com/TryGhost/Ghost/commit/b53296c4d
refs https://github.com/TryGhost/Toolbox/issues/254
- it's useful for us to know how long it takes the theme service to
init, especially as it is dealing with a lot of user-provided files
outside of the Ghost codebase
refs https://ghost.slack.com/archives/C02G9E68C/p1647599592576139
refs https://ghost.slack.com/archives/C02G9E68C/p1647620250625909
Issue: `Cannot destructure property 'fromRegex' of 'this.redirectsredirectId]' as it is undefined.` is being thrown, only when running all tests.
Cause: duplicate redirects are added to a redirectManager, and not cleared correctly in the redirectManager, which throws an error when removing one of the duplicate redirects.
Because the same redirectManager is used, multiple event listeners are connected to the same redirectManager. So when the offer service has been initialised multiple times, multiple listeners are added, which create a redirect for every newly created offer... to the same redirectManager.
So there are three possible fixes for the same problem (would be best to fix them all):
- Create a new redirectManager every time the offer service is initialised
- Figure out a way to remove DomainEvents subscribers between tests
- Don't add the same redirect id multiple times to redirectIds in addRedirect from the express-dynamic-redirects package
This commit contains a fix for the first solution.
It also moved the offers service initialising before the frontend (to `initServicesForFrontend`)
With tiers going GA, this change brings a massive visual overhaul to Portal for almost all pages and flows, along with adding consistency between different multiple tier flows. It also overhauls the tests to match our new UI/UX for Portal.
refs: https://github.com/TryGhost/Toolbox/issues/245
- we don't need this serializer because the default serializer will call the authors mapper
- added an author mapper which is just an alias for users. I did this in a named file, not in index.js
- because we want to change the api framework to load files automatically without needing index files.
- makes sense to hold off that deeper change until we only have one api version else we have to change old APIs
refs: https://github.com/TryGhost/Toolbox/issues/245
- we don't need this serializer because the default serializer will call the tags mapper
- for now I've changed, rather than removed the tag serializer test as this shows default works the same!
refs: https://github.com/TryGhost/Toolbox/issues/245
- There's no need for a mapper or serializer as labels uses the default behaviour
- Added a full suite of tests, consolidating from regression and using the new framework to prove nothing is broken
- settings cache was appearing as untested because we use rewire!
- rewire was totally unnecessary in this case, so I removed it
- updated to 100% test coverage whilst there, including removing one unreachable branch
- commented some undesirable behaviour I found whilst trying to reach all branches
- I don't want to change the behaviour to return false correctly without having a reason beyond improving coverage
no issue
Prevents errors from being uploaded to Sentry when a 404 happens in Ghost Admin. At the moment, 404s in Ghost Admin create an ENOENT error in express' static library. Our generic 404 handler at the end will only intercept requests that don't have any errors in the context, so a simple middleware can strip out 404 errors just before we add in our own.
The Ghost-specific error that we attach to requests does not get uploaded to Sentry :)
refs: https://github.com/TryGhost/Toolbox/issues/245
- Added a serializer called default to the canary API
- Ideally, this would be part of the shared framework, but this would change v2/v3 and we're about to get rid of them
- Therefore, we change just canary for now, and we can refactor again later.
- Added wiring to handler that uses the default serializer, if there is a default, and isn't an explicit serializer for the endpoint
- Removed the invites serializer, so that one endpoint now uses the default
Note: previous commits have added explicit serializers to every endpoint, this is the first step towards paring
that back so that we have less serializers overall, not more!
refs: https://github.com/TryGhost/Toolbox/issues/245
- Offers didn't have a serializer because it's deliberately set at the API level
- With the upcoming refactor we want to have all the serializers defined explicitly
- This will allow us to change the default behaviour
- Tests were added to cover this endpoint in ...
refs: https://github.com/TryGhost/Toolbox/issues/245
- Upload, updateMembersEmail, validateMembersEmailUpdate & disconnectStripeConnectIntegration were all missing serializers
- Upload is an as-is response, same as download
- updateMembersEmail, validateMembersEmailUpdate & disconnectStripeConnectIntegration are all passthroughs with no response
- With the upcoming refactor we want to have all the serializers defined explicitly
- This will allow us to change the default behaviour
- Updated the file based tests to prove the body doesn't change
- Tests were added to cover updateMembersEmail, validateMembersEmailUpdate & disconnectStripeConnectIntegration in 68c1bc0285
refs: https://github.com/TryGhost/Toolbox/issues/245
- Session didn't have a serializer because it's deliberately a passthrough
- With the upcoming refactor we want to have all the serializers defined explicitly
- This will allow us to change the default behaviour
- Tests were added to cover this endpoint in 2cf7e00493
refs: https://github.com/TryGhost/Toolbox/issues/245
- sendTestEmail was missing a serializer because it's deliberately a passthrough
- With the upcoming refactor we want to have all the serializers defined explicitly
- This will allow us to change the default behaviour
- Updated the tests to prove the body doesn't change
refs: https://github.com/TryGhost/Toolbox/issues/245
- Slack didn't have a serializer because it's deliberately a passthrough
- With the upcoming refactor we want to have all the serializers defined explicitly
- This will allow us to change the default behaviour
- Tests already cover this endpoint
refs: https://github.com/TryGhost/Toolbox/issues/245
- The destroy endpoint was missing a serializer
- Instead of adding one, I've refactored to use an all method that's a passthrough
- Updated the tests to use the same pattern as others to make it clearer this is tested
refs: https://github.com/TryGhost/Toolbox/issues/245
- The destroy endpoint was missing a serializer
- As this serializer uses the same createSerializer pattern as members, I've copied the passthrough from members into here
- This ensures the behaviour will stay the same when the default behaviour changes
- Updated the tests to prove the body doesn't change
refs: https://github.com/TryGhost/Toolbox/issues/245
- This was the only endpoint in the members API that didn't have a serializer
- It just needs to be a simple passthrough, but we define it so we can change the default
refs: https://github.com/TryGhost/Toolbox/issues/245
- The destroy endpoint was missing a serializer
- Instead of adding one, we've refactored to use the standard structure for this serializer
- Updated the tests to prove the body doesn't change
refs: https://github.com/TryGhost/Toolbox/issues/245
- There was only a serializer in place for redirects.download.
- Upload was falling through, which means nothing happens by default atm
- We want to change this default, so I'm making sure all our routes have serializers declared and tests
- Updated the tests and checked the behaviour was the same before and after:
- We can't use our new framework here yet because it doesn't support uploads or downloads
- Instead, just add simple matching for the body of the responses
no issue
- Just a small refactor as it was becoming painful to change the version in three places while experimenting with gscan
- Also follows the "rule of 3"
refs https://github.com/TryGhost/Toolbox/issues/169
refs 7becf0a2b2
- The referenced commit has dropped existance of Content and Admin APIs under `/canary/` prefix, which made a breaking change and clients that are still relying on "canary" started to break.
- The `/canary/` prefix should be used up untill the introduction of Ghost v5, otherwise we run the risk of accidentally breaking API clients.
- we use this property in the code but it was missing from the messages
object
- this was causing an error in the `tpl` library so this commit adds the
correct message
no issue
- adds a separate activity feed screen with all member events
- can be filtered to show specific event types
- can be filtered by a specific member to show their full event feed
- updated member details screen to show all events instead of just email events
refs https://github.com/TryGhost/Team/issues/1141
- switched to the same member fetch method as used in `GET /member/:id/` so there's consistent data available when rendering the API responses
refs https://github.com/TryGhost/Team/issues/1302
- Added the `MemberCancelEvent` model to MembersApi
- Triggered when a subscription is canceled by an admin or by the member
- Updated shared dependencies
Co-authored-by: Simon Backx <simon@ghost.org>
- CSS was updated previously, but the minified version wasn't
- as a result the private site landing page was visually broken
- minified CSS is built as part of `grunt prod`, called during `grunt release`
refs c4470ff732
- labs flag was removed under the false assumption it was a client-side only flag but the `last_seen_at` property in API responses was also gated meaning the member details screen showed "Not seen yet" and the members list did not show the last seen date of all members when filtering
refs https://github.com/TryGhost/Team/issues/1367
Because we are passing through a different member object as the context
in the get helper, the content gating was not working correctly, as the
member was missing a status property, this adds the property which fixes
content gating.
- Added extra tests for get helper {{access}} property
- Added extra test for {{access}} property in next_post helper
- In the future we might want to update the tests so they test the whole request -> HBS context flow. Currently the has context is still stubbed manually.
closes https://github.com/TryGhost/Team/issues/1426
When fetching tiers using the content API, we incorrectly returned all tiers including archived ones unless the active:true filter is passed. Correct behaviour is to always hide archived tiers, so this filter should not be required.
- forces `active:true` filter for tiers content api browse
- updates test to check for archived test removal in tiers content api
refs: https://github.com/TryGhost/Toolbox/issues/245
- Ghost's API framework has a mixed up concept of what a serializer is. Mappers are true serializers! What we call serializers are little more than a small formatting step.
- This PR splits mappers into individual files and uses the endpoint's docname as the mapper name. This will help us to automate the calling of a mapper for an endpoint later.
- This is one tiny step in reworking the framework to need less code to make it work, and to have clearer concepts for how to do things.
As multiple tiers is now GA, we want to allow devs to be able to work with Tiers and offers via content/Admin API. This change -
- updates fixtures to add permissions to admin integration role for new sites
- adds migration to update existing sites to have correct permissions for role
- whitelists add/edit/read/browse on tiers and offers API for integrations
refs https://github.com/TryGhost/Toolbox/issues/240
- As gscan's canary is about to be aliased to upcoming v5 version current version of Ghost should be using an explicit v4 checks.
- These will change to v5 once Ghost is doing final preparations for v5 release (on the branch most likely)
- This doesn't affect permissions, only permissions inside an endpoint config block does that
- Rather it creates an extra unused "endpoint" called identities.permissions
refs https://github.com/TryGhost/Toolbox/issues/169
- Before releasing Ghost v5 we would like to move all canary-related URLs to a non-versioned format, which will become a default in v5.
- 'canary' is by definition unstable, so breaking any unprepared client explicitly using the canary is expected
- Removed the aliased /content/ and /admin/ apps from app.js because with updated configuration they become duplicates of 'canary' endpoints