From 5622a29fc1cdb4795c9599a54b19703e4f1eeed1 Mon Sep 17 00:00:00 2001 From: Steve Larson <9larsons@gmail.com> Date: Mon, 26 Aug 2024 17:51:57 -0500 Subject: [PATCH 1/3] Fixed Portal honeypot field (#20825) ref INC-97 ref https://github.com/TryGhost/Ghost/issues/20767 - finishes wiring up the honeypot fied - updates state handing to properly set the value - maintains honeypot field across page changes within portal There isn't a single previous commit to point to here since they didn't get squashed. We added a honeypot field to help mitigate bot signup activity. It's hidden, and if filled out, we can anticipate it's a bot. Right now this just logs to Ghost while we collect data. --- .../src/components/pages/NewsletterSelectionPage.js | 4 ++-- apps/portal/src/components/pages/OfferPage.js | 9 ++++++--- apps/portal/src/components/pages/SigninPage.js | 6 +++--- apps/portal/src/components/pages/SignupPage.js | 8 ++++---- apps/portal/src/utils/api.js | 3 ++- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/apps/portal/src/components/pages/NewsletterSelectionPage.js b/apps/portal/src/components/pages/NewsletterSelectionPage.js index 067c9aa2e5..de49bf2441 100644 --- a/apps/portal/src/components/pages/NewsletterSelectionPage.js +++ b/apps/portal/src/components/pages/NewsletterSelectionPage.js @@ -109,8 +109,8 @@ export default function NewsletterSelectionPage({pageData, onBack}) { id: d.id }; }); - const {name, email, plan, offerId} = pageData; - onAction('signup', {name, email, plan, newsletters, offerId}); + const {name, email, plan, phonenumber, offerId} = pageData; + onAction('signup', {name, email, plan, phonenumber, newsletters, offerId}); }} brandColor={brandColor} label={label} diff --git a/apps/portal/src/components/pages/OfferPage.js b/apps/portal/src/components/pages/OfferPage.js index 357ca718c1..25534673a1 100644 --- a/apps/portal/src/components/pages/OfferPage.js +++ b/apps/portal/src/components/pages/OfferPage.js @@ -282,12 +282,15 @@ export default class OfferPage extends React.Component { }; }, () => { const {onAction} = this.context; - const {name, email, errors} = this.state; + const {name, email, phonenumber, errors} = this.state; const hasFormErrors = (errors && Object.values(errors).filter(d => !!d).length > 0); if (!hasFormErrors) { const signupData = { - name, email, plan: price?.id, - offerId: offer?.id + name, + email, + plan: price?.id, + offerId: offer?.id, + phonenumber }; if (hasMultipleNewsletters({site})) { this.setState({ diff --git a/apps/portal/src/components/pages/SigninPage.js b/apps/portal/src/components/pages/SigninPage.js index b5b73c1025..2905910b7d 100644 --- a/apps/portal/src/components/pages/SigninPage.js +++ b/apps/portal/src/components/pages/SigninPage.js @@ -34,11 +34,11 @@ export default class SigninPage extends React.Component { errors: ValidateInputForm({fields: this.getInputFields({state})}) }; }, async () => { - const {email, honeypot, errors} = this.state; + const {email, phonenumber, errors} = this.state; const {redirect} = this.context.pageData ?? {}; const hasFormErrors = (errors && Object.values(errors).filter(d => !!d).length > 0); if (!hasFormErrors) { - this.context.onAction('signin', {email, honeypot, redirect}); + this.context.onAction('signin', {email, phonenumber, redirect}); } }); } @@ -74,7 +74,7 @@ export default class SigninPage extends React.Component { }, { type: 'text', - value: state.honeypot, + value: state.phonenumber, placeholder: '+1 (123) 456-7890', // Doesn't need translation, hidden field label: 'Phone number', diff --git a/apps/portal/src/components/pages/SignupPage.js b/apps/portal/src/components/pages/SignupPage.js index 9509ac7ae4..47183d068e 100644 --- a/apps/portal/src/components/pages/SignupPage.js +++ b/apps/portal/src/components/pages/SignupPage.js @@ -397,20 +397,20 @@ class SignupPage extends React.Component { }; }, () => { const {site, onAction} = this.context; - const {name, email, plan, honeypot, errors} = this.state; + const {name, email, plan, phonenumber, errors} = this.state; const hasFormErrors = (errors && Object.values(errors).filter(d => !!d).length > 0); if (!hasFormErrors) { if (hasMultipleNewsletters({site})) { this.setState({ showNewsletterSelection: true, - pageData: {name, email, plan}, + pageData: {name, email, plan, phonenumber}, errors: {} }); } else { this.setState({ errors: {} }); - onAction('signup', {name, email, honeypot, plan}); + onAction('signup', {name, email, phonenumber, plan}); } } }); @@ -487,7 +487,7 @@ class SignupPage extends React.Component { }, { type: 'text', - value: state.honeypot, + value: state.phonenumber, placeholder: '+1 (123) 456-7890', // Doesn't need translation, hidden field label: 'Phone number', diff --git a/apps/portal/src/utils/api.js b/apps/portal/src/utils/api.js index 773df5c9ed..9d8f32e082 100644 --- a/apps/portal/src/utils/api.js +++ b/apps/portal/src/utils/api.js @@ -258,7 +258,7 @@ function setupGhostApi({siteUrl = window.location.origin, apiUrl, apiKey}) { } }, - async sendMagicLink({email, emailType, labels, name, oldEmail, newsletters, redirect, integrityToken, customUrlHistory, autoRedirect = true}) { + async sendMagicLink({email, emailType, labels, name, oldEmail, newsletters, redirect, integrityToken, phonenumber, customUrlHistory, autoRedirect = true}) { const url = endpointFor({type: 'members', resource: 'send-magic-link'}); const body = { name, @@ -270,6 +270,7 @@ function setupGhostApi({siteUrl = window.location.origin, apiUrl, apiKey}) { requestSrc: 'portal', redirect, integrityToken, + honeypot: phonenumber, // we don't actually use a phone #, this is from a hidden field to prevent bot activity autoRedirect }; const urlHistory = customUrlHistory ?? getUrlHistory(); From 2df2c7f12005cda8d24c0a812fb7143b6534bf11 Mon Sep 17 00:00:00 2001 From: Steve Larson <9larsons@gmail.com> Date: Mon, 26 Aug 2024 18:06:27 -0500 Subject: [PATCH 2/3] Bumped Portal (#20826) ref https://github.com/TryGhost/Ghost/issues/20767 --- apps/portal/package.json | 2 +- ghost/core/core/shared/config/defaults.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/portal/package.json b/apps/portal/package.json index 99ae1813a2..089804480f 100644 --- a/apps/portal/package.json +++ b/apps/portal/package.json @@ -1,6 +1,6 @@ { "name": "@tryghost/portal", - "version": "2.39.0", + "version": "2.40.0", "license": "MIT", "repository": { "type": "git", diff --git a/ghost/core/core/shared/config/defaults.json b/ghost/core/core/shared/config/defaults.json index cbbe2c3142..0830ae3c1a 100644 --- a/ghost/core/core/shared/config/defaults.json +++ b/ghost/core/core/shared/config/defaults.json @@ -182,7 +182,7 @@ }, "portal": { "url": "https://cdn.jsdelivr.net/ghost/portal@~{version}/umd/portal.min.js", - "version": "2.39" + "version": "2.40" }, "sodoSearch": { "url": "https://cdn.jsdelivr.net/ghost/sodo-search@~{version}/umd/sodo-search.min.js", From 46e9b204796cc247f55f45f6d383f54feab24ee2 Mon Sep 17 00:00:00 2001 From: Ghost CI <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 23:37:13 +0000 Subject: [PATCH 3/3] v5.90.1 --- ghost/admin/package.json | 2 +- ghost/core/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ghost/admin/package.json b/ghost/admin/package.json index 9796e4bb78..7370eff1eb 100644 --- a/ghost/admin/package.json +++ b/ghost/admin/package.json @@ -1,6 +1,6 @@ { "name": "ghost-admin", - "version": "5.90.0", + "version": "5.90.1", "description": "Ember.js admin client for Ghost", "author": "Ghost Foundation", "homepage": "http://ghost.org", diff --git a/ghost/core/package.json b/ghost/core/package.json index 687181ceec..654ca5091a 100644 --- a/ghost/core/package.json +++ b/ghost/core/package.json @@ -1,6 +1,6 @@ { "name": "ghost", - "version": "5.90.0", + "version": "5.90.1", "description": "The professional publishing platform", "author": "Ghost Foundation", "homepage": "https://ghost.org",