diff options
Diffstat (limited to 'mastoapi.c')
| -rw-r--r-- | mastoapi.c | 57 |
1 files changed, 45 insertions, 12 deletions
| @@ -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 |