Renamed verification threshold parameter

refs https://github.com/TryGhost/Toolbox/issues/387

- There will three distinct verification limits soon. To keep the naming clear "configThreshold" would be too generic/confusing to use.
- Introduced jsdoc descriptions for the "source" parameter, which will be corelating with each new config parameter ("apiTriggerThreshold", "importTriggerThreshold", "adminTriggerThreshold", etc.). This should give a better visibility into parameters we are dealing in this area.
This commit is contained in:
Naz 2022-08-25 09:41:19 +08:00
parent 243aa9c834
commit 8892a60948
6 changed files with 20 additions and 15 deletions

View File

@ -105,7 +105,7 @@ module.exports = {
}); });
verificationTrigger = new VerificationTrigger({ verificationTrigger = new VerificationTrigger({
configThreshold: _.get(config.get('hostSettings'), 'emailVerification.importThreshold'), apiTriggerThreshold: _.get(config.get('hostSettings'), 'emailVerification.importThreshold'),
isVerified: () => config.get('hostSettings:emailVerification:verified') === true, isVerified: () => config.get('hostSettings:emailVerification:verified') === true,
isVerificationRequired: () => settingsCache.get('email_verification_required') === true, isVerificationRequired: () => settingsCache.get('email_verification_required') === true,
sendVerificationEmail: ({subject, message, amountImported}) => { sendVerificationEmail: ({subject, message, amountImported}) => {

View File

@ -1,7 +1,7 @@
/** /**
* @typedef {object} MemberCreatedEventData * @typedef {object} MemberCreatedEventData
* @prop {string} memberId * @prop {string} memberId
* @prop {string} source * @prop {'import' | 'system' | 'api' | 'admin' | 'member'} source
* @prop {import('@tryghost/member-attribution/lib/attribution').Attribution} [attribution] Attribution * @prop {import('@tryghost/member-attribution/lib/attribution').Attribution} [attribution] Attribution
*/ */

View File

@ -1,7 +1,7 @@
/** /**
* @typedef {object} MemberSubscribeEventData * @typedef {object} MemberSubscribeEventData
* @prop {string} memberId * @prop {string} memberId
* @prop {string} source * @prop {'import' | 'system' | 'api' | 'admin' | 'member'} source
*/ */
module.exports = class MemberSubscribeEvent { module.exports = class MemberSubscribeEvent {

View File

@ -98,6 +98,11 @@ module.exports = class MemberRepository {
return subscription.plan && subscription.plan.nickname && subscription.plan.nickname.toLowerCase() === 'complimentary'; return subscription.plan && subscription.plan.nickname && subscription.plan.nickname.toLowerCase() === 'complimentary';
} }
/**
* Maps the framework context to members_*.source table record value
* @param {Object} context instance of ghost framework context object
* @returns {'import' | 'system' | 'api' | 'admin' | 'member'}
*/
_resolveContextSource(context) { _resolveContextSource(context) {
let source; let source;

View File

@ -13,7 +13,7 @@ class VerificationTrigger {
/** /**
* *
* @param {object} deps * @param {object} deps
* @param {number} deps.configThreshold Threshold for triggering verification as defined in config * @param {number} deps.apiTriggerThreshold Threshold for triggering verification as defined in config
* @param {() => boolean} deps.isVerified Check Ghost config to see if we are already verified * @param {() => boolean} deps.isVerified Check Ghost config to see if we are already verified
* @param {() => boolean} deps.isVerificationRequired Check Ghost settings to see whether verification has been requested * @param {() => boolean} deps.isVerificationRequired Check Ghost settings to see whether verification has been requested
* @param {(content: {subject: string, message: string, amountImported: number}) => {}} deps.sendVerificationEmail Sends an email to the escalation address to confirm that customer needs to be verified * @param {(content: {subject: string, message: string, amountImported: number}) => {}} deps.sendVerificationEmail Sends an email to the escalation address to confirm that customer needs to be verified
@ -22,7 +22,7 @@ class VerificationTrigger {
* @param {any} deps.eventRepository For querying events * @param {any} deps.eventRepository For querying events
*/ */
constructor({ constructor({
configThreshold, apiTriggerThreshold,
isVerified, isVerified,
isVerificationRequired, isVerificationRequired,
sendVerificationEmail, sendVerificationEmail,
@ -30,7 +30,7 @@ class VerificationTrigger {
Settings, Settings,
eventRepository eventRepository
}) { }) {
this._configThreshold = configThreshold; this._apiTriggerThreshold = apiTriggerThreshold;
this._isVerified = isVerified; this._isVerified = isVerified;
this._isVerificationRequired = isVerificationRequired; this._isVerificationRequired = isVerificationRequired;
this._sendVerificationEmail = sendVerificationEmail; this._sendVerificationEmail = sendVerificationEmail;
@ -44,7 +44,7 @@ class VerificationTrigger {
async _handleMemberSubscribeEvent(event) { async _handleMemberSubscribeEvent(event) {
const source = event.data?.source; const source = event.data?.source;
const sourceThreshold = this._configThreshold; const sourceThreshold = this._apiTriggerThreshold;
if (source === 'api' && isFinite(sourceThreshold)) { if (source === 'api' && isFinite(sourceThreshold)) {
const createdAt = new Date(); const createdAt = new Date();
@ -65,7 +65,7 @@ class VerificationTrigger {
} }
async getImportThreshold() { async getImportThreshold() {
const volumeThreshold = this._configThreshold; const volumeThreshold = this._apiTriggerThreshold;
if (isFinite(volumeThreshold)) { if (isFinite(volumeThreshold)) {
const membersTotal = await this._membersStats.getTotalMembers(); const membersTotal = await this._membersStats.getTotalMembers();
return Math.max(membersTotal, volumeThreshold); return Math.max(membersTotal, volumeThreshold);
@ -75,7 +75,7 @@ class VerificationTrigger {
} }
async testImportThreshold() { async testImportThreshold() {
if (!isFinite(this._configThreshold)) { if (!isFinite(this._apiTriggerThreshold)) {
// Infinite threshold, quick path // Infinite threshold, quick path
return; return;
} }
@ -91,7 +91,7 @@ class VerificationTrigger {
// Import threshold is either the total number of members (discounting any created by imports in // Import threshold is either the total number of members (discounting any created by imports in
// the last 30 days) or the threshold defined in config, whichever is greater. // the last 30 days) or the threshold defined in config, whichever is greater.
const importThreshold = Math.max(membersTotal - events.meta.pagination.total, this._configThreshold); const importThreshold = Math.max(membersTotal - events.meta.pagination.total, this._apiTriggerThreshold);
if (isFinite(importThreshold) && events.meta.pagination.total > importThreshold) { if (isFinite(importThreshold) && events.meta.pagination.total > importThreshold) {
await this.startVerificationProcess({ await this.startVerificationProcess({
amountImported: events.meta.pagination.total, amountImported: events.meta.pagination.total,

View File

@ -9,7 +9,7 @@ const {MemberSubscribeEvent} = require('@tryghost/member-events');
describe('Import threshold', function () { describe('Import threshold', function () {
it('Creates a threshold based on config', async function () { it('Creates a threshold based on config', async function () {
const trigger = new VerificationTrigger({ const trigger = new VerificationTrigger({
configThreshold: 2, apiTriggerThreshold: 2,
membersStats: { membersStats: {
getTotalMembers: async () => 1 getTotalMembers: async () => 1
} }
@ -21,7 +21,7 @@ describe('Import threshold', function () {
it('Increases the import threshold to the number of members', async function () { it('Increases the import threshold to the number of members', async function () {
const trigger = new VerificationTrigger({ const trigger = new VerificationTrigger({
configThreshold: 2, apiTriggerThreshold: 2,
membersStats: { membersStats: {
getTotalMembers: async () => 3 getTotalMembers: async () => 3
} }
@ -34,7 +34,7 @@ describe('Import threshold', function () {
it('Does not check members count when config threshold is infinite', async function () { it('Does not check members count when config threshold is infinite', async function () {
const membersStub = sinon.stub().resolves(null); const membersStub = sinon.stub().resolves(null);
const trigger = new VerificationTrigger({ const trigger = new VerificationTrigger({
configThreshold: Infinity, apiTriggerThreshold: Infinity,
memberStats: { memberStats: {
getTotalMembers: membersStub getTotalMembers: membersStub
} }
@ -203,7 +203,7 @@ describe('Email verification flow', function () {
}); });
const trigger = new VerificationTrigger({ const trigger = new VerificationTrigger({
configThreshold: 2, apiTriggerThreshold: 2,
Settings: { Settings: {
edit: settingsStub edit: settingsStub
}, },
@ -246,7 +246,7 @@ describe('Email verification flow', function () {
}); });
const trigger = new VerificationTrigger({ const trigger = new VerificationTrigger({
configThreshold: Infinity, apiTriggerThreshold: Infinity,
Settings: { Settings: {
edit: settingsStub edit: settingsStub
}, },