mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-27 22:49:56 -05:00
✨ Added /members/validate
ednpoint to Admin API
no issue - This endpoint is meant to be used for validation of imported members - Main function at the moment is to validate if stripe_customer_id present in the dataset exists in connected Stripe account
This commit is contained in:
parent
11a686d734
commit
589d826afd
6 changed files with 90 additions and 8 deletions
|
@ -219,7 +219,7 @@ const members = {
|
||||||
const isStripeLinkingError = error.message && error.message.match(/customer|plan|subscription|Stripe account/g);
|
const isStripeLinkingError = error.message && error.message.match(/customer|plan|subscription|Stripe account/g);
|
||||||
if (model && isStripeLinkingError) {
|
if (model && isStripeLinkingError) {
|
||||||
if (error.message.indexOf('customer') && error.code === 'resource_missing') {
|
if (error.message.indexOf('customer') && error.code === 'resource_missing') {
|
||||||
error.message = `Member not imported, ${error.message}`;
|
error.message = `Member not imported. ${error.message}`;
|
||||||
error.context = i18n.t('errors.api.members.stripeCustomerNotFound.context');
|
error.context = i18n.t('errors.api.members.stripeCustomerNotFound.context');
|
||||||
error.help = i18n.t('errors.api.members.stripeCustomerNotFound.help');
|
error.help = i18n.t('errors.api.members.stripeCustomerNotFound.help');
|
||||||
}
|
}
|
||||||
|
@ -344,6 +344,42 @@ const members = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
validateImport: {
|
||||||
|
permissions: {
|
||||||
|
method: 'add'
|
||||||
|
},
|
||||||
|
headers: {},
|
||||||
|
async query(frame) {
|
||||||
|
const importedMembers = frame.data.members;
|
||||||
|
|
||||||
|
await Promise.map(importedMembers, (async (entry) => {
|
||||||
|
if (entry.stripe_customer_id) {
|
||||||
|
if (!membersService.config.isStripeConnected()) {
|
||||||
|
throw new errors.ValidationError({
|
||||||
|
message: i18n.t('errors.api.members.stripeNotConnected.message', {
|
||||||
|
id: entry.stripe_customer_id
|
||||||
|
}),
|
||||||
|
context: i18n.t('errors.api.members.stripeNotConnected.context'),
|
||||||
|
help: i18n.t('errors.api.members.stripeNotConnected.help')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await membersService.api.members.getStripeCustomer(entry.stripe_customer_id);
|
||||||
|
} catch (error) {
|
||||||
|
throw new errors.ValidationError({
|
||||||
|
message: `Member not imported. ${error.message}`,
|
||||||
|
context: i18n.t('errors.api.members.stripeCustomerNotFound.context'),
|
||||||
|
help: i18n.t('errors.api.members.stripeCustomerNotFound.help')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
importCSV: {
|
importCSV: {
|
||||||
statusCode: 201,
|
statusCode: 201,
|
||||||
permissions: {
|
permissions: {
|
||||||
|
|
|
@ -45,10 +45,10 @@ module.exports = {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
exportCSV(models, apiConfig, frame) {
|
exportCSV(data, apiConfig, frame) {
|
||||||
debug('exportCSV');
|
debug('exportCSV');
|
||||||
|
|
||||||
const members = models.members.map((member) => {
|
const members = data.members.map((member) => {
|
||||||
member = mapper.mapMember(member, frame);
|
member = mapper.mapMember(member, frame);
|
||||||
let stripeCustomerId;
|
let stripeCustomerId;
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,7 @@ module.exports = function apiRoutes() {
|
||||||
|
|
||||||
router.get('/members/stats', shared.middlewares.labs.members, mw.authAdminApi, http(apiCanary.members.stats));
|
router.get('/members/stats', shared.middlewares.labs.members, mw.authAdminApi, http(apiCanary.members.stats));
|
||||||
|
|
||||||
|
router.post('/members/validate', shared.middlewares.labs.members, mw.authAdminApi, http(apiCanary.members.validateImport));
|
||||||
router.get('/members/csv', shared.middlewares.labs.members, mw.authAdminApi, http(apiCanary.members.exportCSV));
|
router.get('/members/csv', shared.middlewares.labs.members, mw.authAdminApi, http(apiCanary.members.exportCSV));
|
||||||
router.post('/members/csv',
|
router.post('/members/csv',
|
||||||
shared.middlewares.labs.members,
|
shared.middlewares.labs.members,
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
"@tryghost/kg-markdown-html-renderer": "2.0.1",
|
"@tryghost/kg-markdown-html-renderer": "2.0.1",
|
||||||
"@tryghost/kg-mobiledoc-html-renderer": "3.0.1",
|
"@tryghost/kg-mobiledoc-html-renderer": "3.0.1",
|
||||||
"@tryghost/magic-link": "^0.4.8",
|
"@tryghost/magic-link": "^0.4.8",
|
||||||
"@tryghost/members-api": "0.20.1",
|
"@tryghost/members-api": "0.21.0",
|
||||||
"@tryghost/members-ssr": "0.8.1",
|
"@tryghost/members-ssr": "0.8.1",
|
||||||
"@tryghost/mw-session-from-token": "0.1.4",
|
"@tryghost/mw-session-from-token": "0.1.4",
|
||||||
"@tryghost/session-service": "0.1.4",
|
"@tryghost/session-service": "0.1.4",
|
||||||
|
|
|
@ -239,6 +239,51 @@ describe('Members API', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Can validate import data', function () {
|
||||||
|
const member = {
|
||||||
|
name: 'test',
|
||||||
|
email: 'memberTestAdd@test.com'
|
||||||
|
};
|
||||||
|
|
||||||
|
return request
|
||||||
|
.post(localUtils.API.getApiQuery(`members/validate`))
|
||||||
|
.send({members: [member]})
|
||||||
|
.set('Origin', config.get('url'))
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||||
|
.expect(200)
|
||||||
|
.then((res) => {
|
||||||
|
should.not.exist(res.headers['x-cache-invalidate']);
|
||||||
|
const jsonResponse = res.body;
|
||||||
|
should.exist(jsonResponse);
|
||||||
|
should.not.exist(jsonResponse.members);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Fails to validate import data when stripe_customer_id is present but Stripe is not connected', function () {
|
||||||
|
const member = {
|
||||||
|
name: 'test',
|
||||||
|
email: 'memberTestAdd@test.com',
|
||||||
|
stripe_customer_id: 'cus_XXXXX'
|
||||||
|
};
|
||||||
|
|
||||||
|
return request
|
||||||
|
.post(localUtils.API.getApiQuery(`members/validate`))
|
||||||
|
.send({members: [member]})
|
||||||
|
.set('Origin', config.get('url'))
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||||
|
.expect(422)
|
||||||
|
.then((res) => {
|
||||||
|
should.not.exist(res.headers['x-cache-invalidate']);
|
||||||
|
const jsonResponse = res.body;
|
||||||
|
should.exist(jsonResponse);
|
||||||
|
should.exist(jsonResponse.errors);
|
||||||
|
jsonResponse.errors[0].message.should.match(/Member not imported/i);
|
||||||
|
jsonResponse.errors[0].context.should.match(/no Stripe account connected/i);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('Can export CSV', function () {
|
it('Can export CSV', function () {
|
||||||
return request
|
return request
|
||||||
.get(localUtils.API.getApiQuery(`members/csv/`))
|
.get(localUtils.API.getApiQuery(`members/csv/`))
|
||||||
|
|
|
@ -496,10 +496,10 @@
|
||||||
jsonwebtoken "^8.5.1"
|
jsonwebtoken "^8.5.1"
|
||||||
lodash "^4.17.15"
|
lodash "^4.17.15"
|
||||||
|
|
||||||
"@tryghost/members-api@0.20.1":
|
"@tryghost/members-api@0.21.0":
|
||||||
version "0.20.1"
|
version "0.21.0"
|
||||||
resolved "https://registry.npmjs.org/@tryghost/members-api/-/members-api-0.20.1.tgz#a4477eb77ac9657a0a238148cf95ac0056d3607a"
|
resolved "https://registry.yarnpkg.com/@tryghost/members-api/-/members-api-0.21.0.tgz#778a747e02de888118ef937861493a7d135f5784"
|
||||||
integrity sha512-IDZGHwKutebCAQq0Oya+sdxFsFw79X/NWg+MfEULJCtLvW09bFdtBc1RWyXrXiPBkFbnKu+zOkhIg1I5Lx48Nw==
|
integrity sha512-0NJmgHxINsTiWfiyV4jCMcWgLp42Fy5lAdHQxLHgcYnmk2Xggqrs0sKl2kfQ/JNMZwej7gorXyd0Xirf8gtBdQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@tryghost/magic-link" "^0.4.9"
|
"@tryghost/magic-link" "^0.4.9"
|
||||||
bluebird "^3.5.4"
|
bluebird "^3.5.4"
|
||||||
|
|
Loading…
Add table
Reference in a new issue