Update category picture (via image upload) API not working
-
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
-
Have you tried uploading that file through the NodeBB UI?
-
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
-
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?
-
I'm pretty sure this same API is used when you upload an image through the UI.
@julian can you take a look?
-
@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.
-
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.
-
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.
-
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" } ]