summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RELEASE_NOTES.md2
-rw-r--r--mastoapi.c57
2 files changed, 46 insertions, 13 deletions
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index b0d37f4..e3cefa4 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -10,7 +10,7 @@ The avatar and/or the header images can now be deleted (contributed by louis77).
10 10
11Code cleaning: HTTP status codes use names instead of hardcoded integers (contributed by louis77). 11Code cleaning: HTTP status codes use names instead of hardcoded integers (contributed by louis77).
12 12
13Mastodon API: some fixes for Mona and Tokodon apps, user credentials can now be edited from apps (contributed by louis77). 13Mastodon API: fixed login problems with the official Mastodon API, IceCube and Toot! on iOS, some fixes for Mona and Tokodon apps, user credentials can now be edited from apps (contributed by louis77).
14 14
15The webfinger content-type response header is now RFC-compliant (contributed by steve-bate). 15The webfinger content-type response header is now RFC-compliant (contributed by steve-bate).
16 16
diff --git a/mastoapi.c b/mastoapi.c
index 03d081d..2337007 100644
--- a/mastoapi.c
+++ b/mastoapi.c
@@ -152,6 +152,7 @@ const char *login_page = ""
152"<html>\n" 152"<html>\n"
153"<head>\n" 153"<head>\n"
154"<title>%s OAuth - Snac2</title>\n" 154"<title>%s OAuth - Snac2</title>\n"
155"<meta content=\"width=device-width, initial-scale=1, minimum-scale=1, user-scalable=no\" name=\"viewport\">"
155"<style>:root {color-scheme: light dark}</style>\n" 156"<style>:root {color-scheme: light dark}</style>\n"
156"</head>\n" 157"</head>\n"
157"<body><h1>%s OAuth identify</h1>\n" 158"<body><h1>%s OAuth identify</h1>\n"
@@ -338,11 +339,7 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
338 const char *cid = xs_dict_get(args, "client_id"); 339 const char *cid = xs_dict_get(args, "client_id");
339 const char *csec = xs_dict_get(args, "client_secret"); 340 const char *csec = xs_dict_get(args, "client_secret");
340 const char *ruri = xs_dict_get(args, "redirect_uri"); 341 const char *ruri = xs_dict_get(args, "redirect_uri");
341 /* FIXME: this 'scope' parameter is mandatory for the official Mastodon API, 342 const char *scope = xs_dict_get(args, "scope");
342 but if it's enabled, it makes it crash after some more steps, which
343 is FAR WORSE */
344 const char *scope = NULL;
345// scope = xs_dict_get(args, "scope");
346 343
347 /* no client_secret? check if it's inside an authorization header 344 /* no client_secret? check if it's inside an authorization header
348 (AndStatus does it this way) */ 345 (AndStatus does it this way) */
@@ -1164,8 +1161,10 @@ void credentials_get(char **body, char **ctype, int *status, snac snac)
1164 acct = xs_dict_append(acct, "url", snac.actor); 1161 acct = xs_dict_append(acct, "url", snac.actor);
1165 acct = xs_dict_append(acct, "locked", xs_stock(XSTYPE_FALSE)); 1162 acct = xs_dict_append(acct, "locked", xs_stock(XSTYPE_FALSE));
1166 acct = xs_dict_append(acct, "bot", xs_dict_get(snac.config, "bot")); 1163 acct = xs_dict_append(acct, "bot", xs_dict_get(snac.config, "bot"));
1164 acct = xs_dict_append(acct, "emojis", xs_stock(XSTYPE_LIST));
1167 1165
1168 xs *src = xs_json_loads("{\"privacy\":\"public\"," 1166 xs *src = xs_json_loads("{\"privacy\":\"public\", \"language\":\"en\","
1167 "\"follow_requests_count\": 0,"
1169 "\"sensitive\":false,\"fields\":[],\"note\":\"\"}"); 1168 "\"sensitive\":false,\"fields\":[],\"note\":\"\"}");
1170 /* some apps take the note from the source object */ 1169 /* some apps take the note from the source object */
1171 src = xs_dict_set(src, "note", xs_dict_get(snac.config, "bio")); 1170 src = xs_dict_set(src, "note", xs_dict_get(snac.config, "bio"));
@@ -1447,9 +1446,27 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1447 if (strcmp(opt, "featured_tags") == 0) { 1446 if (strcmp(opt, "featured_tags") == 0) {
1448 /* snac doesn't have features tags, yet? */ 1447 /* snac doesn't have features tags, yet? */
1449 /* implement empty response so apps like Tokodon don't show an error */ 1448 /* implement empty response so apps like Tokodon don't show an error */
1450 *body = xs_dup("[]"); 1449 out = xs_list_new();
1451 *ctype = "application/json"; 1450 }
1452 status = HTTP_STATUS_OK; 1451 else
1452 if (strcmp(opt, "following") == 0) {
1453 xs *wing = following_list(&snac1);
1454 out = xs_list_new();
1455 int c = 0;
1456 const char *v;
1457
1458 while (xs_list_next(wing, &v, &c)) {
1459 xs *actor = NULL;
1460
1461 if (valid_status(object_get(v, &actor))) {
1462 xs *acct = mastoapi_account(actor);
1463 out = xs_list_append(out, acct);
1464 }
1465 }
1466 }
1467 else
1468 if (strcmp(opt, "followers") == 0) {
1469 out = xs_list_new();
1453 } 1470 }
1454 1471
1455 user_free(&snac2); 1472 user_free(&snac2);
@@ -1470,9 +1487,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1470 if (strcmp(opt, "featured_tags") == 0) { 1487 if (strcmp(opt, "featured_tags") == 0) {
1471 /* snac doesn't have features tags, yet? */ 1488 /* snac doesn't have features tags, yet? */
1472 /* implement empty response so apps like Tokodon don't show an error */ 1489 /* implement empty response so apps like Tokodon don't show an error */
1473 *body = xs_dup("[]"); 1490 out = xs_list_new();
1474 *ctype = "application/json";
1475 status = HTTP_STATUS_OK;
1476 } 1491 }
1477 } 1492 }
1478 } 1493 }
@@ -2408,6 +2423,14 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
2408 const char *ruri = xs_dict_get(args, "redirect_uris"); 2423 const char *ruri = xs_dict_get(args, "redirect_uris");
2409 const char *scope = xs_dict_get(args, "scope"); 2424 const char *scope = xs_dict_get(args, "scope");
2410 2425
2426 /* Ice Cubes sends these values as query parameters, so try these */
2427 if (name == NULL && ruri == NULL && scope == NULL) {
2428 args = xs_dup(xs_dict_get(req, "q_vars"));
2429 name = xs_dict_get(args, "client_name");
2430 ruri = xs_dict_get(args, "redirect_uris");
2431 scope = xs_dict_get(args, "scope");
2432 }
2433
2411 if (xs_type(ruri) == XSTYPE_LIST) 2434 if (xs_type(ruri) == XSTYPE_LIST)
2412 ruri = xs_dict_get(ruri, 0); 2435 ruri = xs_dict_get(ruri, 0);
2413 2436
@@ -2914,6 +2937,10 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
2914 if (op && id && xs_is_hex(id)) { 2937 if (op && id && xs_is_hex(id)) {
2915 if (strcmp(op, "accounts") == 0) { 2938 if (strcmp(op, "accounts") == 0) {
2916 const xs_list *accts = xs_dict_get(args, "account_ids[]"); 2939 const xs_list *accts = xs_dict_get(args, "account_ids[]");
2940
2941 if (xs_is_null(accts))
2942 accts = xs_dict_get(args, "account_ids");
2943
2917 int c = 0; 2944 int c = 0;
2918 const char *v; 2945 const char *v;
2919 2946
@@ -2921,6 +2948,7 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
2921 list_content(&snac, id, v, 1); 2948 list_content(&snac, id, v, 1);
2922 } 2949 }
2923 2950
2951 *ctype = "application/json";
2924 status = HTTP_STATUS_OK; 2952 status = HTTP_STATUS_OK;
2925 } 2953 }
2926 } 2954 }
@@ -2993,6 +3021,10 @@ int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
2993 /* delete account from list */ 3021 /* delete account from list */
2994 p = xs_list_get(l, -2); 3022 p = xs_list_get(l, -2);
2995 const xs_list *accts = xs_dict_get(args, "account_ids[]"); 3023 const xs_list *accts = xs_dict_get(args, "account_ids[]");
3024
3025 if (xs_is_null(accts))
3026 accts = xs_dict_get(args, "account_ids");
3027
2996 int c = 0; 3028 int c = 0;
2997 const char *v; 3029 const char *v;
2998 3030
@@ -3008,6 +3040,7 @@ int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
3008 } 3040 }
3009 } 3041 }
3010 3042
3043 *ctype = "application/json";
3011 status = HTTP_STATUS_OK; 3044 status = HTTP_STATUS_OK;
3012 } 3045 }
3013 else 3046 else