diff options
| author | 2026-01-24 21:33:30 +0100 | |
|---|---|---|
| committer | 2026-01-24 21:33:30 +0100 | |
| commit | bfd071c63826f4d13d48614cedebfb2f8ea20cf6 (patch) | |
| tree | 8cc9b766b88fa66d051e55d65d6694570553a17b /activitypub.c | |
| parent | Added a Follow/Unfollow button next to a new follow notification. (diff) | |
| parent | Merge pull request 'add susie-q (qr) to artwork' (#528) from pmjv/snac2:maste... (diff) | |
| download | snac2-bfd071c63826f4d13d48614cedebfb2f8ea20cf6.tar.gz snac2-bfd071c63826f4d13d48614cedebfb2f8ea20cf6.tar.xz snac2-bfd071c63826f4d13d48614cedebfb2f8ea20cf6.zip | |
Merge pull request 'master' (#7) from grunfink/snac2:master into main
Reviewed-on: https://codeberg.org/byte/snac2/pulls/7
Diffstat (limited to 'activitypub.c')
| -rw-r--r-- | activitypub.c | 209 |
1 files changed, 195 insertions, 14 deletions
diff --git a/activitypub.c b/activitypub.c index 2c0fa2e..c34e510 100644 --- a/activitypub.c +++ b/activitypub.c | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | /* snac - A simple, minimalistic ActivityPub instance */ | 1 | /* snac - A simple, minimalistic ActivityPub instance */ |
| 2 | /* copyright (c) 2022 - 2025 grunfink et al. / MIT license */ | 2 | /* copyright (c) 2022 - 2026 grunfink et al. / MIT license */ |
| 3 | 3 | ||
| 4 | #include "xs.h" | 4 | #include "xs.h" |
| 5 | #include "xs_json.h" | 5 | #include "xs_json.h" |
| 6 | #include "xs_curl.h" | 6 | #include "xs_curl.h" |
| 7 | #include "xs_url.h" | ||
| 7 | #include "xs_mime.h" | 8 | #include "xs_mime.h" |
| 8 | #include "xs_openssl.h" | 9 | #include "xs_openssl.h" |
| 9 | #include "xs_regex.h" | 10 | #include "xs_regex.h" |
| @@ -779,7 +780,7 @@ int is_msg_for_me(snac *snac, const xs_dict *c_msg) | |||
| 779 | object_get(object, &obj); | 780 | object_get(object, &obj); |
| 780 | 781 | ||
| 781 | /* if it's about one of our posts, accept it */ | 782 | /* if it's about one of our posts, accept it */ |
| 782 | if (xs_startswith(object, snac->actor)) | 783 | if (is_msg_mine(snac, object)) |
| 783 | return 2; | 784 | return 2; |
| 784 | 785 | ||
| 785 | /* blocked by hashtag? */ | 786 | /* blocked by hashtag? */ |
| @@ -1242,7 +1243,7 @@ void notify(snac *snac, const char *type, const char *utype, const char *actor, | |||
| 1242 | 1243 | ||
| 1243 | if (xs_match(type, "Like|Announce|EmojiReact")) { | 1244 | if (xs_match(type, "Like|Announce|EmojiReact")) { |
| 1244 | /* if it's not an admiration about something by us, done */ | 1245 | /* if it's not an admiration about something by us, done */ |
| 1245 | if (xs_is_null(objid) || !xs_startswith(objid, snac->actor)) | 1246 | if (xs_is_null(objid) || !is_msg_mine(snac, objid)) |
| 1246 | return; | 1247 | return; |
| 1247 | 1248 | ||
| 1248 | /* if it's an announce by our own relay, done */ | 1249 | /* if it's an announce by our own relay, done */ |
| @@ -1267,7 +1268,7 @@ void notify(snac *snac, const char *type, const char *utype, const char *actor, | |||
| 1267 | return; | 1268 | return; |
| 1268 | 1269 | ||
| 1269 | /* if it's not ours and we didn't vote, discard */ | 1270 | /* if it's not ours and we didn't vote, discard */ |
| 1270 | if (!xs_startswith(poll_id, snac->actor) && !was_question_voted(snac, poll_id)) | 1271 | if (!is_msg_mine(snac, poll_id) && !was_question_voted(snac, poll_id)) |
| 1271 | return; | 1272 | return; |
| 1272 | } | 1273 | } |
| 1273 | 1274 | ||
| @@ -1530,11 +1531,24 @@ xs_dict *msg_update(snac *snac, const xs_dict *object) | |||
| 1530 | 1531 | ||
| 1531 | 1532 | ||
| 1532 | xs_dict *msg_admiration(snac *snac, const char *object, const char *type) | 1533 | xs_dict *msg_admiration(snac *snac, const char *object, const char *type) |
| 1533 | /* creates a Like or Announce message */ | 1534 | /* creates a Like, Announce or EmojiReact message */ |
| 1534 | { | 1535 | { |
| 1535 | xs *a_msg = NULL; | 1536 | xs *a_msg = NULL; |
| 1536 | xs_dict *msg = NULL; | 1537 | xs_dict *msg = NULL; |
| 1537 | xs *wrk = NULL; | 1538 | xs *wrk = NULL; |
| 1539 | char t = 0; | ||
| 1540 | |||
| 1541 | switch (*type) { | ||
| 1542 | case 'L': | ||
| 1543 | t = 'l'; | ||
| 1544 | break; | ||
| 1545 | case 'A': | ||
| 1546 | t = 'a'; | ||
| 1547 | break; | ||
| 1548 | case 'E': | ||
| 1549 | t = 'e'; | ||
| 1550 | break; | ||
| 1551 | } | ||
| 1538 | 1552 | ||
| 1539 | /* call the object */ | 1553 | /* call the object */ |
| 1540 | timeline_request(snac, &object, &wrk, 0); | 1554 | timeline_request(snac, &object, &wrk, 0); |
| @@ -1542,7 +1556,7 @@ xs_dict *msg_admiration(snac *snac, const char *object, const char *type) | |||
| 1542 | if (valid_status(object_get(object, &a_msg))) { | 1556 | if (valid_status(object_get(object, &a_msg))) { |
| 1543 | xs *rcpts = xs_list_new(); | 1557 | xs *rcpts = xs_list_new(); |
| 1544 | xs *o_md5 = xs_md5_hex(object, strlen(object)); | 1558 | xs *o_md5 = xs_md5_hex(object, strlen(object)); |
| 1545 | xs *id = xs_fmt("%s/%s/%s", snac->actor, *type == 'L' ? "l" : "a", o_md5); | 1559 | xs *id = xs_fmt("%s/%c/%s", snac->actor, t, o_md5); |
| 1546 | 1560 | ||
| 1547 | msg = msg_base(snac, type, id, snac->actor, "@now", object); | 1561 | msg = msg_base(snac, type, id, snac->actor, "@now", object); |
| 1548 | 1562 | ||
| @@ -1586,6 +1600,138 @@ xs_dict *msg_repulsion(snac *user, const char *id, const char *type) | |||
| 1586 | return msg; | 1600 | return msg; |
| 1587 | } | 1601 | } |
| 1588 | 1602 | ||
| 1603 | xs_dict *msg_emoji_init(snac *snac, const char *mid, const char *eid_o) | ||
| 1604 | /* creates an emoji reaction from a local user */ | ||
| 1605 | { | ||
| 1606 | xs_dict *n_msg = msg_admiration(snac, mid, "EmojiReact"); | ||
| 1607 | |||
| 1608 | xs *eid = xs_strip_chars_i(xs_dup(eid_o), ":"); | ||
| 1609 | xs *content = NULL; | ||
| 1610 | xs *tag = xs_list_new(); | ||
| 1611 | xs *dict = xs_dict_new(); | ||
| 1612 | xs *icon = xs_dict_new(); | ||
| 1613 | xs *accounts = xs_list_new(); | ||
| 1614 | xs *emjs = emojis_rm_categories(); | ||
| 1615 | |||
| 1616 | /* may be a default emoji */ | ||
| 1617 | xs *eidd = xs_dup(eid); | ||
| 1618 | const char *eidda = eid; | ||
| 1619 | |||
| 1620 | if (xs_is_emoji(xs_utf8_dec(&eidda))) | ||
| 1621 | content = xs_dup(eid); | ||
| 1622 | |||
| 1623 | else if (*eid == '%') { | ||
| 1624 | content = xs_url_dec_emoji(xs_dup(eid)); | ||
| 1625 | if (content == NULL) { | ||
| 1626 | return NULL; | ||
| 1627 | } | ||
| 1628 | } | ||
| 1629 | else { | ||
| 1630 | content = xs_fmt(":%s:", eid); | ||
| 1631 | const char *emo = xs_dict_get(emjs, content); | ||
| 1632 | |||
| 1633 | if (emo == NULL) | ||
| 1634 | return NULL; | ||
| 1635 | |||
| 1636 | if (xs_match(emo, "https://*|http://*")) { /* emoji is an URL to an image */ | ||
| 1637 | icon = xs_dict_set(icon, "type", "Image"); | ||
| 1638 | icon = xs_dict_set(icon, "url", emo); | ||
| 1639 | dict = xs_dict_set(dict, "icon", icon); | ||
| 1640 | |||
| 1641 | dict = xs_dict_set(dict, "id", emo); | ||
| 1642 | dict = xs_dict_set(dict, "name", content); | ||
| 1643 | dict = xs_dict_set(dict, "type", "Emoji"); | ||
| 1644 | tag = xs_list_append(tag, dict); | ||
| 1645 | } | ||
| 1646 | else | ||
| 1647 | if (xs_startswith(emo, "&#")) { | ||
| 1648 | /* snac default emoji as an HTML entity: decode */ | ||
| 1649 | content = xs_free(content); | ||
| 1650 | |||
| 1651 | xs *s1 = xs_strip_chars_i(xs_dup(emo), "&#"); | ||
| 1652 | unsigned int cpoint = 0; | ||
| 1653 | sscanf(s1, "%u;", &cpoint); | ||
| 1654 | |||
| 1655 | if (cpoint) | ||
| 1656 | content = xs_utf8_cat(xs_str_new(NULL), cpoint); | ||
| 1657 | else | ||
| 1658 | content = xs_dup(emo); | ||
| 1659 | } | ||
| 1660 | else { | ||
| 1661 | /* use as it is and hope for the best */ | ||
| 1662 | xs_free(content); | ||
| 1663 | content = xs_dup(emo); | ||
| 1664 | } | ||
| 1665 | } | ||
| 1666 | |||
| 1667 | accounts = xs_list_append(accounts, snac->actor); | ||
| 1668 | |||
| 1669 | n_msg = xs_dict_set(n_msg, "content", content); | ||
| 1670 | n_msg = xs_dict_set(n_msg, "accounts", accounts); | ||
| 1671 | n_msg = xs_dict_set(n_msg, "attributedTo", xs_list_get(xs_dict_get(n_msg, "to"), 1)); | ||
| 1672 | n_msg = xs_dict_set(n_msg, "accountId", snac->uid); | ||
| 1673 | n_msg = xs_dict_set(n_msg, "tag", tag); | ||
| 1674 | |||
| 1675 | int ret = timeline_admire(snac, xs_dict_get(n_msg, "object"), snac->actor, 1, n_msg); | ||
| 1676 | if (ret == 200 || ret == 201) { | ||
| 1677 | enqueue_message(snac, n_msg); | ||
| 1678 | return n_msg; | ||
| 1679 | } | ||
| 1680 | |||
| 1681 | return NULL; | ||
| 1682 | } | ||
| 1683 | |||
| 1684 | xs_dict *msg_emoji_unreact(snac *user, const char *mid, const char *eid) | ||
| 1685 | /* creates an Undo + emoji reaction message */ | ||
| 1686 | { | ||
| 1687 | xs *a_msg = NULL; | ||
| 1688 | xs_dict *msg = NULL; | ||
| 1689 | |||
| 1690 | if (valid_status(object_get(mid, &a_msg))) { | ||
| 1691 | /* create a clone of the original admiration message */ | ||
| 1692 | xs *object = msg_admiration(user, mid, "EmojiReact"); | ||
| 1693 | |||
| 1694 | /* delete the published date */ | ||
| 1695 | object = xs_dict_del(object, "published"); | ||
| 1696 | |||
| 1697 | /* create an undo message for this object */ | ||
| 1698 | msg = msg_undo(user, object); | ||
| 1699 | |||
| 1700 | /* copy the 'to' field */ | ||
| 1701 | msg = xs_dict_set(msg, "to", xs_dict_get(object, "to")); | ||
| 1702 | } | ||
| 1703 | |||
| 1704 | xs *emotes = object_get_emoji_reacts(mid); | ||
| 1705 | const char *v; | ||
| 1706 | int c = 0; | ||
| 1707 | |||
| 1708 | /* may be a default emoji */ | ||
| 1709 | if (strlen(eid) == 12 && *eid == '%') { | ||
| 1710 | eid = xs_url_dec(eid); | ||
| 1711 | if (eid == NULL) { | ||
| 1712 | return NULL; | ||
| 1713 | } | ||
| 1714 | } | ||
| 1715 | |||
| 1716 | /* lets get all emotes for this msg, and compare it to our content */ | ||
| 1717 | while (xs_list_next(emotes, &v, &c)) { | ||
| 1718 | xs_dict *e = NULL; | ||
| 1719 | if (valid_status(object_get_by_md5(v, &e))) { | ||
| 1720 | const char *content = xs_dict_get(e, "content"); | ||
| 1721 | const char *id = xs_dict_get(e, "id"); | ||
| 1722 | const char *actor = xs_dict_get(e, "actor"); | ||
| 1723 | /* maybe formated as :{emoteName}: too */ | ||
| 1724 | if (xs_str_in(eid, content) != -1) | ||
| 1725 | if (strcmp(user->actor, actor) == 0) { | ||
| 1726 | object_rm_emoji_react(mid, id); | ||
| 1727 | return msg; | ||
| 1728 | } | ||
| 1729 | } | ||
| 1730 | } | ||
| 1731 | |||
| 1732 | return NULL; | ||
| 1733 | } | ||
| 1734 | |||
| 1589 | 1735 | ||
| 1590 | xs_dict *msg_actor_place(snac *user, const char *label) | 1736 | xs_dict *msg_actor_place(snac *user, const char *label) |
| 1591 | /* creates a Place object, if the user has a location defined */ | 1737 | /* creates a Place object, if the user has a location defined */ |
| @@ -2432,6 +2578,11 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req) | |||
| 2432 | return -1; | 2578 | return -1; |
| 2433 | } | 2579 | } |
| 2434 | 2580 | ||
| 2581 | if (strcmp(type, "EmojiReact") == 0 && xs_is_true(xs_dict_get(srv_config, "disable_emojireact"))) { | ||
| 2582 | srv_log(xs_fmt("Dropping EmojiReact from %s due to admin configuration", actor)); | ||
| 2583 | return -1; | ||
| 2584 | } | ||
| 2585 | |||
| 2435 | const char *object, *utype; | 2586 | const char *object, *utype; |
| 2436 | 2587 | ||
| 2437 | object = xs_dict_get(msg, "object"); | 2588 | object = xs_dict_get(msg, "object"); |
| @@ -2605,6 +2756,16 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req) | |||
| 2605 | else | 2756 | else |
| 2606 | if (strcmp(type, "Undo") == 0) { /** **/ | 2757 | if (strcmp(type, "Undo") == 0) { /** **/ |
| 2607 | const char *id = xs_dict_get(object, "object"); | 2758 | const char *id = xs_dict_get(object, "object"); |
| 2759 | const char *content = xs_dict_get(object, "content"); | ||
| 2760 | /* misskey sends emojis as like + tag */ | ||
| 2761 | xs *cd = xs_dup(content); | ||
| 2762 | const char *sna = cd; | ||
| 2763 | const xs_dict *tag = xs_dict_get(object, "tag"); | ||
| 2764 | unsigned int utf = xs_utf8_dec((const char **)&sna); | ||
| 2765 | |||
| 2766 | int isEmoji = 0; | ||
| 2767 | if (xs_is_emoji(utf) || (tag && xs_list_len(tag) > 0)) | ||
| 2768 | isEmoji = 1; | ||
| 2608 | 2769 | ||
| 2609 | if (xs_type(object) != XSTYPE_DICT) { | 2770 | if (xs_type(object) != XSTYPE_DICT) { |
| 2610 | snac_debug(snac, 1, xs_fmt("undo: overriding utype %s | %s | %s", | 2771 | snac_debug(snac, 1, xs_fmt("undo: overriding utype %s | %s | %s", |
| @@ -2633,8 +2794,19 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req) | |||
| 2633 | else | 2794 | else |
| 2634 | snac_log(snac, xs_fmt("error deleting follower %s", actor)); | 2795 | snac_log(snac, xs_fmt("error deleting follower %s", actor)); |
| 2635 | } | 2796 | } |
| 2797 | /* *key emojis are like w/ Emoji tag */ | ||
| 2798 | else | ||
| 2799 | if ((isEmoji || strcmp(utype, "EmojiReact") == 0) && | ||
| 2800 | (content && strcmp(content, "♥") != 0)) { | ||
| 2801 | const xs_val *mid = xs_dict_get(object, "id"); | ||
| 2802 | int status = object_rm_emoji_react((char *)id, mid); | ||
| 2803 | /* ensure *key notifications type */ | ||
| 2804 | utype = "EmojiReact"; | ||
| 2805 | |||
| 2806 | snac_log(snac, xs_fmt("Undo 'EmojiReact' for %s %d", id, status)); | ||
| 2807 | } | ||
| 2636 | else | 2808 | else |
| 2637 | if (strcmp(utype, "Like") == 0 || strcmp(utype, "EmojiReact") == 0) { /** **/ | 2809 | if (strcmp(utype, "Like") == 0) { /** **/ |
| 2638 | int status = object_unadmire(id, actor, 1); | 2810 | int status = object_unadmire(id, actor, 1); |
| 2639 | 2811 | ||
| 2640 | snac_log(snac, xs_fmt("Undo '%s' for %s %d", utype, id, status)); | 2812 | snac_log(snac, xs_fmt("Undo '%s' for %s %d", utype, id, status)); |
| @@ -2771,13 +2943,22 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req) | |||
| 2771 | } | 2943 | } |
| 2772 | else | 2944 | else |
| 2773 | if (strcmp(type, "Like") == 0 || strcmp(type, "EmojiReact") == 0) { /** **/ | 2945 | if (strcmp(type, "Like") == 0 || strcmp(type, "EmojiReact") == 0) { /** **/ |
| 2946 | /* misskey sends emojis as Like + tag. | ||
| 2947 | * It is easier to handle them both at the same time. */ | ||
| 2948 | const char *sna = xs_dict_get(msg, "content"); | ||
| 2949 | const xs_dict *tag = xs_dict_get(msg, "tag"); | ||
| 2950 | unsigned int utf = xs_utf8_dec((const char **)&sna); | ||
| 2951 | |||
| 2952 | if (xs_is_emoji(utf) || (tag && xs_list_len(tag) > 0)) | ||
| 2953 | type = "EmojiReact"; | ||
| 2954 | |||
| 2774 | if (xs_type(object) == XSTYPE_DICT) | 2955 | if (xs_type(object) == XSTYPE_DICT) |
| 2775 | object = xs_dict_get(object, "id"); | 2956 | object = xs_dict_get(object, "id"); |
| 2776 | 2957 | ||
| 2777 | if (xs_is_null(object)) | 2958 | if (xs_is_null(object)) |
| 2778 | snac_log(snac, xs_fmt("malformed message: no 'id' field")); | 2959 | snac_log(snac, xs_fmt("malformed message: no 'id' field")); |
| 2779 | else | 2960 | else |
| 2780 | if (timeline_admire(snac, object, actor, 1) == HTTP_STATUS_CREATED) | 2961 | if (timeline_admire(snac, object, actor, 1, msg) == HTTP_STATUS_CREATED) |
| 2781 | snac_log(snac, xs_fmt("new '%s' %s %s", type, actor, object)); | 2962 | snac_log(snac, xs_fmt("new '%s' %s %s", type, actor, object)); |
| 2782 | else | 2963 | else |
| 2783 | snac_log(snac, xs_fmt("repeated '%s' from %s to %s", type, actor, object)); | 2964 | snac_log(snac, xs_fmt("repeated '%s' from %s to %s", type, actor, object)); |
| @@ -2792,10 +2973,10 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req) | |||
| 2792 | if (xs_is_null(object)) | 2973 | if (xs_is_null(object)) |
| 2793 | snac_log(snac, xs_fmt("malformed message: no 'id' field")); | 2974 | snac_log(snac, xs_fmt("malformed message: no 'id' field")); |
| 2794 | else | 2975 | else |
| 2795 | if (is_muted(snac, actor) && !xs_startswith(object, snac->actor)) | 2976 | if (is_muted(snac, actor) && !is_msg_mine(snac, object)) |
| 2796 | snac_log(snac, xs_fmt("dropped 'Announce' from muted actor %s", actor)); | 2977 | snac_log(snac, xs_fmt("dropped 'Announce' from muted actor %s", actor)); |
| 2797 | else | 2978 | else |
| 2798 | if (is_limited(snac, actor) && !xs_startswith(object, snac->actor)) | 2979 | if (is_limited(snac, actor) && !is_msg_mine(snac, object)) |
| 2799 | snac_log(snac, xs_fmt("dropped 'Announce' from limited actor %s", actor)); | 2980 | snac_log(snac, xs_fmt("dropped 'Announce' from limited actor %s", actor)); |
| 2800 | else { | 2981 | else { |
| 2801 | xs *a_msg = NULL; | 2982 | xs *a_msg = NULL; |
| @@ -2818,7 +2999,7 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req) | |||
| 2818 | xs *this_relay = xs_fmt("%s/relay", srv_baseurl); | 2999 | xs *this_relay = xs_fmt("%s/relay", srv_baseurl); |
| 2819 | 3000 | ||
| 2820 | if (strcmp(actor, this_relay) != 0) { | 3001 | if (strcmp(actor, this_relay) != 0) { |
| 2821 | if (valid_status(timeline_admire(snac, object, actor, 0))) | 3002 | if (valid_status(timeline_admire(snac, object, actor, 0, a_msg))) |
| 2822 | snac_log(snac, xs_fmt("new 'Announce' %s %s", actor, object)); | 3003 | snac_log(snac, xs_fmt("new 'Announce' %s %s", actor, object)); |
| 2823 | else | 3004 | else |
| 2824 | snac_log(snac, xs_fmt("repeated 'Announce' from %s to %s", | 3005 | snac_log(snac, xs_fmt("repeated 'Announce' from %s to %s", |
| @@ -2903,7 +3084,7 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req) | |||
| 2903 | snac_log(snac, xs_fmt("malformed message: no 'id' field")); | 3084 | snac_log(snac, xs_fmt("malformed message: no 'id' field")); |
| 2904 | else | 3085 | else |
| 2905 | if (object_here(object)) { | 3086 | if (object_here(object)) { |
| 2906 | if (xs_startswith(object, srv_baseurl) && !xs_startswith(object, actor)) | 3087 | if (xs_startswith(object, srv_baseurl) && !is_msg_mine(snac, object)) |
| 2907 | snac_log(snac, xs_fmt("ignored incorrect 'Delete' %s %s", actor, object)); | 3088 | snac_log(snac, xs_fmt("ignored incorrect 'Delete' %s %s", actor, object)); |
| 2908 | else { | 3089 | else { |
| 2909 | timeline_del(snac, object); | 3090 | timeline_del(snac, object); |
| @@ -3214,7 +3395,7 @@ void process_user_queue_item(snac *user, xs_dict *q_item) | |||
| 3214 | actor_add(actor, actor_o); | 3395 | actor_add(actor, actor_o); |
| 3215 | } | 3396 | } |
| 3216 | else { | 3397 | else { |
| 3217 | if (status == HTTP_STATUS_GONE) { | 3398 | if (status == HTTP_STATUS_GONE || status == HTTP_STATUS_NOT_FOUND) { |
| 3218 | actor_failure(actor, 1); | 3399 | actor_failure(actor, 1); |
| 3219 | snac_log(user, xs_fmt("actor_refresh marking actor %s as broken %d", actor, status)); | 3400 | snac_log(user, xs_fmt("actor_refresh marking actor %s as broken %d", actor, status)); |
| 3220 | } | 3401 | } |
| @@ -3716,7 +3897,7 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path, | |||
| 3716 | const char *type = xs_dict_get(i, "type"); | 3897 | const char *type = xs_dict_get(i, "type"); |
| 3717 | const char *id = xs_dict_get(i, "id"); | 3898 | const char *id = xs_dict_get(i, "id"); |
| 3718 | 3899 | ||
| 3719 | if (type && id && strcmp(type, "Note") == 0 && xs_startswith(id, snac.actor)) { | 3900 | if (type && id && strcmp(type, "Note") == 0 && is_msg_mine(&snac, id)) { |
| 3720 | if (is_msg_public(i)) { | 3901 | if (is_msg_public(i)) { |
| 3721 | xs *c_msg = msg_create(&snac, i); | 3902 | xs *c_msg = msg_create(&snac, i); |
| 3722 | list = xs_list_append(list, c_msg); | 3903 | list = xs_list_append(list, c_msg); |