mirror of
https://codeberg.org/grunfink/snac2.git
synced 2024-11-15 01:55:03 +00:00
Merge branch 'master' of triptico.com:git/snac2
This commit is contained in:
commit
8faa06652d
6 changed files with 71 additions and 25 deletions
|
@ -4,6 +4,8 @@
|
|||
|
||||
Added proper HTTP caching when serving static files (attached images, avatars, etc.)
|
||||
|
||||
Sensitive content messages can now have a summary (i.e. no longer limited to ...)
|
||||
|
||||
Added a way to block full instances (from the command-line tool, as I consider this to be an administration priviledge).
|
||||
|
||||
If the user style.css does not exist, the server-wide one if served instead.
|
||||
|
@ -18,6 +20,8 @@ For polls, show the time left before it closes.
|
|||
|
||||
Added some support for post pinning.
|
||||
|
||||
Fixed a bug that prevented unfollows to be shown in the notification area.
|
||||
|
||||
## 2.35
|
||||
|
||||
Fixed broken URL links with the # symbol on them.
|
||||
|
|
13
TODO.md
13
TODO.md
|
@ -12,8 +12,6 @@ Mastodon API: fix whatever the fuck is making the official app and Megalodon to
|
|||
|
||||
Improve support for audio attachments.
|
||||
|
||||
Add a quick way to block complete domains / instances.
|
||||
|
||||
Add support for pinning posts.
|
||||
|
||||
Important: deleting a follower should do more that just delete the object, see https://codeberg.org/grunfink/snac2/issues/43#issuecomment-956721
|
||||
|
@ -33,7 +31,8 @@ Implement bulleted lists. Mastodon is crap and won't show them, but other implem
|
|||
User request: "will it be possible to click on a link and instead of opening the original instance, we'll be able only to see a list of the posts of this person here in comam?. Something like Mastodon does."
|
||||
|
||||
Test all the possible XSS vulnerabilities in https://raw.githubusercontent.com/danielmiessler/SecLists/master/Fuzzing/big-list-of-naughty-strings.txt
|
||||
Minor data storage housekeeping: index_list() and index_list_desc() should not return deleted (i.e. dash prefixed) entries; _object_user_cache() should call index_del() (?).
|
||||
|
||||
index_list() and index_list_desc() should not return deleted (i.e. dash prefixed) entries.
|
||||
|
||||
## Closed
|
||||
|
||||
|
@ -260,3 +259,11 @@ Replace weird, vestigial 'touch-by-append-spaces' in actor_get() with a more pro
|
|||
With this new disk layout, hidden posts (and their children) can be directly skipped when rendering the HTML timeline (are there any other implications?) (2023-06-23T06:48:51+0200).
|
||||
|
||||
Implement HTTP caches (If-None-Match / ETag) (2023-07-02T11:11:20+0200).
|
||||
|
||||
Add a quick way to block complete domains / instances (2023-07-04T14:35:44+0200).
|
||||
|
||||
_object_user_cache() should call index_del() (2023-07-04T14:36:37+0200).
|
||||
|
||||
Add a content warning description (2023-07-04T15:02:19+0200).
|
||||
|
||||
Propagate the CW status and description from the replied message (2023-07-04T15:02:19+0200).
|
||||
|
|
|
@ -449,7 +449,7 @@ int is_msg_for_me(snac *snac, const xs_dict *c_msg)
|
|||
}
|
||||
|
||||
|
||||
void process_tags(snac *snac, const char *content, xs_str **n_content, xs_list **tag)
|
||||
xs_str *process_tags(snac *snac, const char *content, xs_list **tag)
|
||||
/* parses mentions and tags from content */
|
||||
{
|
||||
xs_str *nc = xs_str_new(NULL);
|
||||
|
@ -559,8 +559,9 @@ void process_tags(snac *snac, const char *content, xs_str **n_content, xs_list *
|
|||
n++;
|
||||
}
|
||||
|
||||
*n_content = nc;
|
||||
*tag = tl;
|
||||
|
||||
return nc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -688,6 +689,9 @@ void notify(snac *snac, const char *type, const char *utype, const char *actor,
|
|||
/* finally, store it in the notification folder */
|
||||
if (strcmp(type, "Follow") == 0)
|
||||
objid = id;
|
||||
else
|
||||
if (strcmp(utype, "Follow") == 0)
|
||||
objid = actor;
|
||||
|
||||
notify_add(snac, type, utype, actor, objid != NULL ? objid : id);
|
||||
}
|
||||
|
@ -836,6 +840,7 @@ xs_dict *msg_actor(snac *snac)
|
|||
xs *ctxt = xs_list_new();
|
||||
xs *icon = xs_dict_new();
|
||||
xs *keys = xs_dict_new();
|
||||
xs *tags = xs_list_new();
|
||||
xs *avtr = NULL;
|
||||
xs *kid = NULL;
|
||||
xs *f_bio = NULL;
|
||||
|
@ -853,8 +858,10 @@ xs_dict *msg_actor(snac *snac)
|
|||
msg = xs_dict_set(msg, "preferredUsername", snac->uid);
|
||||
msg = xs_dict_set(msg, "published", xs_dict_get(snac->config, "published"));
|
||||
|
||||
f_bio = not_really_markdown(xs_dict_get(snac->config, "bio"), NULL);
|
||||
xs *f_bio_2 = not_really_markdown(xs_dict_get(snac->config, "bio"), NULL);
|
||||
f_bio = process_tags(snac, f_bio_2, &tags);
|
||||
msg = xs_dict_set(msg, "summary", f_bio);
|
||||
msg = xs_dict_set(msg, "tag", tags);
|
||||
|
||||
char *folders[] = { "inbox", "outbox", "followers", "following", NULL };
|
||||
for (n = 0; folders[n]; n++) {
|
||||
|
@ -1053,7 +1060,7 @@ xs_dict *msg_note(snac *snac, const xs_str *content, const xs_val *rcpts,
|
|||
irt = xs_val_new(XSTYPE_NULL);
|
||||
|
||||
/* extract the mentions and hashtags and convert the content */
|
||||
process_tags(snac, fc2, &fc1, &tag);
|
||||
fc1 = process_tags(snac, fc2, &tag);
|
||||
|
||||
/* create the attachment list, if there are any */
|
||||
if (!xs_is_null(attach)) {
|
||||
|
|
5
data.c
5
data.c
|
@ -496,10 +496,12 @@ xs_list *index_list(const char *fn, int max)
|
|||
list = xs_list_new();
|
||||
|
||||
while (n < max && fgets(line, sizeof(line), f) != NULL) {
|
||||
if (line[0] != '-') {
|
||||
line[32] = '\0';
|
||||
list = xs_list_append(list, line);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
@ -524,9 +526,11 @@ xs_list *index_list_desc(const char *fn, int skip, int show)
|
|||
/* move to the end minus one entry (or more, if skipping entries) */
|
||||
if (!fseek(f, 0, SEEK_END) && !fseek(f, (skip + 1) * -33, SEEK_CUR)) {
|
||||
while (n < show && fgets(line, sizeof(line), f) != NULL) {
|
||||
if (line[0] != '-') {
|
||||
line[32] = '\0';
|
||||
list = xs_list_append(list, line);
|
||||
n++;
|
||||
}
|
||||
|
||||
/* move backwards 2 entries */
|
||||
if (fseek(f, -66, SEEK_CUR) == -1)
|
||||
|
@ -862,6 +866,7 @@ int _object_user_cache(snac *snac, const char *id, const char *cachedir, int del
|
|||
|
||||
if (del) {
|
||||
ret = unlink(cfn);
|
||||
index_del(idx, id);
|
||||
}
|
||||
else {
|
||||
if ((ret = link(ofn, cfn)) != -1)
|
||||
|
|
43
html.c
43
html.c
|
@ -362,8 +362,10 @@ d_char *html_user_header(snac *snac, d_char *s, int local)
|
|||
s = xs_str_cat(s, s1);
|
||||
|
||||
if (local) {
|
||||
xs *bio = not_really_markdown(xs_dict_get(snac->config, "bio"), NULL);
|
||||
xs *s1 = xs_fmt("<div class=\"p-note snac-top-user-bio\">%s</div>\n", bio);
|
||||
xs *bio1 = not_really_markdown(xs_dict_get(snac->config, "bio"), NULL);
|
||||
xs *tags = xs_list_new();
|
||||
xs *bio2 = process_tags(snac, bio1, &tags);
|
||||
xs *s1 = xs_fmt("<div class=\"p-note snac-top-user-bio\">%s</div>\n", bio2);
|
||||
|
||||
s = xs_str_cat(s, s1);
|
||||
}
|
||||
|
@ -387,7 +389,8 @@ d_char *html_top_controls(snac *snac, d_char *s)
|
|||
"<textarea class=\"snac-textarea\" name=\"content\" "
|
||||
"rows=\"8\" wrap=\"virtual\" required=\"required\"></textarea>\n"
|
||||
"<input type=\"hidden\" name=\"in_reply_to\" value=\"\">\n"
|
||||
"<p>%s: <input type=\"checkbox\" name=\"sensitive\">\n"
|
||||
"<p>%s: <input type=\"checkbox\" name=\"sensitive\"> "
|
||||
"<input type=\"text\" name=\"summary\" placeholder=\"%s\">\n"
|
||||
"<p>%s: <input type=\"checkbox\" name=\"mentioned_only\">\n"
|
||||
|
||||
"<details><summary>%s</summary>\n" /** attach **/
|
||||
|
@ -512,6 +515,7 @@ d_char *html_top_controls(snac *snac, d_char *s)
|
|||
xs *s1 = xs_fmt(_tmpl,
|
||||
snac->actor,
|
||||
L("Sensitive content"),
|
||||
L("Sensitive content description"),
|
||||
L("Only for mentioned people"),
|
||||
|
||||
L("Attach..."),
|
||||
|
@ -684,8 +688,10 @@ xs_str *html_entry_controls(snac *snac, xs_str *os, const xs_dict *msg, const ch
|
|||
|
||||
const char *prev_src1 = xs_dict_get(msg, "sourceContent");
|
||||
|
||||
if (!xs_is_null(prev_src1) && strcmp(actor, snac->actor) == 0) {
|
||||
if (!xs_is_null(prev_src1) && strcmp(actor, snac->actor) == 0) { /** edit **/
|
||||
xs *prev_src = xs_replace(prev_src1, "<", "<");
|
||||
const xs_val *sensitive = xs_dict_get(msg, "sensitive");
|
||||
const char *summary = xs_dict_get(msg, "summary");
|
||||
|
||||
/* post can be edited */
|
||||
xs *s1 = xs_fmt(
|
||||
|
@ -697,7 +703,8 @@ xs_str *html_entry_controls(snac *snac, xs_str *os, const xs_dict *msg, const ch
|
|||
"rows=\"4\" wrap=\"virtual\" required=\"required\">%s</textarea>\n"
|
||||
"<input type=\"hidden\" name=\"edit_id\" value=\"%s\">\n"
|
||||
|
||||
"<p>%s: <input type=\"checkbox\" name=\"sensitive\">\n"
|
||||
"<p>%s: <input type=\"checkbox\" name=\"sensitive\" %s> "
|
||||
"<input type=\"text\" name=\"summary\" placeholder=\"%s\" value=\"%s\">\n"
|
||||
"<p>%s: <input type=\"checkbox\" name=\"mentioned_only\">\n"
|
||||
|
||||
"<details><summary>%s</summary>\n"
|
||||
|
@ -717,6 +724,9 @@ xs_str *html_entry_controls(snac *snac, xs_str *os, const xs_dict *msg, const ch
|
|||
prev_src,
|
||||
id,
|
||||
L("Sensitive content"),
|
||||
xs_type(sensitive) == XSTYPE_TRUE ? "checked" : "",
|
||||
L("Sensitive content description"),
|
||||
xs_is_null(summary) ? "" : summary,
|
||||
L("Only for mentioned people"),
|
||||
L("Attach..."),
|
||||
L("File"),
|
||||
|
@ -728,10 +738,13 @@ xs_str *html_entry_controls(snac *snac, xs_str *os, const xs_dict *msg, const ch
|
|||
s = xs_str_cat(s, s1);
|
||||
}
|
||||
|
||||
{
|
||||
{ /** reply **/
|
||||
/* the post textarea */
|
||||
xs *ct = build_mentions(snac, msg);
|
||||
|
||||
const xs_val *sensitive = xs_dict_get(msg, "sensitive");
|
||||
const char *summary = xs_dict_get(msg, "summary");
|
||||
|
||||
xs *s1 = xs_fmt(
|
||||
"<p><details><summary>%s</summary>\n"
|
||||
"<p><div class=\"snac-note\" id=\"%s_reply\">\n"
|
||||
|
@ -741,7 +754,8 @@ xs_str *html_entry_controls(snac *snac, xs_str *os, const xs_dict *msg, const ch
|
|||
"rows=\"4\" wrap=\"virtual\" required=\"required\">%s</textarea>\n"
|
||||
"<input type=\"hidden\" name=\"in_reply_to\" value=\"%s\">\n"
|
||||
|
||||
"<p>%s: <input type=\"checkbox\" name=\"sensitive\">\n"
|
||||
"<p>%s: <input type=\"checkbox\" name=\"sensitive\" %s> "
|
||||
"<input type=\"text\" name=\"summary\" placeholder=\"%s\" value=\"%s\">\n"
|
||||
"<p>%s: <input type=\"checkbox\" name=\"mentioned_only\">\n"
|
||||
|
||||
"<details><summary>%s</summary>\n"
|
||||
|
@ -761,6 +775,9 @@ xs_str *html_entry_controls(snac *snac, xs_str *os, const xs_dict *msg, const ch
|
|||
ct,
|
||||
id,
|
||||
L("Sensitive content"),
|
||||
xs_type(sensitive) == XSTYPE_TRUE ? "checked" : "",
|
||||
L("Sensitive content description"),
|
||||
xs_is_null(summary) ? "" : summary,
|
||||
L("Only for mentioned people"),
|
||||
L("Attach..."),
|
||||
L("File"),
|
||||
|
@ -1437,7 +1454,7 @@ xs_str *html_notifications(snac *snac)
|
|||
"<form autocomplete=\"off\" "
|
||||
"method=\"post\" action=\"%s/admin/clear-notifications\" id=\"clear\">\n"
|
||||
"<input type=\"submit\" class=\"snac-btn-like\" value=\"%s\">\n"
|
||||
"</form><p>", snac->actor, L("Clear all"));
|
||||
"</form><p>\n", snac->actor, L("Clear all"));
|
||||
s = xs_str_cat(s, s1);
|
||||
|
||||
while (xs_list_iter(&p, &v)) {
|
||||
|
@ -1498,16 +1515,19 @@ xs_str *html_notifications(snac *snac)
|
|||
else
|
||||
if (strcmp(type, "Update") == 0 && strcmp(utype, "Question") == 0)
|
||||
label = L("Finished poll");
|
||||
else
|
||||
if (strcmp(type, "Undo") == 0 && strcmp(utype, "Follow") == 0)
|
||||
label = L("Unfollow");
|
||||
|
||||
xs *s1 = xs_fmt("<div class=\"snac-post-with-desc\">\n"
|
||||
"<p><b>%s by <a href=\"%s\">%s</a></b>:</p>\n",
|
||||
label, actor_id, a_name);
|
||||
s = xs_str_cat(s, s1);
|
||||
|
||||
if (strcmp(type, "Follow") == 0) {
|
||||
if (strcmp(type, "Follow") == 0 || strcmp(utype, "Follow") == 0) {
|
||||
s = xs_str_cat(s, "<div class=\"snac-post\">\n");
|
||||
|
||||
s = html_msg_icon(snac, s, obj);
|
||||
s = html_actor_icon(s, actor, NULL, NULL, NULL, 0);
|
||||
|
||||
s = xs_str_cat(s, "</div>\n");
|
||||
}
|
||||
|
@ -1843,6 +1863,7 @@ int html_post_handler(const xs_dict *req, const char *q_path,
|
|||
xs_list *attach_file = xs_dict_get(p_vars, "attach");
|
||||
xs_str *to = xs_dict_get(p_vars, "to");
|
||||
xs_str *sensitive = xs_dict_get(p_vars, "sensitive");
|
||||
xs_str *summary = xs_dict_get(p_vars, "summary");
|
||||
xs_str *edit_id = xs_dict_get(p_vars, "edit_id");
|
||||
xs_str *alt_text = xs_dict_get(p_vars, "alt_text");
|
||||
int priv = !xs_is_null(xs_dict_get(p_vars, "mentioned_only"));
|
||||
|
@ -1921,7 +1942,7 @@ int html_post_handler(const xs_dict *req, const char *q_path,
|
|||
|
||||
if (sensitive != NULL) {
|
||||
msg = xs_dict_set(msg, "sensitive", xs_stock_true);
|
||||
msg = xs_dict_set(msg, "summary", "...");
|
||||
msg = xs_dict_set(msg, "summary", xs_is_null(summary) ? "..." : summary);
|
||||
}
|
||||
|
||||
if (xs_is_null(edit_id)) {
|
||||
|
|
2
snac.h
2
snac.h
|
@ -207,6 +207,8 @@ int webfinger_get_handler(xs_dict *req, char *q_path,
|
|||
|
||||
const char *default_avatar_base64(void);
|
||||
|
||||
xs_str *process_tags(snac *snac, const char *content, xs_list **tag);
|
||||
|
||||
xs_dict *msg_admiration(snac *snac, char *object, char *type);
|
||||
xs_dict *msg_create(snac *snac, const xs_dict *object);
|
||||
xs_dict *msg_follow(snac *snac, const char *actor);
|
||||
|
|
Loading…
Reference in a new issue