From caef9d74e0883c90d346346d2665cc9b06c592bb Mon Sep 17 00:00:00 2001 From: Hannah Wolfe Date: Wed, 6 Jul 2022 15:25:29 +0200 Subject: [PATCH] Added mapper for comments API refs https://github.com/TryGhost/Team/issues/1664 - ensure that the comment API returns a minimal and clean set of data and doesn't expose member details --- .../serializers/output/mappers/comments.js | 30 +++++++++++++++++++ .../utils/serializers/output/mappers/index.js | 1 + .../__snapshots__/comments.test.js.snap | 26 ++-------------- .../e2e-api/members-comments/comments.test.js | 21 ++++--------- 4 files changed, 40 insertions(+), 38 deletions(-) create mode 100644 core/server/api/endpoints/utils/serializers/output/mappers/comments.js diff --git a/core/server/api/endpoints/utils/serializers/output/mappers/comments.js b/core/server/api/endpoints/utils/serializers/output/mappers/comments.js new file mode 100644 index 0000000000..b971058a4a --- /dev/null +++ b/core/server/api/endpoints/utils/serializers/output/mappers/comments.js @@ -0,0 +1,30 @@ +const _ = require('lodash'); + +const commentFields = [ + 'id', + 'status', + 'html', + 'created_at', + 'edited_at' +]; + +const memberFields = [ + 'id', + 'name', + 'bio', + 'avatar_image' +]; + +module.exports = (model, frame) => { + const jsonModel = model.toJSON ? model.toJSON(frame.options) : model; + + const response = _.pick(jsonModel, commentFields); + + if (jsonModel.member) { + response.member = _.pick(jsonModel.member, memberFields); + } else { + response.member = null; + } + + return response; +}; diff --git a/core/server/api/endpoints/utils/serializers/output/mappers/index.js b/core/server/api/endpoints/utils/serializers/output/mappers/index.js index cd5e1677be..f4ddcf7bc0 100644 --- a/core/server/api/endpoints/utils/serializers/output/mappers/index.js +++ b/core/server/api/endpoints/utils/serializers/output/mappers/index.js @@ -1,6 +1,7 @@ module.exports = { actions: require('./actions'), authors: require('./authors'), + comments: require('./comments'), emails: require('./emails'), images: require('./images'), integrations: require('./integrations'), diff --git a/test/e2e-api/members-comments/__snapshots__/comments.test.js.snap b/test/e2e-api/members-comments/__snapshots__/comments.test.js.snap index 9fd44f4281..6a32780179 100644 --- a/test/e2e-api/members-comments/__snapshots__/comments.test.js.snap +++ b/test/e2e-api/members-comments/__snapshots__/comments.test.js.snap @@ -11,27 +11,10 @@ Object { "member": Object { "avatar_image": null, "bio": null, - "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, - "email": "member@example.com", - "email_count": 0, - "email_open_rate": null, - "email_opened_count": 0, - "enable_comment_notifications": true, - "geolocation": null, "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, - "last_commented_at": null, - "last_seen_at": null, "name": null, - "note": null, - "status": "free", - "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, - "uuid": StringMatching /\\[a-f0-9\\]\\{8\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{12\\}/, }, - "member_id": StringMatching /\\[a-f0-9\\]\\{24\\}/, - "parent_id": null, - "post_id": StringMatching /\\[a-f0-9\\]\\{24\\}/, "status": "published", - "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, }, ], "meta": Object { @@ -51,7 +34,7 @@ exports[`Comments API when authenticated Can browse all comments of a post 2: [h Object { "access-control-allow-origin": "*", "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", - "content-length": "805", + "content-length": "327", "content-type": "application/json; charset=utf-8", "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, "vary": "Accept-Encoding", @@ -67,11 +50,8 @@ Object { "edited_at": null, "html": "This is a message", "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, - "member_id": StringMatching /\\[a-f0-9\\]\\{24\\}/, - "parent_id": null, - "post_id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "member": null, "status": "published", - "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, }, ], } @@ -81,7 +61,7 @@ exports[`Comments API when authenticated Can comment on a post 2: [headers] 1`] Object { "access-control-allow-origin": "*", "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", - "content-length": "286", + "content-length": "167", "content-type": "application/json; charset=utf-8", "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, "location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/comments\\\\/\\[a-f0-9\\]\\{24\\}\\\\//, diff --git a/test/e2e-api/members-comments/comments.test.js b/test/e2e-api/members-comments/comments.test.js index 58aa7f41c4..a6cfdca605 100644 --- a/test/e2e-api/members-comments/comments.test.js +++ b/test/e2e-api/members-comments/comments.test.js @@ -27,7 +27,7 @@ describe('Comments API', function () { }); it('Can comment on a post', async function () { - const {body} = await membersAgent + await membersAgent .post(`/api/comments/`) .body({comments: [{ post_id: postId, @@ -41,10 +41,7 @@ describe('Comments API', function () { .matchBodySnapshot({ comments: [{ id: anyObjectId, - member_id: anyObjectId, - post_id: anyObjectId, - created_at: anyISODateTime, - updated_at: anyISODateTime + created_at: anyISODateTime }] }); // Save for other tests @@ -52,7 +49,7 @@ describe('Comments API', function () { }); it('Can browse all comments of a post', async function () { - const {body} = await membersAgent + await membersAgent .get(`/api/comments/?filter=post_id:${postId}&include=member`) .expectStatus(200) .matchHeaderSnapshot({ @@ -61,16 +58,10 @@ describe('Comments API', function () { .matchBodySnapshot({ comments: [{ id: anyObjectId, - member_id: anyObjectId, - member: { - id: anyObjectId, - created_at: anyISODateTime, - updated_at: anyISODateTime, - uuid: anyUuid - }, - post_id: anyObjectId, created_at: anyISODateTime, - updated_at: anyISODateTime + member: { + id: anyObjectId + } }] }); });