From ee607734d8effdfb3a1a163e59153546a6ae9506 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 15 Dec 2024 15:17:38 +0100 Subject: mastoapi: fixed incorrect field 'bot' for newly created accounts. --- mastoapi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index 990898b..d844b42 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1193,10 +1193,13 @@ int process_auth_token(snac *snac, const xs_dict *req) return logged_in; } + void credentials_get(char **body, char **ctype, int *status, snac snac) { xs *acct = xs_dict_new(); + const xs_val *bot = xs_dict_get(snac.config, "bot"); + acct = xs_dict_append(acct, "id", snac.md5); acct = xs_dict_append(acct, "username", xs_dict_get(snac.config, "uid")); acct = xs_dict_append(acct, "acct", xs_dict_get(snac.config, "uid")); @@ -1206,7 +1209,7 @@ void credentials_get(char **body, char **ctype, int *status, snac snac) acct = xs_dict_append(acct, "note", xs_dict_get(snac.config, "bio")); acct = xs_dict_append(acct, "url", snac.actor); acct = xs_dict_append(acct, "locked", xs_stock(XSTYPE_FALSE)); - acct = xs_dict_append(acct, "bot", xs_dict_get(snac.config, "bot")); + acct = xs_dict_append(acct, "bot", xs_stock(xs_is_true(bot) ? XSTYPE_TRUE : XSTYPE_FALSE)); acct = xs_dict_append(acct, "emojis", xs_stock(XSTYPE_LIST)); xs *src = xs_json_loads("{\"privacy\":\"public\", \"language\":\"en\"," @@ -1220,7 +1223,7 @@ void credentials_get(char **body, char **ctype, int *status, snac snac) src = xs_dict_set(src, "sensitive", strcmp(cw, "open") == 0 ? xs_stock(XSTYPE_TRUE) : xs_stock(XSTYPE_FALSE)); - src = xs_dict_set(src, "bot", xs_dict_get(snac.config, "bot")); + src = xs_dict_set(src, "bot", xs_stock(xs_is_true(bot) ? XSTYPE_TRUE : XSTYPE_FALSE)); xs *avatar = NULL; const char *av = xs_dict_get(snac.config, "avatar"); -- cgit v1.2.3 From b2d301de2d5956b17ee0e26201bca952c4269e27 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 15 Dec 2024 15:23:28 +0100 Subject: mastoapi: deleted useless code. --- mastoapi.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index d844b42..4d0c063 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1322,7 +1322,7 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn const char *max_id = xs_dict_get(args, "max_id"); const char *since_id = xs_dict_get(args, "since_id"); - const char *min_id = xs_dict_get(args, "min_id"); +// const char *min_id = xs_dict_get(args, "min_id"); /* unsupported old-to-new navigation */ const char *limit_s = xs_dict_get(args, "limit"); int limit = 0; int cnt = 0; @@ -1351,13 +1351,6 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn break; } - /* only returns entries newer than min_id */ - /* what does really "Return results immediately newer than ID" mean? */ - if (min_id) { - if (strcmp(md5, MID_TO_MD5(min_id)) == 0) - break; - } - /* get the entry */ if (user) { if (!valid_status(timeline_get_by_md5(user, md5, &msg))) -- cgit v1.2.3 From e8ae4920f6758c064bccba63f0a74d09ab57b751 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 15 Dec 2024 15:47:27 +0100 Subject: Fixed crash in mastoapi_status() Emoji list. --- mastoapi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index 4d0c063..be8be80 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -990,7 +990,7 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg) const char *o_url = xs_dict_get(icon, "url"); if (!xs_is_null(o_url)) { - xs *url = make_url(o_url, snac->actor, 1); + xs *url = make_url(o_url, snac ? snac->actor : NULL, 1); xs *nm = xs_strip_chars_i(xs_dup(name), ":"); d1 = xs_dict_append(d1, "shortcode", nm); @@ -1322,7 +1322,7 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn const char *max_id = xs_dict_get(args, "max_id"); const char *since_id = xs_dict_get(args, "since_id"); -// const char *min_id = xs_dict_get(args, "min_id"); /* unsupported old-to-new navigation */ + const char *min_id = xs_dict_get(args, "min_id"); /* unsupported old-to-new navigation */ const char *limit_s = xs_dict_get(args, "limit"); int limit = 0; int cnt = 0; @@ -1333,7 +1333,7 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn if (limit == 0) limit = 20; - if (index_desc_first(f, md5, 0)) { + if (min_id == NULL && index_desc_first(f, md5, 0)) { do { xs *msg = NULL; -- cgit v1.2.3 From c6562fa39bc3b609429fea9064a94cf080922da5 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 15 Dec 2024 22:52:41 +0100 Subject: New function timeline_link_header(). --- mastoapi.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index be8be80..6b816f4 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1434,8 +1434,35 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn } +xs_str *timeline_link_header(const char *endpoint, xs_list *timeline) +/* returns a Link header with paging information */ +{ + xs_str *s = NULL; + + if (xs_list_len(timeline) == 0) + return NULL; + + const xs_dict *first_st = xs_list_get(timeline, 0); + const xs_dict *last_st = xs_list_get(timeline, -1); + const char *first_id = xs_dict_get(first_st, "id"); + const char *last_id = xs_dict_get(last_st, "id"); + const char *host = xs_dict_get(srv_config, "host"); + const char *protocol = xs_dict_get_def(srv_config, "protocol", "https"); + + s = xs_fmt( + "<%s:/" "/%s%s?max_id=%s>; rel=\"next\", " + "<%s:/" "/%s%s?since_id=%s>; rel=\"prev\"", + protocol, host, endpoint, last_id, + protocol, host, endpoint, first_id); + + srv_debug(1, xs_fmt("timeline_link_header %s", s)); + + return s; +} + + int mastoapi_get_handler(const xs_dict *req, const char *q_path, - char **body, int *b_size, char **ctype) + char **body, int *b_size, char **ctype, xs_str **link) { (void)b_size; @@ -1695,6 +1722,8 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, xs *ifn = user_index_fn(&snac1, "private"); xs *out = mastoapi_timeline(&snac1, args, ifn); + *link = timeline_link_header(cmd, out); + *body = xs_json_dumps(out, 4); *ctype = "application/json"; status = HTTP_STATUS_OK; -- cgit v1.2.3 From b010be81807295e4336443a4f8b12d0513b436a5 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 15 Dec 2024 23:25:11 +0100 Subject: Fixed bad url in timeline link. --- mastoapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index 6b816f4..2c8c04d 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1722,7 +1722,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, xs *ifn = user_index_fn(&snac1, "private"); xs *out = mastoapi_timeline(&snac1, args, ifn); - *link = timeline_link_header(cmd, out); + *link = timeline_link_header("/api/v1/timelines/home", out); *body = xs_json_dumps(out, 4); *ctype = "application/json"; -- cgit v1.2.3 From fa253f008a0f4d028dbb9ef14c83d6699a133614 Mon Sep 17 00:00:00 2001 From: Paul Martin Date: Thu, 19 Dec 2024 19:55:56 +0000 Subject: Implement mastoapi markers for notifications and home. --- mastoapi.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 7 deletions(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index 2c8c04d..c78c380 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1788,6 +1788,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, xs *out = xs_list_new(); const xs_dict *v; const xs_list *excl = xs_dict_get(args, "exclude_types[]"); + const char *min_id = xs_dict_get(args, "min_id"); const char *max_id = xs_dict_get(args, "max_id"); xs_list_foreach(l, v) { @@ -1814,10 +1815,14 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, continue; if (max_id) { - if (strcmp(fid, max_id) == 0) - max_id = NULL; + if (strcmp(fid, max_id) > 0) + continue; + } - continue; + if (min_id) { + if (strcmp(fid, min_id) <= 0) { + continue; + } } /* convert the type */ @@ -2298,9 +2303,22 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, } else if (strcmp(cmd, "/v1/markers") == 0) { /** **/ - *body = xs_dup("{}"); - *ctype = "application/json"; - status = HTTP_STATUS_OK; + if (logged_in) { + const xs_list *timeline = xs_dict_get(args, "timeline[]"); + xs_str *json = NULL; + if (!xs_is_null(timeline)) + json = xs_json_dumps(markers_get(&snac1, timeline), 4); + + if (!xs_is_null(json)) + *body = json; + else + *body = xs_dup("{}"); + + *ctype = "application/json"; + status = HTTP_STATUS_OK; + } + else + status = HTTP_STATUS_UNAUTHORIZED; } else if (strcmp(cmd, "/v1/followed_tags") == 0) { /** **/ @@ -2997,9 +3015,35 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path, } } } + } + else if (strcmp(cmd, "/v1/markers") == 0) { /** **/ + xs_str *json = NULL; + if (logged_in) { + const xs_str *home_marker = xs_dict_get(args, "home[last_read_id]"); + if (xs_is_null(home_marker)) { + const xs_dict *home = xs_dict_get(args, "home"); + if (!xs_is_null(home)) + home_marker = xs_dict_get(home, "last_read_id"); + } + + const xs_str *notify_marker = xs_dict_get(args, "notifications[last_read_id]"); + if (xs_is_null(notify_marker)) { + const xs_dict *notify = xs_dict_get(args, "notifications"); + if (!xs_is_null(notify)) + notify_marker = xs_dict_get(notify, "last_read_id"); + } + json = xs_json_dumps(markers_set(&snac, home_marker, notify_marker), 4); + } + if (!xs_is_null(json)) + *body = json; else - status = HTTP_STATUS_UNPROCESSABLE_CONTENT; + *body = xs_dup("{}"); + + *ctype = "application/json"; + status = HTTP_STATUS_OK; } + else + status = HTTP_STATUS_UNPROCESSABLE_CONTENT; /* user cleanup */ if (logged_in) -- cgit v1.2.3 From 664f9cbeefa5af10d37b3f9f7a987e484d0ab885 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 20 Dec 2024 08:33:02 +0100 Subject: Mastoapi: added badlogin support. --- mastoapi.c | 110 ++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 62 insertions(+), 48 deletions(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index 2c8c04d..ea550d6 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -293,47 +293,54 @@ int oauth_post_handler(const xs_dict *req, const char *q_path, snac snac; if (user_open(&snac, login)) { - /* check the login + password */ - if (check_password(login, passwd, xs_dict_get(snac.config, "passwd"))) { - /* success! redirect to the desired uri */ - xs *code = random_str(); + const char *addr = xs_or(xs_dict_get(req, "remote-addr"), + xs_dict_get(req, "x-forwarded-for")); - xs_free(*body); + if (badlogin_check(login, addr)) { + /* check the login + password */ + if (check_password(login, passwd, xs_dict_get(snac.config, "passwd"))) { + /* success! redirect to the desired uri */ + xs *code = random_str(); - if (strcmp(redir, "urn:ietf:wg:oauth:2.0:oob") == 0) { - *body = xs_dup(code); - } - else { - if (xs_str_in(redir, "?") != -1) - *body = xs_fmt("%s&code=%s", redir, code); - else - *body = xs_fmt("%s?code=%s", redir, code); + xs_free(*body); - status = HTTP_STATUS_SEE_OTHER; - } + if (strcmp(redir, "urn:ietf:wg:oauth:2.0:oob") == 0) { + *body = xs_dup(code); + } + else { + if (xs_str_in(redir, "?") != -1) + *body = xs_fmt("%s&code=%s", redir, code); + else + *body = xs_fmt("%s?code=%s", redir, code); - /* if there is a state, add it */ - if (!xs_is_null(state) && *state) { - *body = xs_str_cat(*body, "&state="); - *body = xs_str_cat(*body, state); - } + status = HTTP_STATUS_SEE_OTHER; + } - srv_log(xs_fmt("oauth x-snac-login: '%s' success, redirect to %s", + /* if there is a state, add it */ + if (!xs_is_null(state) && *state) { + *body = xs_str_cat(*body, "&state="); + *body = xs_str_cat(*body, state); + } + + srv_log(xs_fmt("oauth x-snac-login: '%s' success, redirect to %s", login, *body)); - /* assign the login to the app */ - xs *app = app_get(cid); + /* assign the login to the app */ + xs *app = app_get(cid); - if (app != NULL) { - app = xs_dict_set(app, "uid", login); - app = xs_dict_set(app, "code", code); - app_add(cid, app); + if (app != NULL) { + app = xs_dict_set(app, "uid", login); + app = xs_dict_set(app, "code", code); + app_add(cid, app); + } + else + srv_log(xs_fmt("oauth x-snac-login: error getting app %s", cid)); + } + else { + srv_debug(1, xs_fmt("oauth x-snac-login: login '%s' incorrect", login)); + badlogin_inc(login, addr); } - else - srv_log(xs_fmt("oauth x-snac-login: error getting app %s", cid)); } - else - srv_debug(1, xs_fmt("oauth x-snac-login: login '%s' incorrect", login)); user_free(&snac); } @@ -474,29 +481,36 @@ int oauth_post_handler(const xs_dict *req, const char *q_path, snac user; if (user_open(&user, login)) { - /* check the login + password */ - if (check_password(login, passwd, xs_dict_get(user.config, "passwd"))) { - /* success! create a new token */ - xs *tokid = random_str(); + const char *addr = xs_or(xs_dict_get(req, "remote-addr"), + xs_dict_get(req, "x-forwarded-for")); + + if (badlogin_check(login, addr)) { + /* check the login + password */ + if (check_password(login, passwd, xs_dict_get(user.config, "passwd"))) { + /* success! create a new token */ + xs *tokid = random_str(); - srv_debug(1, xs_fmt("x-snac-new-token: " + srv_debug(1, xs_fmt("x-snac-new-token: " "successful login for %s, new token %s", login, tokid)); - xs *token = xs_dict_new(); - token = xs_dict_append(token, "token", tokid); - token = xs_dict_append(token, "client_id", "snac-client"); - token = xs_dict_append(token, "client_secret", ""); - token = xs_dict_append(token, "uid", login); - token = xs_dict_append(token, "code", ""); + xs *token = xs_dict_new(); + token = xs_dict_append(token, "token", tokid); + token = xs_dict_append(token, "client_id", "snac-client"); + token = xs_dict_append(token, "client_secret", ""); + token = xs_dict_append(token, "uid", login); + token = xs_dict_append(token, "code", ""); - token_add(tokid, token); + token_add(tokid, token); - *ctype = "text/plain"; - xs_free(*body); - *body = xs_dup(tokid); - } + *ctype = "text/plain"; + xs_free(*body); + *body = xs_dup(tokid); + } + else + badlogin_inc(login, addr); - user_free(&user); + user_free(&user); + } } } } -- cgit v1.2.3 From 1167b64f8ff4de9a782feba01c67fef9d75ea3a6 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 20 Dec 2024 09:45:11 +0100 Subject: mastoapi: minor tweak to notification list (Tusky was in a forever request loop). --- mastoapi.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index 59b0515..96aa3ac 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1805,6 +1805,11 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, const char *min_id = xs_dict_get(args, "min_id"); const char *max_id = xs_dict_get(args, "max_id"); + if (dbglevel) { + xs *js = xs_json_dumps(args, 0); + srv_debug(1, xs_fmt("mastoapi_notifications args %s", js)); + } + xs_list_foreach(l, v) { xs *noti = notify_get(&snac1, v); @@ -1829,8 +1834,10 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, continue; if (max_id) { - if (strcmp(fid, max_id) > 0) - continue; + if (strcmp(fid, max_id) == 0) + max_id = NULL; + + continue; } if (min_id) { @@ -1886,6 +1893,8 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, out = xs_list_append(out, mn); } + srv_debug(1, xs_fmt("mastoapi_notifications count %d", xs_list_len(out))); + *body = xs_json_dumps(out, 4); *ctype = "application/json"; status = HTTP_STATUS_OK; @@ -3002,6 +3011,7 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path, status = HTTP_STATUS_UNPROCESSABLE_CONTENT; } } + else if (xs_startswith(cmd, "/v1/lists/")) { /** list maintenance **/ if (logged_in) { xs *l = xs_split(cmd, "/"); -- cgit v1.2.3 From 00004500a9b56ca22cfe5e6949ea5072d0a63414 Mon Sep 17 00:00:00 2001 From: default Date: Sat, 21 Dec 2024 16:49:45 +0100 Subject: mastoapi: fixed audio attachments. --- mastoapi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index 96aa3ac..3f8b59d 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -912,7 +912,7 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg) const char *o_href = xs_dict_get(v, "href"); const char *name = xs_dict_get(v, "name"); - if (xs_match(type, "image/*|video/*|Image|Video")) { /* */ + if (xs_match(type, "image/*|video/*|audio/*|Image|Video")) { /* */ xs *matteid = xs_fmt("%s_%d", id, xs_list_len(matt)); xs *href = make_url(o_href, proxy, 1); @@ -924,7 +924,8 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg) d = xs_dict_append(d, "remote_url", href); d = xs_dict_append(d, "description", name); - d = xs_dict_append(d, "type", (*type == 'v' || *type == 'V') ? "video" : "image"); + d = xs_dict_append(d, "type", (*type == 'v' || *type == 'V') ? "video" : + (*type == 'a' || *type == 'A') ? "audio" : "image"); matt = xs_list_append(matt, d); } -- cgit v1.2.3 From 0bbecf53a670202334128b1372cfc5d83273fbf1 Mon Sep 17 00:00:00 2001 From: default Date: Sun, 22 Dec 2024 09:26:17 +0100 Subject: mastoapi: allow search for post URLs. --- mastoapi.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index 3f8b59d..09e18a1 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -2377,6 +2377,37 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, if (xs_is_null(offset) || strcmp(offset, "0") == 0) { /* reply something only for offset 0; otherwise, apps like Tusky keep asking again and again */ + if (xs_startswith(q, "https://")) { + xs *md5 = xs_md5_hex(q, strlen(q)); + + if (!timeline_here(&snac1, md5)) { + xs *object = NULL; + int status; + + status = activitypub_request(&snac1, q, &object); + snac_debug(&snac1, 1, xs_fmt("Request searched URL %s %d", q, status)); + + if (valid_status(status)) { + /* got it; also request the actor */ + const char *attr_to = get_atto(object); + xs *actor_obj = NULL; + + if (!xs_is_null(attr_to)) { + status = actor_request(&snac1, attr_to, &actor_obj); + + snac_debug(&snac1, 1, xs_fmt("Request author %s of %s %d", attr_to, q, status)); + + if (valid_status(status)) { + /* add the actor */ + actor_add(attr_to, actor_obj); + + /* add the post to the timeline */ + timeline_add(&snac1, q, object); + } + } + } + } + } if (!xs_is_null(q)) { if (xs_is_null(type) || strcmp(type, "accounts") == 0) { -- cgit v1.2.3