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

  • @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
    * TCP_NODELAY set
    * Connected to ( port 4567 (#0)
    > POST /api/admin/category/uploadpicture HTTP/1.1
    > Host:
    > 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 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 Admin

    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 and then storing the cookies then we use it to make POST requests.

  • NodeBB Admin

    This worked for me give it a try

    # get csrf token and save cookies
    curl -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[][email protected]:\ideas.png" \
      -F "_csrf=bHqyDEde-Y_zLYuitkD4uc5Cd7-0mYF1m5GU"  \
      -b cookies.txt \

    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 Admin

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

  • @baris thanks, just tried that and it didn't work. Is there a 3rd step to actually placing the image?

  • NodeBB Admin

    Ahh yes you need to set the backgroundImage property of category:2 to the value of "url": "/assets/uploads/category/category-2.png"

  • @baris Thank-you, found it, it is a PUT on the write API. First go, I got the syntax mostly correct, I got a 200 OK message, but the Response:backgroundImage key was empty.

    I will poke at this more after dinner, but I think we can call this one solved, since it is just a matter of figuring out the right syntax at this point.

  • @baris Using the below site, reminding me of just how powerful Chrome Developers tools are, I was able to Copy As Curl the specific PUT command.

    Curl Convert

    Then using the same command and just changing the CID, I confirmed the same command works for all of them.

    This is what ended up working, it includes all the recorded headers, of which some will be removed as not necessary:

    curl '' \
      -X 'PUT' \
      -H 'Connection: keep-alive' \
      -H 'Accept: */*' \
      -H 'DNT: 1' \
      -H 'x-csrf-token: H5FMJEaY-CthHWM_2Unzf7DtoPeryGq_JejE' \
      -H 'X-Requested-With: XMLHttpRequest' \
      -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36' \
      -H 'Content-Type: application/json; charset=UTF-8' \
      -H 'Origin:' \
      -H 'Referer:' \
      -H 'Accept-Language: en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7,zh-TW;q=0.6,ja;q=0.5,ko;q=0.4,th;q=0.3' \
      -H 'Cookie: _csrf=27ygKMdG0c0EyiVsJKAkKpId; express.sid=s%3AdODaXfUpLz7NTFsijWLq0d2rPUhH1Ki4.qkyxWOaxlBy%2BLDRpTYbhWS9QkD9IJE%2FRTN1vIhp7yV4' \
      -H 'sec-gpc: 1' \
      --data '{"backgroundImage":"/assets/uploads/category/category-84.jpg"}' \
      --compressed \

    Then using the cURL convert site, was able to save as javascript and modify to our needs so that we could loop through all categories.


  • Topic has been marked as solved   J   jpop71 

Suggested Topics

| | | |