refs https://github.com/TryGhost/Team/issues/1055
We use the models defined in Ghost as our database connection to store
the analytic events. So we must pass this down to the Members module so
that we can store the events
refs https://github.com/TryGhost/Team/issues/873
The @tryghost/members-api module needs access to this model in order to
create events when members access to products are updated.
refs https://github.com/TryGhost/Team/issues/958
- The module contains a service class and not an api index as index.js file should. This rename also fixes an ESLint warning around index.js file being too complicated.
- The serivice should ideally be extracted into the member repository in the future iteration
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/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
- The membersApi variable can be in uninitialized state. It should be accessed through membersService getter to make sure it's always correctly referenced
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 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/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
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 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.
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.
- 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
- 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
- This is a precursor to trying to split apart into:
- model events + webhooks system which makes sense
- frontend events which should be independent or removed
- maybe some concept of a settings manager that we can use in various places to bind logic 🤔
- other usages of events that should be refactored to not use events
no refs
- adds `price` data on subscription from related `stripe_price` on updating a member via frontend
- removes inconsistency between `GET` and `PUT` data for logged in member on a site
- This is part of the quest to separate the frontend and server & get rid of all the places where there are cross-requires
- At the moment the settings cache is one big shared cache used by the frontend and server liberally
- This change doesn't really solve the fundamental problems, as we still depend on events, and requires from inside frontend
- However it allows us to control the misuse slightly better by getting rid of restricted requires and turning on that eslint ruleset
refs https://github.com/TryGhost/Team/issues/765
This supercedes the `complimentary_plan` flag, as it is more precise
because it determines _which_ product(s) a member has access to. Because
of this, if the `products` column is present the `complimentary_plan`
column is not used.
refs https://github.com/TryGhost/Team/issues/765
As part of the multiple products feature, we're not longer using Stripe
subscriptions to denote Complimentary access, instead we're linking
members directly to products. Here we update the importer to follow
suit, so long as the flag is enabled.
no issue
The only pieces of Ghost-Ignition used in Ghost were debug and
logging. Both of these modules have been superceded by the Framework
monorepo, and all usages of Ignition have now been removed, replaced
with @tryghost/debug and @tryghost/logging.
no refs
Monthly/yearly price values on a product can be `null` when stripe is not connected, this change handles the prices passed to Portal settings to ignore null prices in the array.
refs https://github.com/TryGhost/Team/issues/718
The ids for default prices for a product is now stored directly on product model instead of on global settings. This change updates
- the products data sent to Portal to use list of products with their active monthly/yearly prices, as well as
- the prices data sent to Portal to use the prices of default(first) product
refs https://github.com/TryGhost/Team/issues/598
refs https://github.com/TryGhost/Ghost/commit/5cdf910e
As part of the changes to disallow sites with starting up without https when they are connected to stripe, the conditional missed the check for stripe connection. As a result we were erroring in boot sequence for all sites starting without https irrespective if they are connected to Stripe or not which is incorrect. This fixes the `init` check for members service to only error for non-https sites if they are connected to Stripe.
refs https://github.com/TryGhost/Team/issues/598
We now have several pre-conditions related to members which determine
whether or not Ghost is allowed to start. Rather than burying this
within the members-api module, we have now surfaced them to an init
method which can be called during the boot sequence of Ghost. This will
allow us to exit early and explicitly.
no-issue
Our linter now requires that files named index.js have less than 50
lines, so this renames the index.js file to service.js and reexports
service.js from index.js so that linting will pass.
no refs
Filters active prices in Portal settings to only contain the selected prices by site owner in new monthly/yearly price id settings, ignoring all other prices for now.
closes https://github.com/TryGhost/Team/issues/560
closes https://github.com/TryGhost/Ghost/issues/12870
The endpoint `/members/api/member/` is used by Portal for fetching member details on site load to setup different flows. The response from this endpoint for logged out member has now changed from 401 Unauthorized to 204 No Content.
Ghost API was previously returning 401 Unauthorized error for logged-out member as this seemed to be technically correct response for unauthorized access to membership features. This resulted in a lot of confusion for end users where visible 401 errors on console were perceived as errors in the script as well as caught by loggers as erroneous traffic. Also for an end user, in the context of visiting a website - the user themselves is not trying to gain access to anything so this becomes cause for more confusion.
After internal discussion, the endpoint - [SITE_URL]/members/api/member- now returns 204 No Content instead of 401 for logged out member, denoting server was able to process the request but did not find any associated member. This should avoid any unwanted error logging on Portal load on a site, as well as make Portal functioning more transparent for a site.
no-issue
When importing Members it is possible to have both the
complimentary_plan and the stripe_customer_id columns set, this can
result in unusual outcomes, for example when importing a customer with a
zero-amount subscription, they would end up with two "comped"
subscriptions, and there would be two "comped" prices in the database.
As we are deprecating the use of "comped" in favour of creating a
subscription with a specific price, we're updating the import to prefer
`stripe_customer_id` column, only using the `complimentary_plan` column
when it is the only of the two columns passed.
refs https://github.com/TryGhost/Team/issues/581
closes https://github.com/TryGhost/Team/issues/582
Emails can now be sent to members with specific associated labels or products by specifying an NQL string. We want to bring the same members segment feature to content by allowing `visibility` to be an NQL filter string on top of the `public/members/paid` special-case strings.
As an example it's possible to set `posts.visibility` to `label:vip` to make a post available only to those members with the `vip` label.
- removed enum validations for `visibility` so it now accepts any string or `null`
- bumped `@tryghost/admin-api-schema` for API-level validation changes
- added nql validation to API input validators by running the visibility query against the members model
- added transform of NQL to special-case visibility values when saving post model
- ensures there's a single way of representing "members" and "paid" where NQL gives multiple ways of representing the same segment
- useful for keeping theme-level checks such as `{{#has visibility="paid"}}` working as expected
- updated content-gating to parse nql from post's visibility and use it to query the currently logged in member to see if there's a match
- bumped @tryghost/members-api to include label and product data when loading member
refs https://github.com/TryGhost/Team/issues/637
With custom products it's possible to change the name and description of any price. This assumes that people would want to change the same properties of a Free membership, and wires up the values for free membership price settings to Portal site settings API for Portal UI
refs https://github.com/TryGhost/Team/issues/586
We are no longer using the `stripe_plans` setting, instead we are using
the `stripe_prices` database table. However, we must keep the setting as
the migration from the setting to the database is not done as a standard
migration, but in code. This means our code has to still read and pass
the setting because we will never know if the migration in code has run
yet.
The `portal_plans` setting has been updated to only include 'free' by
default, because the setting must include id's now rather than names.
refs https://github.com/TryGhost/Team/issues/665
Portal only needs to work with active prices(not archived), this change filters prices sent to Portal to only include active prices
refs https://github.com/TryGhost/Team/issues/637
refs 75169b705b
With custom prices, Portal now needs to show all available custom prices in the UI as well as product's name and description in the Portal UI. This change adds product information to member site settings for Portal UI.
refs https://github.com/TryGhost/Team/issues/637
With custom prices, Portal now needs to show all available custom prices in the UI instead of just `monthly` and `yearly` prices. This change adds a list of all custom prices to Portal site settings for the default product which Portal will use to show the available prices in UI.
Note: As part of cleanup, the stripe price ids will be removed from the prices list.
Also:
- Fixes product name in serialised subscriptions
- Adds `type` value in serialised price object
refs 829e8ed010
- i18n is used everywhere but only requires shared or external packages, therefore it's a good candidate for living in shared
- this reduces invalid requires across frontend and server, and lets us use it everywhere until we come up with a better option
- Having these as destructured from the same package is hindering refactoring now
- Events should really only ever be used server-side
- i18n should be a shared module for now so it can be used everywhere until we figure out something better
- Having them seperate also allows us to lint them properly
refs https://github.com/TryGhost/Team/issues/637
refs https://github.com/TryGhost/Team/issues/591
We need to run migrations which will update the `portal_plans` setting
to use id's rather than names. This migration relies on the
`stripe_prices` table being complete populated. The migration to
populate the `stripe_prices` table was not added as a "normal"
migration because it needs to access the Stripe API over the network.
Any migrations that rely on this are unable to be run in a "normal"
migration as that cannot be sure that the database is in the correct
state.
The `portal_plans` setting migration is therefore run in code, and needs
access to the Settings model in order to modify the database.
refs https://github.com/TryGhost/Team/issues/579
The new signup access setting allows site owner to set the type of access level allowed for a member which Portal needs to handle
refs https://github.com/TryGhost/Team/issues/579
`members_signup_access = 'invite'` now forces invite-only mode so both free and paid setups both use the `'all'` setting. To ensure we're properly allowing/disabling free (self signup) signups in the members API we need to update `allowSelfSignup()` to take additional settings into account.
- `true` when Stripe is not connected. There are no paid plans available in this configuration so free signup is always enabled. To disable free signup on a site with no Stripe setup the members signup access should be set to `invite` or `none`.
- `true` when Stripe is configured and free plan is enabled in portal, without it Members API would not send magic link emails to signup requests
- `false` in all other situations such as invite-only and members-disabled signup access modes, or when the free plan has been disabled in portal configuration
refs c873899e49
- as of `bson-objectid` v2.0.0, this library exports the function
to generate an ObjectID directly, and then you need to use `.toHexString()`
to get the 24 character hex string - 6696f27d82
- this commit removes all uses of `.generate()` and replaces with this
change
refs https://github.com/TryGhost/Team/issues/579
Currently the members signup setting is explicitly yes/no to allowing free members signup, with the implication that when set to "no" members is still active but members have to be created via Stripe or the admin API.
This change renames the setting and changes its type to allow more than a binary option.
- migration to create/update the new setting based on the old value
- free signup = "all", no free signup = "invite"; matches the current UI for this setting
- rename setting everywhere it's used/tested against
- modify `getAllowSelfSignup()` used to configure members packages to only return `true` when the new setting is set to `'all'` to match behaviour to the older setting
- update importer to rename the setting when importing from an older Ghost version
refs https://github.com/TryGhost/Team/issues/586
- Passes new Product, Stripe Price and Stripe Product models to members API service
- Allows members service to populate the tables for existing plans and products
refs https://github.com/TryGhost/Team/issues/397
The default newsletter/support email address for a site is currently setup as noreply@DOMAIN , which means for a custom domain setup with www the email address becomes noreply@www.somesite.com which is not the expected behavior normally. This removes the `www` subdomain if present for those email addresses, but doesn't change any other subdomain
refs https://github.com/TryGhost/Team/issues/536
From 4.0, we ensure and require that accent colour is always set. This change removes hardcoded accent color fallbacks to avoid confusion as well as cause accidental fallback that is undesired causing themes to look different
closes https://github.com/TryGhost/Team/issues/570
When site owner/admin updates their newsletter/support email address from settings, they receive an email with confirmation link which on success takes them to Ghost Admin on email settings screen with a toast about success. Since the path for email settings in Ghost Admin changed in v4, the fix updates the redirect link to new Admin settings URL.
no issue
Comped members were not able to view paid-member content because content gating was only looking for `member.status === 'paid'` which doesn't take into consideration members on a "complimentary" plan.
- added front-end acceptance tests for member access to posts
- updated content-gating check to take comped members into consideration
refs: https://github.com/TryGhost/Team/issues/510
- The current member limit was implemented as a member-specific concept
- The new limit service is much more generic, here we are swapping old for new
- The updated concept here is blocking all publishing, not just email sending, when a site is over its member limit
- To determine that we are publishing a post, we must be in the model layer. The code has been moved to the permissible function which makes sense as this is a permissions error that we are throwing
- I've left the extra check for email retries in, in case there is some loophole here (but we may wish to change it)
refs https://github.com/TryGhost/Team/issues/510
- When the host config was introduced it was incorrectly introduced as host_settings instead of hostSettings
- All other Ghost config uses camelCase, so changing this now before it becomes a problem
- Note: Also removed some rogue return awaits that don't make sense. It's not possible to hit that case, but cleaning up anyway
refs https://github.com/TryGhost/Team/issues/513
- Bumping version as this is now the latest stable API.
- The change might cause this particular side effect (acceptable for major version): if a member requests a login URL when the instance is on 3.x version and site owner upgrades do 4.x before member authenticates through login link, the login will fail and the member will have to request a new login URL.
refs https://github.com/TryGhost/Team/issues/498
Requests to fetch the data of the logged in member made without a
session cookie were responsing with 400 Bad Request. This was incorrect
and always should have been a 401 Unauthorized.
refs https://github.com/TryGhost/Team/issues/498
This was filling up logs with less than useful information - for every
single request made by a non-member to the frontend. Be gone!
refs https://github.com/TryGhost/Ghost/issues/12602
As part of the member events, we added a third status of 'comped'.
Members with a status of 'comped' should still be considered paid, so
this fixes the definition of the paid flag to take that into account.
no-issue
This removes all references to the members labs setting, any code that was run conditionally behind this flag now runs unconditionally.
* Removed usage of Members labs flag
* Removed tests for Members disabled
* Added dynamic keypair generation for when setting is missing
no refs
- Updates member model serializer to directly set subscriptions on member object instead of `stripe.subscriptions`
- Updates all references to members subscriptions from nested `stripe.subscriptions` to `subscriptions`
- Updates v3 API serializer to still use `stripe.subscriptions`
- Updates tests
no-issue
* Removed support for paid param from v3 & canary API
* Updated active subscription checks to use status flag
* Updated MEGA to use status filter over paid flag
* Removed support for paid option at model level
* Installed @tryghost/members-api@1.0.0-rc.0
* Updated members fixtures
no issue
We added `portal-action` and `requestSrc` in 3.x to allow Portal to handle notifications only for auth actions trigged while using it directly, so that existing themes are not affected in any way. Going forward in 4.0, we don't want to have any special handling in backend for Portal but instead expect themes to handle any Portal specific behavior directly.
- Removes setting of `portal-action` for auth actions like signup
- Removes `requestSrc` being passed through to determine portal actions