From 7826762f561fc3ab9851bfec2a8e73182017d158 Mon Sep 17 00:00:00 2001 From: Kester Date: Tue, 24 Sep 2024 17:26:31 -0400 Subject: [PATCH 1/4] frontend and functional backend for verifying message --- .../partials/topic/post-menu-list.tpl | 146 ++++++++++++++++++ .../templates/partials/topic/post.tpl | 130 ++++++++++++++++ .../components/schemas/PostObject.yaml | 4 +- public/openapi/read/topic/topic_id.yaml | 6 +- public/openapi/write/posts/pid.yaml | 6 +- public/openapi/write/posts/pid/replies.yaml | 2 + public/src/client/topic/events.js | 7 + public/src/client/topic/postTools.js | 12 ++ src/api/posts.js | 8 + src/controllers/write/posts.js | 12 ++ src/posts/data.js | 2 +- src/posts/index.js | 1 + src/posts/summary.js | 2 +- src/posts/verify.js | 27 ++++ src/routes/write/posts.js | 3 + test/posts.js | 8 + 16 files changed, 371 insertions(+), 5 deletions(-) create mode 100644 nodebb-theme-slackers/templates/partials/topic/post-menu-list.tpl create mode 100644 nodebb-theme-slackers/templates/partials/topic/post.tpl create mode 100644 src/posts/verify.js diff --git a/nodebb-theme-slackers/templates/partials/topic/post-menu-list.tpl b/nodebb-theme-slackers/templates/partials/topic/post-menu-list.tpl new file mode 100644 index 0000000000..2267990cc8 --- /dev/null +++ b/nodebb-theme-slackers/templates/partials/topic/post-menu-list.tpl @@ -0,0 +1,146 @@ +{{{ if posts.display_moderator_tools }}} +
  • + + [[topic:edit]] + +
  • +
  • + + [[topic:delete]] + +
  • +
  • + + [[topic:restore]] + +
  • +{{{ if posts.display_purge_tools }}} +
  • + + [[topic:purge]] + +
  • +{{{ end }}} + +{{{ if posts.display_move_tools }}} +
  • + + [[topic:move]] + +
  • +{{{ end }}} + +{{{ if !posts.verified }}} +
  • + + Verify Message + +
  • +{{{ else }}} +
  • + + Un-Verify Message + +
  • +{{{ end }}} + +{{{ if posts.display_change_owner_tools }}} +
  • + + [[topic:change-owner]] + +
  • +{{{ end }}} + +{{{ if posts.ip }}} +
  • + + [[topic:copy-ip]] {posts.ip} + +
  • +{{{ if posts.display_ip_ban }}} +
  • + + [[topic:ban-ip]] {posts.ip} + +
  • +{{{ end }}} +{{{ end }}} +{{{ end }}} + +{{{ each posts.tools }}} +
  • + + {{./html}} + +
  • +{{{ end }}} + +{{{ if !posts.deleted }}} + {{{ if posts.display_history}}} +
  • + + [[topic:view-history]] + +
  • + {{{ end }}} + + {{{ if config.loggedIn }}} +
  • + + + + + + [[topic:bookmark]] + {posts.bookmarks}  + +
  • + {{{ end }}} + +
  • + + [[topic:copy-permalink]] + +
  • + + {{{ if postSharing.length }}} + {{{ if config.loggedIn }}}{{{ end }}} + + {{{ end }}} +
  • + {{{ each postSharing }}} + + {{{ end }}} +
  • +{{{ end }}} + +{{{ if posts.display_flag_tools }}} + + +
  • + [[topic:flag-post]] +
  • +
  • + [[topic:already-flagged]] +
  • + +{{{ if (!posts.selfPost && posts.uid) }}} +
  • + [[topic:flag-user]] +
  • +{{{ end }}} +{{{ end }}} + +{{{ if posts.display_moderator_tools }}} +{{{ if posts.flags.exists }}} +
  • + [[topic:view-flag-report]] +
  • +{{{ if (posts.flags.state == "open") }}} +
  • + [[topic:resolve-flag]] +
  • +{{{ end }}} +{{{ end }}} +{{{ end }}} diff --git a/nodebb-theme-slackers/templates/partials/topic/post.tpl b/nodebb-theme-slackers/templates/partials/topic/post.tpl new file mode 100644 index 0000000000..0fb932ccea --- /dev/null +++ b/nodebb-theme-slackers/templates/partials/topic/post.tpl @@ -0,0 +1,130 @@ +{{{ if (!./index && widgets.mainpost-header.length) }}} +
    + {{{ each widgets.mainpost-header }}} + {widgets.mainpost-header.html} + {{{ end }}} +
    +{{{ end }}} +
    + +
    + + +
    + {posts.content} +
    +
    +
    + +
    + {{{ if posts.user.signature }}} +
    {posts.user.signature}
    + {{{ end }}} + + + +
    + +
    + + + + + {{{ if !reputation:disabled }}} +
    + + + + + + + {posts.votes} + + {{{ if !downvote:disabled }}} + + + + {{{ end }}} +
    + {{{ end }}} + + +
    +
    +{{{ if (!./index && widgets.mainpost-footer.length) }}} +
    + {{{ each widgets.mainpost-footer }}} + {widgets.mainpost-footer.html} + {{{ end }}} +
    +{{{ end }}} \ No newline at end of file diff --git a/public/openapi/components/schemas/PostObject.yaml b/public/openapi/components/schemas/PostObject.yaml index ea91579cc6..cda40e0a93 100644 --- a/public/openapi/components/schemas/PostObject.yaml +++ b/public/openapi/components/schemas/PostObject.yaml @@ -16,6 +16,8 @@ PostObject: type: number deleted: type: boolean + verify: + type: number upvotes: type: number downvotes: @@ -139,4 +141,4 @@ PostObject: isMainPost: type: boolean replies: - type: number \ No newline at end of file + type: number diff --git a/public/openapi/read/topic/topic_id.yaml b/public/openapi/read/topic/topic_id.yaml index f0fde1b6c0..654d02d71a 100644 --- a/public/openapi/read/topic/topic_id.yaml +++ b/public/openapi/read/topic/topic_id.yaml @@ -67,6 +67,10 @@ get: type: number deleted: type: number + verify: + type: number + verifyUid: + type: number upvotes: type: number downvotes: @@ -443,4 +447,4 @@ get: - tid - $ref: ../../components/schemas/Pagination.yaml#/Pagination - $ref: ../../components/schemas/Breadcrumbs.yaml#/Breadcrumbs - - $ref: ../../components/schemas/CommonProps.yaml#/CommonProps \ No newline at end of file + - $ref: ../../components/schemas/CommonProps.yaml#/CommonProps diff --git a/public/openapi/write/posts/pid.yaml b/public/openapi/write/posts/pid.yaml index 593a7acd01..044fc31fe6 100644 --- a/public/openapi/write/posts/pid.yaml +++ b/public/openapi/write/posts/pid.yaml @@ -40,6 +40,10 @@ get: type: number deleted: type: number + verify: + type: number + verifyUid: + type: number upvotes: type: number downvotes: @@ -138,4 +142,4 @@ delete: $ref: ../../components/schemas/Status.yaml#/Status response: type: object - properties: {} \ No newline at end of file + properties: {} diff --git a/public/openapi/write/posts/pid/replies.yaml b/public/openapi/write/posts/pid/replies.yaml index b021eec14e..ff33ceb63e 100644 --- a/public/openapi/write/posts/pid/replies.yaml +++ b/public/openapi/write/posts/pid/replies.yaml @@ -45,6 +45,8 @@ get: type: number deleted: type: number + verify: + type: number upvotes: type: number downvotes: diff --git a/public/src/client/topic/events.js b/public/src/client/topic/events.js index e091dd69c8..b151ac54c1 100644 --- a/public/src/client/topic/events.js +++ b/public/src/client/topic/events.js @@ -40,6 +40,9 @@ define('forum/topic/events', [ 'posts.bookmark': togglePostBookmark, 'posts.unbookmark': togglePostBookmark, + 'posts.verify': toggleVerifyMessage, + 'posts.unverify': toggleVerifyMessage, + 'posts.upvote': togglePostVote, 'posts.downvote': togglePostVote, 'posts.unvote': togglePostVote, @@ -65,6 +68,10 @@ define('forum/topic/events', [ } }; + function toggleVerifyMessage(data) { + console.log(data); + } + function onUserStatusChange(data) { app.updateUserStatus($('[data-uid="' + data.uid + '"] [component="user/status"]'), data.status); } diff --git a/public/src/client/topic/postTools.js b/public/src/client/topic/postTools.js index f8d2ca8933..d32ab12fac 100644 --- a/public/src/client/topic/postTools.js +++ b/public/src/client/topic/postTools.js @@ -129,6 +129,10 @@ define('forum/topic/postTools', [ return bookmarkPost($(this), getData($(this), 'data-pid')); }); + postContainer.on('click', '[component="post/verify"]', function () { + return verifyMessage($(this)); + }); + postContainer.on('click', '[component="post/upvote"]', function () { return votes.toggleVote($(this), '.upvoted', 1); }); @@ -404,6 +408,14 @@ define('forum/topic/postTools', [ postAction(action, pid); } + async function verifyMessage(button) { + const pid = getData(button, 'data-pid'); + const method = 'put'; + const action = 'verify'; + console.log('trying to call api'); + api[method](`/posts/${pid}/${action}`).catch(alerts.error); + } + function purgePost(button) { postAction('purge', getData(button, 'data-pid')); } diff --git a/src/api/posts.js b/src/api/posts.js index 4e3917a008..af205532ef 100644 --- a/src/api/posts.js +++ b/src/api/posts.js @@ -413,6 +413,14 @@ postsAPI.unbookmark = async function (caller, data) { return await apiHelpers.postCommand(caller, 'unbookmark', 'bookmarked', '', data); }; +postsAPI.verify = async function (caller, data) { + return await apiHelpers.postCommand(caller, 'verify', 'verify', '', data); +}; + +postsAPI.unverify = async function (caller, data) { + return await apiHelpers.postCommand(caller, 'unverify', 'unverify', '', data); +}; + async function diffsPrivilegeCheck(pid, uid) { const [deleted, privilegesData] = await Promise.all([ posts.getPostField(pid, 'deleted'), diff --git a/src/controllers/write/posts.js b/src/controllers/write/posts.js index 1dc8cf6800..27778341c6 100644 --- a/src/controllers/write/posts.js +++ b/src/controllers/write/posts.js @@ -153,6 +153,18 @@ Posts.unbookmark = async (req, res) => { helpers.formatApiResponse(200, res); }; +Posts.verify = async (req, res) => { + const data = await mock(req); + await api.posts.verify(req, data); + helpers.formatApiResponse(200, res); +}; + +Posts.unverify = async (req, res) => { + const data = await mock(req); + await api.posts.unverify(req, data); + helpers.formatApiResponse(200, res); +}; + Posts.getDiffs = async (req, res) => { helpers.formatApiResponse(200, res, await api.posts.getDiffs(req, { ...req.params })); }; diff --git a/src/posts/data.js b/src/posts/data.js index 3a4d303ff5..b69002550f 100644 --- a/src/posts/data.js +++ b/src/posts/data.js @@ -7,7 +7,7 @@ const utils = require('../utils'); const intFields = [ 'uid', 'pid', 'tid', 'deleted', 'timestamp', 'upvotes', 'downvotes', 'deleterUid', 'edited', - 'replies', 'bookmarks', + 'replies', 'bookmarks', 'verify', 'verifyUid', ]; module.exports = function (Posts) { diff --git a/src/posts/index.js b/src/posts/index.js index 9db52c6b27..0fe7e3a772 100644 --- a/src/posts/index.js +++ b/src/posts/index.js @@ -24,6 +24,7 @@ require('./tools')(Posts); require('./votes')(Posts); require('./bookmarks')(Posts); require('./queue')(Posts); +require('./verify')(Posts); require('./diffs')(Posts); require('./uploads')(Posts); diff --git a/src/posts/summary.js b/src/posts/summary.js index 364baad1f7..58df71c8f9 100644 --- a/src/posts/summary.js +++ b/src/posts/summary.js @@ -20,7 +20,7 @@ module.exports = function (Posts) { options.parse = options.hasOwnProperty('parse') ? options.parse : true; options.extraFields = options.hasOwnProperty('extraFields') ? options.extraFields : []; - const fields = ['pid', 'tid', 'content', 'uid', 'timestamp', 'deleted', 'upvotes', 'downvotes', 'replies', 'handle'].concat(options.extraFields); + const fields = ['pid', 'tid', 'content', 'uid', 'timestamp', 'deleted', 'upvotes', 'downvotes', 'replies', 'handle', 'verify'].concat(options.extraFields); let posts = await Posts.getPostsFields(pids, fields); posts = posts.filter(Boolean); diff --git a/src/posts/verify.js b/src/posts/verify.js new file mode 100644 index 0000000000..08f1ab621f --- /dev/null +++ b/src/posts/verify.js @@ -0,0 +1,27 @@ +'use strict'; + +const plugins = require('../plugins'); + +module.exports = function (Posts) { + Posts.verify = async function (pid, uid) { + return await toggleVerify('verify', pid, uid); + }; + + Posts.unverify = async function (pid, uid) { + return await toggleVerify('unverify', pid, uid); + }; + + async function toggleVerify(type, pid, uid) { + const isVerifying = type === 'verify'; + await plugins.hooks.fire(`filter:post.${type}`, { pid: pid, uid: uid }); + + await Posts.setPostFields(pid, { + verify: isVerifying ? 1 : 0, + verifyUid: isVerifying ? uid : 0, + }); + + const postData = await Posts.getPostFields(pid, ['pid', 'tid', 'uid', 'content', 'timestamp']); + + return postData; + } +}; diff --git a/src/routes/write/posts.js b/src/routes/write/posts.js index e573bbb9b0..29d1520ef7 100644 --- a/src/routes/write/posts.js +++ b/src/routes/write/posts.js @@ -32,6 +32,9 @@ module.exports = function () { setupApiRoute(router, 'put', '/:pid/bookmark', middlewares, controllers.write.posts.bookmark); setupApiRoute(router, 'delete', '/:pid/bookmark', middlewares, controllers.write.posts.unbookmark); + setupApiRoute(router, 'put', '/:pid/verify', middlewares, controllers.write.posts.verify); + setupApiRoute(router, 'put', '/:pid/verify', middlewares, controllers.write.posts.unverify); + setupApiRoute(router, 'get', '/:pid/diffs', [middleware.assert.post], controllers.write.posts.getDiffs); setupApiRoute(router, 'get', '/:pid/diffs/:since', [middleware.assert.post], controllers.write.posts.loadDiff); setupApiRoute(router, 'put', '/:pid/diffs/:since', middlewares, controllers.write.posts.restoreDiff); diff --git a/test/posts.js b/test/posts.js index 20403e24cf..e8a70cc3b9 100644 --- a/test/posts.js +++ b/test/posts.js @@ -281,6 +281,14 @@ describe('Post\'s', () => { }); }); + describe('answering', async () => { + it('should mark post verified', async () => { + await apiPosts.verify({ uid: voterUid }, { pid: postData.pid, room_id: `topic_${postData.tid}` }); + const isAnswered = await posts.getPostField(postData.pid, 'verify'); + assert.strictEqual(isAnswered, 1); + }); + }); + describe('post tools', () => { it('should error if data is invalid', (done) => { socketPosts.loadPostTools({ uid: globalModUid }, null, (err) => { From 95c1bd52063b7f431e17d00e6d25b4a3773f327f Mon Sep 17 00:00:00 2001 From: Kester Date: Tue, 24 Sep 2024 17:37:18 -0400 Subject: [PATCH 2/4] changed theme to reflect post schema --- .../templates/partials/topic/post-menu-list.tpl | 2 +- nodebb-theme-slackers/templates/partials/topic/post.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nodebb-theme-slackers/templates/partials/topic/post-menu-list.tpl b/nodebb-theme-slackers/templates/partials/topic/post-menu-list.tpl index 2267990cc8..ceb32ca8a1 100644 --- a/nodebb-theme-slackers/templates/partials/topic/post-menu-list.tpl +++ b/nodebb-theme-slackers/templates/partials/topic/post-menu-list.tpl @@ -30,7 +30,7 @@ {{{ end }}} -{{{ if !posts.verified }}} +{{{ if !posts.verify }}}
  • Verify Message diff --git a/nodebb-theme-slackers/templates/partials/topic/post.tpl b/nodebb-theme-slackers/templates/partials/topic/post.tpl index 0fb932ccea..c8c3309831 100644 --- a/nodebb-theme-slackers/templates/partials/topic/post.tpl +++ b/nodebb-theme-slackers/templates/partials/topic/post.tpl @@ -54,7 +54,7 @@ {{{ end }}}
    - {{{ if posts.verified }}} + {{{ if posts.verify }}} {{{ end }}} From 653c107f5f797f159b7b4dd02097baa2a2b031e7 Mon Sep 17 00:00:00 2001 From: Kester Date: Tue, 24 Sep 2024 17:54:51 -0400 Subject: [PATCH 3/4] added openapi documentation --- public/openapi/write.yaml | 4 +++- public/openapi/write/posts/pid/verify.yaml | 26 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 public/openapi/write/posts/pid/verify.yaml diff --git a/public/openapi/write.yaml b/public/openapi/write.yaml index c59b9bce29..aea404e425 100644 --- a/public/openapi/write.yaml +++ b/public/openapi/write.yaml @@ -186,6 +186,8 @@ paths: $ref: 'write/posts/pid/upvoters.yaml' /posts/{pid}/bookmark: $ref: 'write/posts/pid/bookmark.yaml' + /posts/{pid}/verify: + $ref: 'write/posts/pid/verify.yaml' /posts/{pid}/diffs: $ref: 'write/posts/pid/diffs.yaml' /posts/{pid}/diffs/{since}: @@ -261,4 +263,4 @@ paths: /files/: $ref: 'write/files.yaml' /files/folder: - $ref: 'write/files/folder.yaml' \ No newline at end of file + $ref: 'write/files/folder.yaml' diff --git a/public/openapi/write/posts/pid/verify.yaml b/public/openapi/write/posts/pid/verify.yaml new file mode 100644 index 0000000000..d5f6c8517f --- /dev/null +++ b/public/openapi/write/posts/pid/verify.yaml @@ -0,0 +1,26 @@ +put: + tags: + - posts + summary: verifies a post + description: This operation verifies a post. + parameters: + - in: path + name: pid + schema: + type: string + required: true + description: a valid post id + example: 2 + responses: + '200': + description: Post successfully verified + content: + application/json: + schema: + type: object + properties: + status: + $ref: ../../../components/schemas/Status.yaml#/Status + response: + type: object + properties: {} From 8fde2f4be8c04d174feaf551111153a152e5f6b6 Mon Sep 17 00:00:00 2001 From: Kester Date: Tue, 24 Sep 2024 23:53:13 -0400 Subject: [PATCH 4/4] addresses lints from git merge --- public/src/client/topic/events.js | 2 +- src/controllers/write/posts.js | 2 ++ src/posts/data.js | 2 +- test/posts.js | 8 ++++---- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/public/src/client/topic/events.js b/public/src/client/topic/events.js index 133b7cacc6..8894d62358 100644 --- a/public/src/client/topic/events.js +++ b/public/src/client/topic/events.js @@ -42,7 +42,7 @@ define('forum/topic/events', [ 'posts.verify': toggleVerifyMessage, 'posts.unverify': toggleVerifyMessage, - + 'posts.answer': toggleAnswered, 'posts.unanswer': toggleAnswered, diff --git a/src/controllers/write/posts.js b/src/controllers/write/posts.js index df19543c1e..fc58594ffc 100644 --- a/src/controllers/write/posts.js +++ b/src/controllers/write/posts.js @@ -162,6 +162,8 @@ Posts.verify = async (req, res) => { Posts.unverify = async (req, res) => { const data = await mock(req); await api.posts.unverify(req, data); + helpers.formatApiResponse(200, res); +}; Posts.answer = async (req, res) => { const data = await mock(req); diff --git a/src/posts/data.js b/src/posts/data.js index b2a5b8c0fc..1889c5d2d5 100644 --- a/src/posts/data.js +++ b/src/posts/data.js @@ -8,7 +8,7 @@ const intFields = [ 'uid', 'pid', 'tid', 'deleted', 'timestamp', 'upvotes', 'downvotes', 'deleterUid', 'edited', 'replies', 'bookmarks', 'verify', 'verifyUid', - 'answered', 'answererUid', + 'answered', 'answererUid', ]; module.exports = function (Posts) { diff --git a/test/posts.js b/test/posts.js index 122621f94c..063c341b96 100644 --- a/test/posts.js +++ b/test/posts.js @@ -280,13 +280,13 @@ describe('Post\'s', () => { assert.equal(hasBookmarked[0], false); }); }); - - describe('verifying', async () => { + + describe('verifying', async () => { it('should mark post verified', async () => { await apiPosts.verify({ uid: voterUid }, { pid: postData.pid, room_id: `topic_${postData.tid}` }); const isVerified = await posts.getPostField(postData.pid, 'verify'); - assert.strictEqual(isVerified, 1); - }); + assert.strictEqual(isVerified, 1); + }); }); describe('answering', async () => {