fixes https://github.com/TryGhost/Ghost/issues/14508
This change requires the frontend to send an explicit `emailType` when sending a magic link. We default to `subscribe` (`signin` for invite only sites) for now to remain compatible with the existing behaviour.
**Problem:**
When a member tries to login and that member doesn't exist, we created a new member in the past.
- This caused the creation of duplicate accounts when members were guessing the email address they used.
- This caused the creation of new accounts when using an old impersonation token, login link or email change link that was sent before member deletion.
**Fixed:**
- Trying to login with an email address that doesn't exist will throw an error now.
- Added new and separate rate limiting to login (to prevent user enumeration). This rate limiting has a higher default limit of 8. I think it needs a higher default limit (because it is rate limited on every call instead of per email address. And it should be configurable independent from administrator rate limiting. It also needs a lower lifetime value because it is never reset.
- Updated error responses in the `sendMagicLink` endpoint to use the default error encoding middleware.
- The type (`signin`, `signup`, `updateEmail` or `subscribe`) is now stored in the magic link. This is used to prevent signups with a sign in token.
**Notes:**
- Between tests, we truncate the database, but this is not enough for the rate limits to be truly reset. I had to add a method to the spam prevention service to reset all the instances between tests. Not resetting them caused random failures because every login in every test was hitting those spam prevention middlewares and somehow left a trace of that in those instances (even when the brute table is reset). Maybe those instances were doing some in memory caching.
refs https://github.com/TryGhost/Toolbox/issues/426
- with the existing `ship` command, it publishes to npm before pushing
to GitHub
- I fear we're likely to run into a scenario where the HEAD of `main` is
behind, so the git push fails, and then rebasing the HEAD will break
the tags that we created
- in this scenario, I think it's better to hard reset back, git pull and
then try again
- in that case, we need to publish to npm after GitHub
- this commit should implement that
refs https://github.com/TryGhost/Toolbox/issues/426
- now Portal is in the monorepo, the dev script doesn't need to wipe the
console output nor print instructions as that should be handled with
setting environment variables
- these changes were needed ahead of the upcoming bump to react-scripts,
which bumps eslint to v8, and therefore we can update
eslint-plugin-ghost, which introduces some new linting rules
- we added attribution data from localstorage to api requests made via Portal UI, but was missed for requests directly from theme via data-attributes
- includes url history data for free or paid signups via theme to mark correct attribution
closes https://github.com/TryGhost/Team/issues/1034
- pressing esc to dismiss popup didn't work for signup page as it was focused on input field
- allows esc to dismiss popup if the focused input field is empty