Bugs in Xibo Api

While working with Xibo API, we experienced some Bugs. The CMS version is 2.1:

1. Wrong start value in response header next-link

The correct order would be

First page (0-10):   http://localhost/api/layout?start=0&length=10
Second page (10-20): http://localhost/api/layout?start=10&length=10
Third page (20-30):  http://localhost/api/layout?start=20&length=10

However, Xibo’s API skips over the second page.

GET https://xxx.yyy.com/api/layout?length=2&start=0 returns a response with the following header

Link <https://xxx.yyy.com/api/layout?start=4&length=2>; rel="next", 
<https://xxx.yyy.com/api/layout?start=0&length=2>; rel="first"

Bug: start is 4, instead of 2. It has been incremented twice for some unknown reason.

Additionally, GET https://xxx.yyy.com/api/layout?start=4&length=2
returns a response with the following header

Link <https://xxx.yyy.com/api/layout?start=8&length=2>; rel="next", 
<https://xxx.yyy.com/api/layout?start=2&length=2>; rel="prev", 
<https://xxx.yyy.com/api/layout?start=0&length=2>; rel="first"

The prev is correct, however start=8 instead of the expected 6

Even the Xibo documentation has this bug https://xibo.org.uk/docs/developer/cms-api-overview#grid_data_-_lists_of_records

2. Swagger documentation doesn’t distinguish between multipart/form-data and application/x-www-form-urlencoded

e.g. PUT https://xxx.yyy.com/api/playlist/widget/{widgetId}/audio only accepts application/x-www-form-urlencoded while POST https://xxx.yyy.com/api/library accepts both.

3. Trailing / in a URL leads to different behaviour

POST https://xxx.yyy.com/api/library/ leads to an error message

{
  "error": {
    "message": "Seite nicht gefunden",
    "code": 404,
    "data": []
  }
}

while POST https://xxx.yyy.com/api/library (without a trailing slash) works as intended

4. OAuth access_code user needs to a superadmin

This seems to be a direct consequence of the fact that Xibo can only create applications with the All permission. Everything else is not accepted.

5. Xibo library search cannot handle special characters such as ( )

Brackets are surprisingly common characters in file names, and yet Xibo’s library search doesn’t handle them correctly. An example of such a file name is Screenshot (1).png

GET https://xxx.yyy.com/api/library?media=Screenshot%20(1).png will return [ ], in other words, nothing.
However GET https://xxx.yyy.com/api/library?media=Screenshot%20(1) will gladly return the file. Even ``GET https://xxx.yyy.com/api/library?media=Screenshot%20(1).with a dot will return the file. It's not an issue with file name extensions breaking the search, because searching for a previously uploadedindex.html` works flawlessly

6. Embedded Widgets cannot handle special characters

HTML to Embed

<h1> This works </h2>
<h2> However, this will get cut off right 🦈 where the shark is </h2>

This is because Xibo apparently cannot handle any Unicode astral symbols. Other examples of such symbols are 𝄞, 𝐁, 😀

7. Inconsistent /library return JSON

GET https://xxx.yyy.com/api/library returns a response with a mediaType.

However, when uploading a file using POST, it will return a response without a mediaType (e.g. "mediaType": "image"). Instead it returns a response with a type (e.g. "type": "image").

8. Date format

API is wildly inconsistent with which date format it uses and returns. To make matters worse, it’s undocumented. Apparently when calling PUT ​https://xxx.yyy.com/api/playlist/widget/${widgetId}/expiry Xibo wants a date in the format Y-m-d H:i:s. This is a rather non-standard date format and using the ISO date format would be a vastly superior choice.
And when getting an expiry date, the API returns a Unix timestamp and apparently suffers from the year 2038-millennium bug.
Also, occasionally, I’ve encountered Xibo returning a date as a string-number such as "1567716614562" instead of 1567716614562

9. Add webpage widget to layout using the API is still not documented

This rather important feature hasn’t been documented since 2016. You have to dig through the Xibo forum to find it.

10. Put playlist item clears some optional parameters

PUT ​https://xxx.yyy.com/api/playlist​/widget​/{widgetId} results in a number of optional parameters simply being set to empty values.
e.g. useDuration, effect, speed, backgroundColor will simply be erased. However, duration will stay.

11. No documented way to get a widget

You have to use a PUT call to do what a GET call is supposed to do.
As in, PUT ​https://xxx.yyy.com/api/playlist​/widget​/{widgetId} to get a widget

12. Text widget cannot update duration without setting text

Not a bug, but rather sub-optimal API design. You cannot update the duration of a text-widget without also setting the text again.

Form data
duration: 6
useDuration: 1

results in

{
    "error": {
        "message": "Please enter some text",
        "code": 422,
        "data": {
            "property": "text"
        }
    }
}

Best regards

Thank you for your feedback.

You certainly raised some good points, we will go over your post in the next few days, create issue reports and fixes as needed.

I’ve created couple of issues in GitHub from your post, please see the details below.

1 - I agree, reported here - https://github.com/xibosignage/xibo/issues/1963

2 - All PUT calls need application/x-www-form-urlencoded content type header, but we can certainly improve our API documentation, logged here - https://github.com/xibosignage/xibo/issues/1964

3 - In our opinion the trailing slash added means it’s a different URL and as such 404 is expected.

4 - That’s by design, however it may become more configurable in the future.

5 - Agreed, Reported here - https://github.com/xibosignage/xibo/issues/1965

6 - We will look into this - https://github.com/xibosignage/xibo/issues/1966

7 - Agreed - https://github.com/xibosignage/xibo/issues/1967

8 - Agreed that it needs investigation, however we will not use the ISO date format - https://github.com/xibosignage/xibo/issues/1968

9 - Indeed it will need some improvements - https://github.com/xibosignage/xibo/issues/1969

10 & 12 - that’s by design, we’re replacing whole object on PUT call, we will make it clearer in the API documentation.

11 - There is a GET /playlist/widget call that can take either playlistId or widgetId, it’s there in the API documentation in Playlist section, however it has the same operationId as GET /playlist which we will fix in 2.1.1 - reported here https://github.com/xibosignage/xibo/issues/1970

Thank you for bringing this to our attention.