diff options
Diffstat (limited to 'html.c')
| -rw-r--r-- | html.c | 90 |
1 files changed, 86 insertions, 4 deletions
| @@ -29,9 +29,18 @@ int login(snac *snac, const xs_dict *headers) | |||
| 29 | xs *l1 = xs_split_n(s2, ":", 1); | 29 | xs *l1 = xs_split_n(s2, ":", 1); |
| 30 | 30 | ||
| 31 | if (xs_list_len(l1) == 2) { | 31 | if (xs_list_len(l1) == 2) { |
| 32 | logged_in = check_password( | 32 | const char *user = xs_list_get(l1, 0); |
| 33 | xs_list_get(l1, 0), xs_list_get(l1, 1), | 33 | const char *pwd = xs_list_get(l1, 1); |
| 34 | xs_dict_get(snac->config, "passwd")); | 34 | const char *addr = xs_or(xs_dict_get(headers, "remote-addr"), |
| 35 | xs_dict_get(headers, "x-forwarded-for")); | ||
| 36 | |||
| 37 | if (badlogin_check(user, addr)) { | ||
| 38 | logged_in = check_password(user, pwd, | ||
| 39 | xs_dict_get(snac->config, "passwd")); | ||
| 40 | |||
| 41 | if (!logged_in) | ||
| 42 | badlogin_inc(user, addr); | ||
| 43 | } | ||
| 35 | } | 44 | } |
| 36 | } | 45 | } |
| 37 | 46 | ||
| @@ -633,6 +642,17 @@ xs_html *html_user_head(snac *user, const char *desc, const char *url) | |||
| 633 | else | 642 | else |
| 634 | s_desc = xs_dup(desc); | 643 | s_desc = xs_dup(desc); |
| 635 | 644 | ||
| 645 | /* show metrics in og:description? */ | ||
| 646 | if (xs_is_true(xs_dict_get(user->config, "show_contact_metrics"))) { | ||
| 647 | xs *fwers = follower_list(user); | ||
| 648 | xs *fwing = following_list(user); | ||
| 649 | |||
| 650 | xs *s1 = xs_fmt(L("%d following, %d followers ยท "), | ||
| 651 | xs_list_len(fwing), xs_list_len(fwers)); | ||
| 652 | |||
| 653 | s_desc = xs_str_prepend_i(s_desc, s1); | ||
| 654 | } | ||
| 655 | |||
| 636 | /* shorten desc to a reasonable size */ | 656 | /* shorten desc to a reasonable size */ |
| 637 | for (n = 0; s_desc[n]; n++) { | 657 | for (n = 0; s_desc[n]; n++) { |
| 638 | if (n > 512 && (s_desc[n] == ' ' || s_desc[n] == '\n')) | 658 | if (n > 512 && (s_desc[n] == ' ' || s_desc[n] == '\n')) |
| @@ -2041,6 +2061,23 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, | |||
| 2041 | if (content && xs_str_in(content, o_href) != -1) | 2061 | if (content && xs_str_in(content, o_href) != -1) |
| 2042 | continue; | 2062 | continue; |
| 2043 | 2063 | ||
| 2064 | /* do this attachment include an icon? */ | ||
| 2065 | const xs_dict *icon = xs_dict_get(a, "icon"); | ||
| 2066 | if (xs_type(icon) == XSTYPE_DICT) { | ||
| 2067 | const char *icon_mtype = xs_dict_get(icon, "mediaType"); | ||
| 2068 | const char *icon_url = xs_dict_get(icon, "url"); | ||
| 2069 | |||
| 2070 | if (icon_mtype && icon_url && xs_startswith(icon_mtype, "image/")) { | ||
| 2071 | xs_html_add(content_attachments, | ||
| 2072 | xs_html_tag("a", | ||
| 2073 | xs_html_attr("href", icon_url), | ||
| 2074 | xs_html_attr("target", "_blank"), | ||
| 2075 | xs_html_sctag("img", | ||
| 2076 | xs_html_attr("loading", "lazy"), | ||
| 2077 | xs_html_attr("src", icon_url)))); | ||
| 2078 | } | ||
| 2079 | } | ||
| 2080 | |||
| 2044 | xs *href = make_url(o_href, proxy, 0); | 2081 | xs *href = make_url(o_href, proxy, 0); |
| 2045 | 2082 | ||
| 2046 | if (xs_startswith(type, "image/") || strcmp(type, "Image") == 0) { | 2083 | if (xs_startswith(type, "image/") || strcmp(type, "Image") == 0) { |
| @@ -2996,9 +3033,54 @@ int html_get_handler(const xs_dict *req, const char *q_path, | |||
| 2996 | } | 3033 | } |
| 2997 | else { | 3034 | else { |
| 2998 | const char *q = xs_dict_get(q_vars, "q"); | 3035 | const char *q = xs_dict_get(q_vars, "q"); |
| 3036 | xs *url_acct = NULL; | ||
| 3037 | |||
| 3038 | /* searching for an URL? */ | ||
| 3039 | if (q && xs_match(q, "https://*|http://*")) { | ||
| 3040 | /* may by an actor; try a webfinger */ | ||
| 3041 | xs *actor_obj = NULL; | ||
| 3042 | |||
| 3043 | if (valid_status(webfinger_request(q, &actor_obj, &url_acct))) { | ||
| 3044 | /* it's an actor; do the dirty trick of changing q to the account name */ | ||
| 3045 | q = url_acct; | ||
| 3046 | } | ||
| 3047 | else { | ||
| 3048 | /* if it's not already here, try to bring it to the user's timeline */ | ||
| 3049 | xs *md5 = xs_md5_hex(q, strlen(q)); | ||
| 3050 | |||
| 3051 | if (!timeline_here(&snac, md5)) { | ||
| 3052 | xs *object = NULL; | ||
| 3053 | int status; | ||
| 3054 | |||
| 3055 | status = activitypub_request(&snac, q, &object); | ||
| 3056 | snac_debug(&snac, 1, xs_fmt("Request searched URL %s %d", q, status)); | ||
| 3057 | |||
| 3058 | if (valid_status(status)) { | ||
| 3059 | /* got it; also request the actor */ | ||
| 3060 | const char *attr_to = get_atto(object); | ||
| 3061 | |||
| 3062 | if (!xs_is_null(attr_to)) { | ||
| 3063 | status = actor_request(&snac, attr_to, &actor_obj); | ||
| 3064 | |||
| 3065 | snac_debug(&snac, 1, xs_fmt("Request author %s of %s %d", attr_to, q, status)); | ||
| 3066 | |||
| 3067 | if (valid_status(status)) { | ||
| 3068 | /* add the actor */ | ||
| 3069 | actor_add(attr_to, actor_obj); | ||
| 3070 | |||
| 3071 | /* add the post to the timeline */ | ||
| 3072 | timeline_add(&snac, q, object); | ||
| 3073 | } | ||
| 3074 | } | ||
| 3075 | } | ||
| 3076 | } | ||
| 3077 | } | ||
| 3078 | |||
| 3079 | /* fall through */ | ||
| 3080 | } | ||
| 2999 | 3081 | ||
| 3000 | if (q && *q) { | 3082 | if (q && *q) { |
| 3001 | if (xs_regex_match(q, "^@?[a-zA-Z0-9_]+@[a-zA-Z0-9-]+\\.")) { | 3083 | if (xs_regex_match(q, "^@?[a-zA-Z0-9._]+@[a-zA-Z0-9-]+\\.")) { |
| 3002 | /** search account **/ | 3084 | /** search account **/ |
| 3003 | xs *actor = NULL; | 3085 | xs *actor = NULL; |
| 3004 | xs *acct = NULL; | 3086 | xs *acct = NULL; |