mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-28 14:03:48 +03:00
Added Admin API for deleting members (#10673)
no issue - Added new API to delete members - Added methods to handle e2e member deletion - Deleting member via Admin leads to - Removal of member from payment processor and cancelling all active subscriptions immediately - Removal of member information from DB
This commit is contained in:
parent
a7385f5e10
commit
c03ca79c66
@ -29,6 +29,26 @@ const members = {
|
||||
query(frame) {
|
||||
return memberUserObject.get(frame.data, frame.options);
|
||||
}
|
||||
},
|
||||
|
||||
destroy: {
|
||||
statusCode: 204,
|
||||
headers: {},
|
||||
options: [
|
||||
'id'
|
||||
],
|
||||
validation: {
|
||||
options: {
|
||||
id: {
|
||||
required: true
|
||||
}
|
||||
}
|
||||
},
|
||||
permissions: true,
|
||||
query(frame) {
|
||||
frame.options.require = true;
|
||||
return memberUserObject.destroy(frame.options).return(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -22,6 +22,7 @@ module.exports = function MembersApi({
|
||||
validateMember,
|
||||
updateMember,
|
||||
getMember,
|
||||
deleteMember,
|
||||
listMembers,
|
||||
sendEmail,
|
||||
siteConfig
|
||||
@ -35,6 +36,7 @@ module.exports = function MembersApi({
|
||||
createMember,
|
||||
updateMember,
|
||||
getMember,
|
||||
deleteMember,
|
||||
validateMember,
|
||||
sendEmail,
|
||||
encodeToken,
|
||||
|
@ -66,4 +66,22 @@ module.exports = class PaymentProcessorService {
|
||||
return this._processors[metadata.adapter].getSubscription(member, metadata);
|
||||
});
|
||||
}
|
||||
|
||||
removeSubscription(member, metadata) {
|
||||
if (!metadata.adapter) {
|
||||
return Promise.reject(new Error('removeSubscription(member, { adapter }) requires an adapter'));
|
||||
}
|
||||
return this._ready.then(() => {
|
||||
return this._processors[metadata.adapter].removeSubscription(member, metadata);
|
||||
});
|
||||
}
|
||||
|
||||
removeCustomer(member, metadata) {
|
||||
if (!metadata.adapter) {
|
||||
return Promise.reject(new Error('removeCustomer(member, { adapter }) requires an adapter'));
|
||||
}
|
||||
return this._ready.then(() => {
|
||||
return this._processors[metadata.adapter].removeCustomer(member, metadata);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -118,6 +118,22 @@ function createCreator(resource, getAttrs) {
|
||||
};
|
||||
}
|
||||
|
||||
function createRemover(resource, get, generateHashSeed) {
|
||||
return function remove(stripe, object, ...rest) {
|
||||
return get(stripe, object, generateHashSeed(object, ...rest)).then((res) => {
|
||||
return stripe[resource].del(res.id).then((result) => {
|
||||
return result;
|
||||
}, (err) => {
|
||||
throw err;
|
||||
});
|
||||
}).catch((err) => {
|
||||
if (err.code !== 'resource_missing') {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function createEnsurer(get, create, generateHashSeed) {
|
||||
return function ensure(stripe, object, ...rest) {
|
||||
return get(stripe, object, generateHashSeed(object, ...rest))
|
||||
@ -134,9 +150,10 @@ function createEnsurer(get, create, generateHashSeed) {
|
||||
function createApi(resource, validResult, getAttrs, generateHashSeed) {
|
||||
const get = createGetter(resource, validResult);
|
||||
const create = createCreator(resource, getAttrs);
|
||||
const remove = createRemover(resource, get, generateHashSeed);
|
||||
const ensure = createEnsurer(get, create, generateHashSeed);
|
||||
|
||||
return {
|
||||
get, create, ensure
|
||||
get, create, remove, ensure
|
||||
};
|
||||
}
|
||||
|
@ -91,4 +91,24 @@ module.exports = class StripePaymentProcessor {
|
||||
return api.subscriptions.get(this._stripe, member);
|
||||
});
|
||||
}
|
||||
|
||||
removeSubscription(member) {
|
||||
if (!this._stripe) {
|
||||
throw new Error('StripePaymentProcessor must be configured()');
|
||||
}
|
||||
|
||||
return this._ready.then(() => {
|
||||
return api.subscriptions.remove(this._stripe, member);
|
||||
});
|
||||
}
|
||||
|
||||
removeCustomer(member) {
|
||||
if (!this._stripe) {
|
||||
throw new Error('StripePaymentProcessor must be configured()');
|
||||
}
|
||||
|
||||
return this._ready.then(() => {
|
||||
return api.customers.remove(this._stripe, member);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -4,6 +4,7 @@ module.exports = function ({
|
||||
updateMember,
|
||||
getMember,
|
||||
listMembers,
|
||||
deleteMember,
|
||||
validateMember,
|
||||
sendEmail,
|
||||
encodeToken,
|
||||
@ -45,12 +46,30 @@ module.exports = function ({
|
||||
});
|
||||
}
|
||||
|
||||
function destroy(...args) {
|
||||
return getMember(...args).then((member) => {
|
||||
if (!member) {
|
||||
return null;
|
||||
}
|
||||
return subscriptions.getAdapters().then((adapters) => {
|
||||
return Promise.all(adapters.map((adapter) => {
|
||||
return subscriptions.removeCustomer(member, {
|
||||
adapter
|
||||
});
|
||||
}));
|
||||
}).then(() => {
|
||||
return deleteMember(...args);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
requestPasswordReset,
|
||||
resetPassword,
|
||||
create: createMember,
|
||||
validate: validateMember,
|
||||
list: listMembers,
|
||||
destroy,
|
||||
get
|
||||
};
|
||||
};
|
||||
|
@ -37,6 +37,17 @@ function getMember(data, options) {
|
||||
});
|
||||
}
|
||||
|
||||
function deleteMember(options) {
|
||||
options = options || {};
|
||||
return models.Member.destroy(options).catch(models.Member.NotFoundError, () => {
|
||||
throw new common.errors.NotFoundError({
|
||||
message: common.i18n.t('errors.api.resource.resourceNotFound', {
|
||||
resource: 'Member'
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function listMembers(options) {
|
||||
return models.Member.findPage(options).then((models) => {
|
||||
return {
|
||||
@ -170,6 +181,7 @@ const api = MembersApi({
|
||||
validateAudience,
|
||||
createMember,
|
||||
getMember,
|
||||
deleteMember,
|
||||
listMembers,
|
||||
validateMember,
|
||||
updateMember,
|
||||
|
@ -109,6 +109,7 @@ module.exports = function apiRoutes() {
|
||||
// ## Members
|
||||
router.get('/members', shared.middlewares.labs.members, mw.authAdminApi, http(apiv2.members.browse));
|
||||
router.get('/members/:id', shared.middlewares.labs.members, mw.authAdminApi, http(apiv2.members.read));
|
||||
router.del('/members/:id', shared.middlewares.labs.members, mw.authAdminApi, http(apiv2.members.destroy));
|
||||
|
||||
// ## Roles
|
||||
router.get('/roles/', mw.authAdminApi, http(apiv2.roles.browse));
|
||||
|
Loading…
Reference in New Issue
Block a user