Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose the settings API to other clients #3529

Closed
1 task done
n1k0 opened this issue Jun 3, 2017 · 4 comments
Closed
1 task done

Expose the settings API to other clients #3529

n1k0 opened this issue Jun 3, 2017 · 4 comments

Comments

@n1k0
Copy link

n1k0 commented Jun 3, 2017

I'm one of the developer of Tooty, a Web client for Mastodon. I see on the official client that the /api/web/settings endpoint is used to persist settings for notifications, filters and so on, and I'd love using it as well for Tooty, so its users could use the same settings as with the official client.

While it seems I can update settings using PUT /api/web/settings and a Bearer token, I couldn't find any other place for GETting the settings from the server than /web/getting-started, which only delivers HTML with a script tag containing the JSON for settings.

I'm obviously not gonna scrape HTML to extract the JSON bits I'm interested in, and I understand that this settings API is undocumented and I should not rely on it; though I'd really like bringing the issue to the table, do we want clients to access this feature? I think that could bring consistency to the ecosystem.

Note that from a server side implementation perspective, that'd be just matter of enabling GET to the /api/web/settings endpoint, exposing the settings as JSON, and documenting the feature officially.

Thoughts?


  • I searched or browsed the repo’s other issues to ensure this is not a duplicate.
@Gargron
Copy link
Member

Gargron commented Jun 3, 2017

/api/web is a persistence layer for the JavaScript state in the web UI, nothing more. I would have used localStorage if it would be accessed from one device only, but it can be accessed through any, so it had to persist between devices, therefore that internal API. You can't use it with an access token, only a valid session.

@n1k0
Copy link
Author

n1k0 commented Jun 3, 2017

I understand the point of app state persistence, right. I still feel like settings persistence, interoperability and sharing accross devices might be something worth to users, though.

No big deal. Just so you know and FWIW, I confirm one can update the settings just using the bearer token, no webapp cookie needed. Here's a sample trace from Insomnia, obfuscated on purpose:

* Preparing request to https://mamot.fr/api/web/settings
* Enable automatic URL encoding
* Enable SSL validation
* Replaced cookie _mastodon_session="cVRrRy8yTHFGRTFTK3hNaEJuMXNpQ2c1M00vWElUdVVka0VnNFUzd3BPM0VwZE52V2VxbFFEYmpOem8rZjFTK3BHT2NuNzZucEl5d291YzNXVEIvSzZRckFrblJYVGxMUlFHZEI2NzhKbUxFV1Q5ekNGc051QjJ4OGVQZVhkazMtLXhWVXlZVHhJSE1zcmJNcU11eVNVWFE9PQ%3D%3D--6670c1334a551d9f1d922eea9c0c6eb3a2837d67" for domain mamot.fr, path /, expire 0
* Enable cookie sending with jar of 2 cookies
*   Trying 185.34.33.7...
* Connected to mamot.fr (185.34.33.7) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /tmp/insomnia/2017-01-18.pem
*   CApath: /etc/ssl/certs
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
* 	 subject: CN=mamot.fr
* 	 start date: Apr  6 10:08:00 2017 GMT
* 	 expire date: Jul  5 10:08:00 2017 GMT
* 	 subjectAltName: mamot.fr matched
* 	 issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* 	 SSL certificate verify ok.
> PUT /api/web/settings HTTP/1.1
> Host: mamot.fr
> User-Agent: insomnia/5.1.1
> Accept: */*
> Accept-Encoding: deflate, gzip
> Cookie: _mastodon_session=cVRrRy8yTHFGRTFTK3hNaEJuMXNpQ2c1M00vWElUdVVka0VnNFUzd3BPM0VwZE52V2VxbFFEYmpOem8rZjFTK3BHT2NuNzZucEl5d291YzNXVEIvSzZRckFrblJYVGxMUlFHZEI2NzhKbUxFV1Q5ekNGc051QjJ4OGVQZVhkazMtLXhWVXlZVHhJSE1zcmJNcU11eVNVWFE9PQ%3D%3D--6670c1334a551d9f1d922eea9c0c6eb3a2837d67
> Content-Type: application/json
> Authorization: Bearer <obfuscated_bearer_token>
> Content-Length: 603
| {
|   "data": {
|     "onboarded": true,
|     "home": {
|       "shows": {
|         "reblog": true,
|         "reply": true
|       },
|       "regex": {
|         "body": "test_should_appear_on_official_web_client"
|       }
|     },
|     "notifications": {
|       "alerts": {
|         "follow": false,
|         "favourite": false,
|         "reblog": false,
|         "mention": true
|       },
|       "shows": {
|         "follow": true,
|         "favourite": false,
|         "reblog": false,
|         "mention": true
|       },
|       "sounds": {
|         "follow": false,
|         "favourite": false,
|         "reblog": false,
|         "mention": true
|       }
|     }
|   }
| }
* upload completely sent off: 603 out of 603 bytes
< HTTP/1.1 200 OK
< Date: Sat, 03 Jun 2017 13:39:28 GMT
< Content-Type: application/json; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Server: Mastodon
< X-Frame-Options: DENY
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Vary: Accept-Encoding, Origin
< Content-Encoding: deflate
< ETag: W/"462f732abd055db85c16dbc4921bb5d3"
< Cache-Control: max-age=0, private, must-revalidate
< X-Request-Id: 84fff8f1-0462-406c-9e38-ac6bc6c42ba8
< X-Runtime: 0.027019
< Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
< Referrer-Policy: strict-origin-when-cross-origin
< Content-Security-Policy: default-src 'none'; font-src 'self'; media-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self'; img-src 'self' https://img.pawoo.net https://pawoo.net data:; connect-src 'self' wss://mamot.fr;

* Received 15 B chunk
* Received 5 B chunk
* Connection #0 to host mamot.fr left intact
* Ignored 0 cookies

test_should_appear_on_official_web_client appears just fine on the web client. If you don't want to add support for settings to the API, maybe that's still something you want to investigate.

@n1k0 n1k0 closed this as completed Jun 3, 2017
@Gargron
Copy link
Member

Gargron commented Jun 3, 2017

You sent a cookie along, are you sure that isn't an authenticated session?

If not I think I know what kind of accidental regression may have changed it around to accepting access tokens. That's not a big deal but not intended.

@n1k0
Copy link
Author

n1k0 commented Jun 3, 2017

Yes I'm sure, here's another trace without no cookie passed at all.

* Preparing request to https://mamot.fr/api/web/settings
* Enable automatic URL encoding
* Enable SSL validation
* Enable cookie sending with jar of 0 cookies
* Found bundle for host mamot.fr: 0x1c66abf263a0 [can pipeline]
* Re-using existing connection! (#0) with host mamot.fr
* Connected to mamot.fr (185.34.33.7) port 443 (#0)
> PUT /api/web/settings HTTP/1.1
> Host: mamot.fr
> User-Agent: insomnia/5.1.1
> Accept: */*
> Accept-Encoding: deflate, gzip
> Content-Type: application/json
> Authorization: Bearer <xxx>
> Content-Length: 602
| {
|   "data": {
|     "onboarded": true,
|     "home": {
|       "shows": {
|         "reblog": true,
|         "reply": true
|       },
|       "regex": {
|         "body": "test here"
|       }
|     },
|     "notifications": {
|       "alerts": {
|         "follow": false,
|         "favourite": false,
|         "reblog": false,
|         "mention": true
|       },
|       "shows": {
|         "follow": true,
|         "favourite": false,
|         "reblog": false,
|         "mention": true
|       },
|       "sounds": {
|         "follow": false,
|         "favourite": false,
|         "reblog": false,
|         "mention": true
|       }
|     }
|   }
| }
* upload completely sent off: 602 out of 602 bytes
< HTTP/1.1 200 OK
< Date: Sat, 03 Jun 2017 14:27:43 GMT
< Content-Type: application/json; charset=utf-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< Server: Mastodon
< X-Frame-Options: DENY
< X-Content-Type-Options: nosniff
< X-XSS-Protection: 1; mode=block
< Vary: Accept-Encoding, Origin
< Content-Encoding: deflate
< ETag: W/"462f732abd055db85c16dbc4921bb5d3"
< Cache-Control: max-age=0, private, must-revalidate
< X-Request-Id: e2dbfaeb-bf8f-40da-8e70-6846852665b4
< X-Runtime: 0.021147
< Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
< Referrer-Policy: strict-origin-when-cross-origin
< Content-Security-Policy: default-src 'none'; font-src 'self'; media-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self'; img-src 'self' https://img.pawoo.net https://pawoo.net data:; connect-src 'self' wss://mamot.fr;

* Received 15 B chunk
* Received 5 B chunk
* Connection #0 to host mamot.fr left intact
* Ignored 0 cookies

Yes that's no big deal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants