SOLVED Update category picture (via image upload) API not working


  • $ curl -s -H "Authorization: Bearer 000000-000a-0000-ab00-622505ce32ba" -XPOST --data 'cid=84&files=/tmp/categories/ideas.png' http://localhost:4567/api/admin/category/uploadpicture | jq .
    

    Output:

    {
      "path": "/api/admin/category/uploadpicture",
      "error": "Cannot read property 'files' of undefined",
      "bodyClass": "page-admin page-admin-category page-admin-uploadpicture page-status-500 user-loggedin"
    }
    

    Can someone help me out here? The path is correct according to the API documentation and the required data parts are correct. Not sure what all this means.

    Regards,
    Jeff

  • NodeBB

    This worked for me give it a try

    # get csrf token and save cookies
    curl http://127.0.0.1:4567/api/config -c cookies.txt -s | grep csrf
    
    #this will print something like
    "csrf_token": "bHqyDEde-Y_zLYuitkD4uc5Cd7-0mYF1m5GU",
    

    Copy the value of the csrf_token and make the upload also use cookies.txt with -b cookies.txt

    curl -H "Authorization: Bearer da21bf5f-6924-4e5d-9a82-92191e6f2240" -XPOST \
      -F params="{\"cid\":\"2\"}" \
      -F "files[]=@c:\ideas.png" \
      -F "_csrf=bHqyDEde-Y_zLYuitkD4uc5Cd7-0mYF1m5GU"  \
      -b cookies.txt \
      http://127.0.0.1:4567/api/admin/category/uploadpicture
    

    Should get this output

    [
        {
            "name": "ideas.png",
            "url": "/assets/uploads/category/category-2.png"
        }
    ]
    
  • Global Moderator Plugin & Theme Dev

    That route accepts multiparty form data. The way you're setting data right now doesn't tell curl that that path is a file it needs to send.

    You need to do something like

    curl -s -H "Authorization: Bearer 000000-000a-0000-ab00-622505ce32ba" -X POST http://localhost:4567/api/admin/category/uploadpicture -F cid=84 -F files=@/tmp/categories/ideas.png | jq .
    

  • @pitaj that still isn't working

    $ curl -H "Authorization: Bearer xxxxxxxxx" -XPOST -F cid=84 -F files=@/tmp/ideas.png http://localhost:4567/api/admin/category/uploadpicture | jq .
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100  7661  100   198  100  7463   2083  78520 --:--:-- --:--:-- --:--:-- 79393
    {
      "path": "/api/admin/category/uploadpicture",
      "error": "[[error:invalid-files]]",
      "bodyClass": "page-admin page-admin-category page-admin-uploadpicture page-status-500 user-loggedin"
    

    Additional log from the application window:

    2021-10-20T22:04:38.271Z [4567/19620] - error: /api/admin/category/uploadpicture
    Error: [[error:invalid-files]]
        at validateFiles (/opt/nodebb/src/middleware/index.js:112:15)
        at Layer.handle [as handle_request] (/opt/nodebb/node_modules/express/lib/router/layer.js:95:5)
        at next (/opt/nodebb/node_modules/express/lib/router/route.js:137:13)
        at Form.<anonymous> (/opt/nodebb/node_modules/connect-multiparty/index.js:114:7)
        at Form.emit (events.js:326:22)
        at /opt/nodebb/node_modules/multiparty/index.js:610:12
        at processTicksAndRejections (internal/process/task_queues.js:79:11)
    

    J

  • Global Moderator Plugin & Theme Dev

    Have you tried uploading that file through the NodeBB UI?


  • @pitaj Yes I have. It's not the image causing this it is a bug in the API.

  • Global Moderator Plugin & Theme Dev

    Okay just wanted to make sure it wasn't the file or NodeBB rejecting it for some other reason.

    You might need to specify that files is an array like this:

    files[0]=@/tmp/ideas.png
    

  • @pitaj no that didn't work either.

    parse error: Invalid numeric literal at EOF at line 1, column 9
    
  • Global Moderator Plugin & Theme Dev

    Looks like an error from curl, did you try wrapping the argument in quotes?

    "files[0]=@/tmp/ideas.jpg"
    

  • @pitaj No that didn't work either. I even tried escaping, quoting, single quoting the brackets. Face it, this is a bug in the API, the required field "files" is not in the code or isn't enabled somewhere else. The error is 500 Server Error. No amount of curl command-fu is going to resolve this.

    What is the next step, do I need to push this over to a Git issue or something?

  • Global Moderator Plugin & Theme Dev

    I'm pretty sure this same API is used when you upload an image through the UI.

    @julian can you take a look?

  • NodeBB

    Did you try logging the value of req.files here.


  • @baris Not yet, but I'm going to now.


  • @baris adding log output produces zero additional data, I just see the error:

    2021-10-22T22:58:44.720Z [4567/19620] - error: /api/admin/category/uploadpicture
    Error: [[error:invalid-files]]
        at validateFiles (/opt/nodebb/src/middleware/index.js:112:15)
        at Layer.handle [as handle_request] (/opt/nodebb/node_modules/express/lib/router/layer.js:95:5)
        at next (/opt/nodebb/node_modules/express/lib/router/route.js:137:13)
        at Form.<anonymous> (/opt/nodebb/node_modules/connect-multiparty/index.js:114:7)
        at Form.emit (events.js:326:22)
        at /opt/nodebb/node_modules/multiparty/index.js:610:12
        at processTicksAndRejections (internal/process/task_queues.js:79:11)
    

    I work with API's of all flavors for my job. This sincerely looks like "files" does not exist in the API. Is it possible that this function was just not enabled, or otherwise overlooked? Server error 500's usually means bad code. I'm just not familiar enough with NodeBB to debug this myself.

  • NodeBB

    This seems to work for me on windows.

    $ curl -H "Authorization: Bearer ...." -XPOST -F cid=2 -F "files[]=@c:\ideas.png" http://127.0.0.1:4567/api/admin/category/uploadpicture
    Forbidden
    

    I got a forbidden error due to missing csrf token but the file was visible on the server logs.

    {
      files: [
        {
          fieldName: 'files[]',
          originalFilename: 'ideas.png',
          path: 'C:\\Users\\Baris\\AppData\\Local\\Temp\\BnugKrdsfzdSP4rlETtcLt9t.png',
          headers: [Object],
          size: 59289,
          name: 'ideas.png',
          type: 'image/png'
        }
      ]
    }
    

    Did you try using "files[]=@c:\ideas.png" ?


  • @baris We did not try that way, we tried files[0]=

    Now I'm getting 403 Forbidden, with invalid csrf token in the logs.

    2021-10-22T23:54:52.993Z [4567/19620] - error: /api/admin/category/uploadpicture
    invalid csrf token
    

    How do I get around the invalid token?


  • Here is the verbose output from my macbook:

    Note: Unnecessary use of -X or --request, POST is already inferred.
    *   Trying 192.168.10.65...
    * TCP_NODELAY set
    * Connected to pubdump.unfufadoo.net (192.168.10.65) port 4567 (#0)
    > POST /api/admin/category/uploadpicture HTTP/1.1
    > Host: pubdump.unfufadoo.net:4567
    > User-Agent: curl/7.64.1
    > Accept: */*
    > Authorization: Bearer e3642513-175a-4650-ae39-622505ce32ba
    > Content-Length: 7450
    > Content-Type: multipart/form-data; boundary=------------------------23a77408539631fe
    > Expect: 100-continue
    >
    < HTTP/1.1 100 Continue
    * We are completely uploaded and fine
    < HTTP/1.1 403 Forbidden
    < X-DNS-Prefetch-Control: off
    < Expect-CT: max-age=0
    < X-Frame-Options: SAMEORIGIN
    < X-Download-Options: noopen
    < X-Content-Type-Options: nosniff
    < X-Permitted-Cross-Domain-Policies: none
    < X-XSS-Protection: 0
    < Referrer-Policy: strict-origin-when-cross-origin
    < X-Powered-By: NodeBB
    < Content-Security-Policy: frame-ancestors 'self'
    < Set-Cookie: _csrf=KEEYRk8-aMRzJbUywg3dSE5C; Path=/
    < Set-Cookie: express.sid=s%3AAZCyzQs6kMVtHBfIxhfjHyTNarERnXAx.IXyYI8wP1w3cJjJkcreNjgGJTVJGP6UoI0FXRTJQZso; Path=/; Expires=Sat, 06 Nov 2021 00:09:16 GMT; HttpOnly; SameSite=Lax
    < Content-Type: text/plain; charset=utf-8
    < Content-Length: 9
    < ETag: W/"9-PatfYBLj4Um1qTm5zrukoLhNyPU"
    < Date: Sat, 23 Oct 2021 00:09:16 GMT
    < Connection: keep-alive
    < Keep-Alive: timeout=5
    <
    * Connection #0 to host pubdump.unfufadoo.net left intact
    Forbidden* Closing connection 0
    

    I see the message "We are completely uploaded and fine" in the above. But ultimately am getting the invalid token error over and over.

  • NodeBB

    I think you have to first load a regular route and get a csrf token and then use that in your POST call. I am not sure how to do that in curl. Our tests do it using request https://github.com/NodeBB/NodeBB/blob/master/test/helpers/index.js#L14 and then storing the cookies then we use it to make POST requests.

  • NodeBB

    This worked for me give it a try

    # get csrf token and save cookies
    curl http://127.0.0.1:4567/api/config -c cookies.txt -s | grep csrf
    
    #this will print something like
    "csrf_token": "bHqyDEde-Y_zLYuitkD4uc5Cd7-0mYF1m5GU",
    

    Copy the value of the csrf_token and make the upload also use cookies.txt with -b cookies.txt

    curl -H "Authorization: Bearer da21bf5f-6924-4e5d-9a82-92191e6f2240" -XPOST \
      -F params="{\"cid\":\"2\"}" \
      -F "files[]=@c:\ideas.png" \
      -F "_csrf=bHqyDEde-Y_zLYuitkD4uc5Cd7-0mYF1m5GU"  \
      -b cookies.txt \
      http://127.0.0.1:4567/api/admin/category/uploadpicture
    

    Should get this output

    [
        {
            "name": "ideas.png",
            "url": "/assets/uploads/category/category-2.png"
        }
    ]
    

  • @baris we are definitely close. That process works, I do get the success output, but the image doesn't appear as the category image. It just stays the default background color.

  • NodeBB

    That could be due to cache, did you try clearing the object cache at /admin/advanced/cache?

Suggested Topics

  • 7
  • 16
  • 7
  • 2
  • 2
| |