walinejs / waline

💬 A Simple, Safe Comment System
https://waline.js.org/en/
GNU General Public License v2.0
2.17k stars 381 forks source link

[Bug]: Cannot like other comment when logged in #2619

Closed Sugarlessmuffins closed 1 week ago

Sugarlessmuffins commented 1 month ago

问题描述 | Describe the bug

When User Logged In, it can't like or unlike another comment other than it self. i think this is logic problem in comment.js. here is the log when error happen:

    [2024-07-19T00:47:33.582] [325640] [INFO] - SQL: SELECT * FROM `wl_Comment` WHERE ( `user_id` = 2 ) AND ( `id` = '131' ), Time: 2ms
    ForbiddenError: Forbidden
        at Object.throw (/home/ploi/wp/waline/node_modules/.pnpm/koa@2.15.0/node_modules/koa/lib/context.js:97:11)
        at module.exports.putAction (/home/ploi/wp/waline/packages/server/src/logic/comment.js:286:26)
        at processTicksAndRejections (node:internal/process/task_queues:95:5)
        at cors (/home/ploi/wp/waline/node_modules/.pnpm/@koa+cors@5.0.0/node_modules/@koa/cors/index.js:109:16)
        at /home/ploi/wp/waline/packages/server/src/middleware/version.js:5:3
        at /home/ploi/wp/waline/packages/server/src/middleware/prefix-warning.js:27:3

i think the problem is how waline handle the logic:

// server/src/logic/comment.js
  async putAction() {
    const { userInfo } = this.ctx.state;
    const { like } = this.post();

    // 1. like
    if (think.isEmpty(userInfo) && think.isBoolean(like)) {
      this.rules = {
        like: {
          required: true,
          boolean: true,
        },
      };

      return;
    }

    if (think.isEmpty(userInfo)) {
      return this.ctx.throw(401);
    }

    // 2. administrator
    if (userInfo.type === 'administrator') {
      return;
    }

    // 3. comment author modify comment content
    const modelInstance = this.getModel('Comment');
    const commentData = await modelInstance.select({
      user_id: userInfo.objectId,
      objectId: this.id,
    });

    if (!think.isEmpty(commentData)) {
      return;
    }

    return this.ctx.throw(403);
  }

i also trying to add log to see if the userinfo is retrieved correctly:

 userInfo set in state: {
  email: 'some-email@gmail.com',
  url: '',
  display_name: 'Whatzitooya',
  type: 'guest',
  github: null,
  twitter: null,
  facebook: null,
  google: '106800731446975697806',
  weibo: null,
  qq: null,
  avatar: 'https://avatar.url',
  '2fa': null,
  label: null,
  objectId: 3,
  mailMd5: 'b7ee6471076807965603ea08bd0effbb'
}

The userInfo is there. and we can see user type is "guest", when type = guest the logic isn't properly handling the case for liking a comment. The 403 error is being thrown because the user is neither an administrator nor the author of the comment, and the logic for handling likes is not allowing the action. it also make anonymous user can like comment even though they are not logged in because when userInfo check is happening they are returning no value.

问题网站 | Website URL

https://komen.izanami.rest

服务部署在哪里? | Where your waline deploy?

Self Host

数据存储在哪里?| Where your comment data store?

MySQL

Sugarlessmuffins commented 1 month ago

This Modification fix the issue:

 //comment.js:250
  async putAction() {
    const { userInfo } = this.ctx.state;
    const { like } = this.post();

    // 1. like
    if (think.isEmpty(userInfo)) {
      // Unauthorized users cannot proceed
      return this.ctx.throw(401, "Unauthorized access");
    }

    // Check for like request
    if (think.isBoolean(like)) {
      // Allow any logged-in user to like the comment
      this.rules = {
        like: {
          required: true,
          boolean: true,
        },
      };
      return;
    }

    // 2. administrator
    if (userInfo.type === 'administrator') {
      return;
    }

    // 3. comment author modify comment content
    const modelInstance = this.getModel('Comment');
    const commentData = await modelInstance.select({
      user_id: userInfo.objectId,
      objectId: this.id,
    });

    if (!think.isEmpty(commentData)) {
      return;
    }

    return this.ctx.throw(403);
  }

BUT, now unauthorized user cannot like or update the comment, so its a disadvantage for those who dont want to set LOGIN=force in their application.

@lizheming this is not a fix, but maybe give you idea what to do

lizheming commented 1 week ago

Thank you for your report~ I will try to repeat the problem later and fix it with reference to your plan.