/* snac - A simple, minimalistic ActivityPub instance */ /* copyright (c) 2022 - 2023 grunfink / MIT license */ #include "xs.h" #include "xs_io.h" #include "xs_encdec.h" #include "xs_json.h" #include "xs_regex.h" #include "xs_set.h" #include "xs_openssl.h" #include "xs_time.h" #include "xs_mime.h" #include "snac.h" int login(snac *snac, char *headers) /* tries a login */ { int logged_in = 0; char *auth = xs_dict_get(headers, "authorization"); if (auth && xs_startswith(auth, "Basic ")) { int sz; xs *s1 = xs_crop_i(xs_dup(auth), 6, 0); xs *s2 = xs_base64_dec(s1, &sz); xs *l1 = xs_split_n(s2, ":", 1); if (xs_list_len(l1) == 2) { logged_in = check_password( xs_list_get(l1, 0), xs_list_get(l1, 1), xs_dict_get(snac->config, "passwd")); } } return logged_in; } d_char *html_actor_icon(snac *snac, d_char *os, char *actor, const char *date, const char *udate, const char *url, int priv) { xs *s = xs_str_new(NULL); xs *name = NULL; xs *avatar = NULL; char *p, *v; /* get the name */ if (xs_is_null((v = xs_dict_get(actor, "name"))) || *v == '\0') { if (xs_is_null(v = xs_dict_get(actor, "preferredUsername"))) { v = "user"; } } name = xs_dup(v); /* replace the :shortnames: */ if (!xs_is_null(p = xs_dict_get(actor, "tag"))) { /* iterate the tags */ while (xs_list_iter(&p, &v)) { char *t = xs_dict_get(v, "type"); if (t && strcmp(t, "Emoji") == 0) { char *n = xs_dict_get(v, "name"); char *i = xs_dict_get(v, "icon"); if (n && i) { char *u = xs_dict_get(i, "url"); xs *img = xs_fmt("", u); name = xs_replace_i(name, n, img); } } } } /* get the avatar */ if ((v = xs_dict_get(actor, "icon")) != NULL && (v = xs_dict_get(v, "url")) != NULL) { avatar = xs_dup(v); } if (avatar == NULL) avatar = xs_fmt("data:image/png;base64, %s", default_avatar_base64()); { xs *s1 = xs_fmt("
\n", avatar);
s = xs_str_cat(s, s1);
}
{
xs *s1 = xs_fmt("%s",
xs_dict_get(actor, "id"), name);
s = xs_str_cat(s, s1);
}
if (!xs_is_null(url)) {
xs *s1 = xs_fmt(" »", url);
s = xs_str_cat(s, s1);
}
if (priv)
s = xs_str_cat(s, " 🔒");
if (xs_is_null(date)) {
s = xs_str_cat(s, "
\n \n");
}
else {
xs *date_label = xs_crop_i(xs_dup(date), 0, 10);
xs *date_title = xs_dup(date);
if (!xs_is_null(udate)) {
xs *sd = xs_crop_i(xs_dup(udate), 0, 10);
date_label = xs_str_cat(date_label, " / ");
date_label = xs_str_cat(date_label, sd);
date_title = xs_str_cat(date_title, " / ");
date_title = xs_str_cat(date_title, udate);
}
xs *s1 = xs_fmt(
"
\n\n",
date_title, date_label);
s = xs_str_cat(s, s1);
}
return xs_str_cat(os, s);
}
d_char *html_msg_icon(snac *snac, d_char *os, char *msg)
{
char *actor_id;
xs *actor = NULL;
if ((actor_id = xs_dict_get(msg, "attributedTo")) == NULL)
actor_id = xs_dict_get(msg, "actor");
if (actor_id && valid_status(actor_get(snac, actor_id, &actor))) {
char *date = NULL;
char *udate = NULL;
char *url = NULL;
int priv = 0;
if (strcmp(xs_dict_get(msg, "type"), "Note") == 0)
url = xs_dict_get(msg, "id");
priv = !is_msg_public(snac, msg);
date = xs_dict_get(msg, "published");
udate = xs_dict_get(msg, "updated");
os = html_actor_icon(snac, os, actor, date, udate, url, priv);
}
return os;
}
d_char *html_user_header(snac *snac, d_char *s, int local)
/* creates the HTML header */
{
char *p, *v;
s = xs_str_cat(s, "\n\n
%s
\n" "@%s@%s
\n" "\n" "
\n" "
\n"
"%s
\n"
"
%s
\n"
"
" "\n", L("Edit..."), md5, snac->actor, md5, prev_src, id, L("Sensitive content"), L("Image description"), md5, L("Post") ); s = xs_str_cat(s, s1); } { /* the post textarea */ xs *ct = build_mentions(snac, msg); xs *s1 = xs_fmt( "
%s
\n"
"
" "\n", L("Reply..."), md5, snac->actor, md5, ct, id, L("Sensitive content"), L("Image description"), md5, L("Post") ); s = xs_str_cat(s, s1); } s = xs_str_cat(s, "
%s
"); if (!xs_startswith(c, "
")) { xs *s1 = c; c = xs_fmt("
%s
", s1); } /* replace the :shortnames: */ if (!xs_is_null(p = xs_dict_get(msg, "tag"))) { /* iterate the tags */ while (xs_list_iter(&p, &v)) { char *t = xs_dict_get(v, "type"); if (t && strcmp(t, "Emoji") == 0) { char *n = xs_dict_get(v, "name"); char *i = xs_dict_get(v, "icon"); if (n && i) { char *u = xs_dict_get(i, "url"); xs *img = xs_fmt("", u); c = xs_replace_i(c, n, img); } } } } s = xs_str_cat(s, c); } s = xs_str_cat(s, "\n"); /* add the attachments */ char *attach; if ((attach = xs_dict_get(msg, "attachment")) != NULL) { char *v; while (xs_list_iter(&attach, &v)) { char *t = xs_dict_get(v, "mediaType"); if (xs_is_null(t)) continue; if (xs_startswith(t, "image/")) { char *url = xs_dict_get(v, "url"); char *name = xs_dict_get(v, "name"); if (url != NULL) { xs *s1 = xs_fmt("\n", url, xs_is_null(name) ? "" : name); s = xs_str_cat(s, s1); } } else if (xs_startswith(t, "video/")) { char *url = xs_dict_get(v, "url"); if (url != NULL) { xs *s1 = xs_fmt("\n", url); s = xs_str_cat(s, s1); } } } } if (sensitive) s = xs_str_cat(s, "\n"); s = xs_str_cat(s, "
\n"); if (level < 4) ss = xs_str_cat(ss, "
%s
" "%s" "
\n", snac->actor, local ? "" : "/admin", skip + show, show, L("More...")); s = xs_str_cat(s, s1); } s = html_user_footer(snac, s); s = xs_str_cat(s, "\n\n"); return s; } d_char *html_people_list(snac *snac, d_char *os, d_char *list, const char *header, const char *t) { xs *s = xs_str_new(NULL); xs *h = xs_fmt("")) s = xs_str_cat(s, sc); else { xs *s1 = xs_fmt("
%s
", sc); s = xs_str_cat(s, s1); } s = xs_str_cat(s, "%s
\n"
"
\n", L("Direct Message..."), md5, t, snac->actor, md5, actor_id, L("Post") ); s = xs_str_cat(s, s2); s = xs_str_cat(s, "