summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RELEASE_NOTES.md4
-rw-r--r--activitypub.c2
-rw-r--r--data/greeting.html13
-rw-r--r--data/server.json21
-rw-r--r--data/style.css27
-rw-r--r--html.c10
-rw-r--r--httpd.c8
-rw-r--r--mastoapi.c45
-rw-r--r--utils.c1
-rw-r--r--xs_formdata.h27
10 files changed, 148 insertions, 10 deletions
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 7d3f683..4614da6 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -4,10 +4,12 @@
4 4
5Added support for Peertube videos. 5Added support for Peertube videos.
6 6
7Mastodon API: Added support for editing posts, fixed an error related to the edit date of a post. 7Mastodon API: Added support for editing posts, fixed an error related to the edit date of a post, fixed some crashes.
8 8
9Added a handshake emoji next to a user name if it's a mutual relation (follower and followed), because friendship is bliss. 9Added a handshake emoji next to a user name if it's a mutual relation (follower and followed), because friendship is bliss.
10 10
11Tweaked some retry timeout values for better behaviour in larger instances (thanks to me@mysmallinstance.homelinux.org for their help).
12
11## 2.45 13## 2.45
12 14
13Fixed a collision in webfinger caching. This may affect federation with some software, so I recommend an upgrade. 15Fixed a collision in webfinger caching. This may affect federation with some software, so I recommend an upgrade.
diff --git a/activitypub.c b/activitypub.c
index e680e33..698758c 100644
--- a/activitypub.c
+++ b/activitypub.c
@@ -2220,7 +2220,7 @@ void process_queue_item(xs_dict *q_item)
2220 2220
2221 /* deliver (if previous error status was a timeout, try now longer) */ 2221 /* deliver (if previous error status was a timeout, try now longer) */
2222 status = send_to_inbox_raw(keyid, seckey, inbox, msg, 2222 status = send_to_inbox_raw(keyid, seckey, inbox, msg,
2223 &payload, &p_size, p_status == 599 ? 20 : 3); 2223 &payload, &p_size, p_status == 599 ? 8 : 6);
2224 2224
2225 if (payload) { 2225 if (payload) {
2226 if (p_size > 64) { 2226 if (p_size > 64) {
diff --git a/data/greeting.html b/data/greeting.html
new file mode 100644
index 0000000..b664538
--- /dev/null
+++ b/data/greeting.html
@@ -0,0 +1,13 @@
1<!DOCTYPE html>
2<html><head>
3<meta name="viewport" content="width=device-width, initial-scale=1"/>
4<title>Welcome to %host%</title>
5<body style="margin: auto; max-width: 50em">
6<p><b>%host%</b> is a <a href="https://en.wikipedia.org/wiki/Fediverse">Fediverse</a> instance that uses the <a href="https://en.wikipedia.org/wiki/ActivityPub">ActivityPub</a> protocol. In other words, users at this host can communicate with people that use software like Mastodon, Pleroma, Friendica, etc. all around the world.</p>
7<p>This server runs the <a href="https://comam.es/what-is-snac">snac</a> software and there is no automatic sign-up process.</p>
8<p>The following users are part of this community:</p>
9
10%userlist%
11
12<p>This site is powered by <abbr title="Social Networks Are Crap">snac</abbr>.</p>
13</body></html>
diff --git a/data/server.json b/data/server.json
new file mode 100644
index 0000000..901f377
--- /dev/null
+++ b/data/server.json
@@ -0,0 +1,21 @@
1{
2 "prefix": "",
3 "port": 8001,
4 "dbglevel": 0,
5 "queue_retry_minutes": 2,
6 "queue_retry_max": 10,
7 "cssurls": [
8 ""
9 ],
10 "max_timeline_entries": 128,
11 "timeline_purge_days": 120,
12 "local_purge_days": 0,
13 "admin_account": "",
14 "title": "",
15 "short_description": "",
16 "fastcgi": false,
17 "layout": 2.7,
18 "address": "0.0.0.0",
19 "host": "snac.notnull.space",
20 "admin_email": "paul@notnull.space"
21} \ No newline at end of file
diff --git a/data/style.css b/data/style.css
new file mode 100644
index 0000000..24be520
--- /dev/null
+++ b/data/style.css
@@ -0,0 +1,27 @@
1body { max-width: 48em; margin: auto; line-height: 1.5; padding: 0.8em; word-wrap: break-word; }
2pre { overflow-x: scroll; }
3.snac-embedded-video, img { max-width: 100% }
4.snac-origin { font-size: 85% }
5.snac-score { float: right; font-size: 85% }
6.snac-top-user { text-align: center; padding-bottom: 2em }
7.snac-top-user-name { font-size: 200% }
8.snac-top-user-id { font-size: 150% }
9.snac-avatar { float: left; height: 2.5em; padding: 0.25em }
10.snac-author { font-size: 90%; text-decoration: none }
11.snac-author-tag { font-size: 80% }
12.snac-pubdate { color: #a0a0a0; font-size: 90% }
13.snac-top-controls { padding-bottom: 1.5em }
14.snac-post { border-top: 1px solid #a0a0a0; }
15.snac-children { padding-left: 2em; border-left: 1px solid #a0a0a0; }
16.snac-textarea { font-family: inherit; width: 100% }
17.snac-history { border: 1px solid #606060; border-radius: 3px; margin: 2.5em 0; padding: 0 2em }
18.snac-btn-mute { float: right; margin-left: 0.5em }
19.snac-btn-unmute { float: right; margin-left: 0.5em }
20.snac-btn-follow { float: right; margin-left: 0.5em }
21.snac-btn-unfollow { float: right; margin-left: 0.5em }
22.snac-btn-hide { float: right; margin-left: 0.5em }
23.snac-btn-delete { float: right; margin-left: 0.5em }
24.snac-btn-limit { float: right; margin-left: 0.5em }
25.snac-btn-unlimit { float: right; margin-left: 0.5em }
26.snac-footer { margin-top: 2em; font-size: 75% }
27.snac-poll-result { margin-left: auto; margin-right: auto; }
diff --git a/html.c b/html.c
index 444a53d..de2c60e 100644
--- a/html.c
+++ b/html.c
@@ -427,7 +427,9 @@ static xs_html *html_base_head(void)
427 xs_html_attr("name", "generator"), 427 xs_html_attr("name", "generator"),
428 xs_html_attr("content", USER_AGENT))); 428 xs_html_attr("content", USER_AGENT)));
429 429
430 /* add server CSS */ 430 /* add server CSS and favicon */
431 xs *f;
432 f = xs_fmt("%s/favicon.ico", srv_baseurl);
431 xs_list *p = xs_dict_get(srv_config, "cssurls"); 433 xs_list *p = xs_dict_get(srv_config, "cssurls");
432 char *v; 434 char *v;
433 while (xs_list_iter(&p, &v)) { 435 while (xs_list_iter(&p, &v)) {
@@ -438,6 +440,12 @@ static xs_html *html_base_head(void)
438 xs_html_attr("href", v))); 440 xs_html_attr("href", v)));
439 } 441 }
440 442
443 xs_html_add(head,
444 xs_html_sctag("link",
445 xs_html_attr("rel", "icon"),
446 xs_html_attr("type", "image/x-icon"),
447 xs_html_attr("href", f)));
448
441 return head; 449 return head;
442} 450}
443 451
diff --git a/httpd.c b/httpd.c
index a20d692..3a39481 100644
--- a/httpd.c
+++ b/httpd.c
@@ -243,6 +243,14 @@ int server_get_handler(xs_dict *req, const char *q_path,
243 *body = xs_str_new("User-agent: *\n" 243 *body = xs_str_new("User-agent: *\n"
244 "Disallow: /\n"); 244 "Disallow: /\n");
245 } 245 }
246 else
247 if (strcmp(q_path, "/.well-known/host-meta") == 0) {
248 status = 200;
249 *ctype = "application/xrd+xml";
250 *body = xs_str_new("<XRD>"
251 "<Link rel=\"lrdd\" type=\"application/xrd+xml\" template=\"%s/.well-known/webfinger?resource={uri}\"/>"
252 "</XRD>");
253 }
246 254
247 if (status != 0) 255 if (status != 0)
248 srv_debug(1, xs_fmt("server_get_handler serving '%s' %d", q_path, status)); 256 srv_debug(1, xs_fmt("server_get_handler serving '%s' %d", q_path, status));
diff --git a/mastoapi.c b/mastoapi.c
index 9f6c383..6ed3835 100644
--- a/mastoapi.c
+++ b/mastoapi.c
@@ -240,8 +240,10 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
240 char *i_ctype = xs_dict_get(req, "content-type"); 240 char *i_ctype = xs_dict_get(req, "content-type");
241 xs *args = NULL; 241 xs *args = NULL;
242 242
243 if (i_ctype && xs_startswith(i_ctype, "application/json")) 243 if (i_ctype && xs_startswith(i_ctype, "application/json")) {
244 args = xs_json_loads(payload); 244 if (!xs_is_null(payload))
245 args = xs_json_loads(payload);
246 }
245 else 247 else
246 if (i_ctype && xs_startswith(i_ctype, "application/x-www-form-urlencoded") && payload) { 248 if (i_ctype && xs_startswith(i_ctype, "application/x-www-form-urlencoded") && payload) {
247 xs *upl = xs_url_dec(payload); 249 xs *upl = xs_url_dec(payload);
@@ -250,6 +252,9 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
250 else 252 else
251 args = xs_dup(xs_dict_get(req, "p_vars")); 253 args = xs_dup(xs_dict_get(req, "p_vars"));
252 254
255 if (args == NULL)
256 return 400;
257
253 xs *cmd = xs_replace_n(q_path, "/oauth", "", 1); 258 xs *cmd = xs_replace_n(q_path, "/oauth", "", 1);
254 259
255 srv_debug(1, xs_fmt("oauth_post_handler %s", q_path)); 260 srv_debug(1, xs_fmt("oauth_post_handler %s", q_path));
@@ -354,6 +359,12 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
354 } 359 }
355 } 360 }
356 361
362 /* no code?
363 I'm not sure of the impacts of this right now, but Subway Tooter does not
364 provide a code so one must be generated */
365 if (xs_is_null(code)){
366 code = random_str();
367 }
357 if (gtype && code && cid && csec && ruri) { 368 if (gtype && code && cid && csec && ruri) {
358 xs *app = app_get(cid); 369 xs *app = app_get(cid);
359 370
@@ -1403,7 +1414,6 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1403 const char *type = xs_dict_get(msg, "type"); 1414 const char *type = xs_dict_get(msg, "type");
1404 if (!xs_match(type, "Note|Question|Page|Article")) 1415 if (!xs_match(type, "Note|Question|Page|Article"))
1405 continue; 1416 continue;
1406
1407 const char *from = NULL; 1417 const char *from = NULL;
1408 if (strcmp(type, "Page") == 0) 1418 if (strcmp(type, "Page") == 0)
1409 from = xs_dict_get(msg, "audience"); 1419 from = xs_dict_get(msg, "audience");
@@ -1617,6 +1627,15 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1617 status = 200; 1627 status = 200;
1618 } 1628 }
1619 else 1629 else
1630 if (strcmp(cmd, "/v2/filters") == 0) { /** **/
1631 /* snac will never have filters
1632 * but still, without a v2 endpoint a short delay is introduced
1633 * in some apps */
1634 *body = xs_dup("[]");
1635 *ctype = "application/json";
1636 status = 200;
1637 }
1638 else
1620 if (strcmp(cmd, "/v1/favourites") == 0) { /** **/ 1639 if (strcmp(cmd, "/v1/favourites") == 0) { /** **/
1621 /* snac will never support a list of favourites */ 1640 /* snac will never support a list of favourites */
1622 *body = xs_dup("[]"); 1641 *body = xs_dup("[]");
@@ -1981,8 +2000,18 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
1981 xs *args = NULL; 2000 xs *args = NULL;
1982 char *i_ctype = xs_dict_get(req, "content-type"); 2001 char *i_ctype = xs_dict_get(req, "content-type");
1983 2002
1984 if (i_ctype && xs_startswith(i_ctype, "application/json")) 2003 if (i_ctype && xs_startswith(i_ctype, "application/json")) {
1985 args = xs_json_loads(payload); 2004 if (!xs_is_null(payload))
2005 args = xs_json_loads(payload);
2006 }
2007 else if (i_ctype && xs_startswith(i_ctype, "application/x-www-form-urlencoded"))
2008 {
2009 // Some apps send form data instead of json so we should cater for those
2010 if (!xs_is_null(payload)) {
2011 xs *upl = xs_url_dec(payload);
2012 args = xs_url_vars(upl);
2013 }
2014 }
1986 else 2015 else
1987 args = xs_dup(xs_dict_get(req, "p_vars")); 2016 args = xs_dup(xs_dict_get(req, "p_vars"));
1988 2017
@@ -2504,8 +2533,10 @@ int mastoapi_put_handler(const xs_dict *req, const char *q_path,
2504 xs *args = NULL; 2533 xs *args = NULL;
2505 char *i_ctype = xs_dict_get(req, "content-type"); 2534 char *i_ctype = xs_dict_get(req, "content-type");
2506 2535
2507 if (i_ctype && xs_startswith(i_ctype, "application/json")) 2536 if (i_ctype && xs_startswith(i_ctype, "application/json")) {
2508 args = xs_json_loads(payload); 2537 if (!xs_is_null(payload))
2538 args = xs_json_loads(payload);
2539 }
2509 else 2540 else
2510 args = xs_dup(xs_dict_get(req, "p_vars")); 2541 args = xs_dup(xs_dict_get(req, "p_vars"));
2511 2542
diff --git a/utils.c b/utils.c
index 9992205..0d02659 100644
--- a/utils.c
+++ b/utils.c
@@ -81,6 +81,7 @@ static const char *greeting_html =
81 "<!DOCTYPE html>\n" 81 "<!DOCTYPE html>\n"
82 "<html><head>\n" 82 "<html><head>\n"
83 "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/>\n" 83 "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/>\n"
84 "<link rel=\"icon\" type=\"image/x-icon\" href=\"https://%host%/favicon.ico\"/>\n"
84 "<title>Welcome to %host%</title>\n" 85 "<title>Welcome to %host%</title>\n"
85 "<body style=\"margin: auto; max-width: 50em\">\n" 86 "<body style=\"margin: auto; max-width: 50em\">\n"
86 "%blurb%" 87 "%blurb%"
diff --git a/xs_formdata.h b/xs_formdata.h
new file mode 100644
index 0000000..213bd3e
--- /dev/null
+++ b/xs_formdata.h
@@ -0,0 +1,27 @@
1/* copyright (c) 2022 - 2024 grunfink et al. / MIT license */
2#include "xs.h"
3
4#ifndef _XS_FORMDATA_H
5
6#define _XS_FORMDATA_H
7
8xs_val *xs_formdata_loads(const xs_str *formdata);
9
10#ifdef XS_IMPLEMENTATION
11
12/** IMPLEMENTATION **/
13
14xs_val *xs_formdata_loads(const xs_str *formdata)
15/* loads a string in formdata format and converts to a multiple data */
16{
17 xs_val *v = NULL;
18 xs_list *args = xs_split(formdata, "&");
19 int i = 0;
20 while (){}
21 printf("args: %s\r\n", args); fflush(stdout);
22 printf("data: %s\r\n", formdata); fflush(stdout);
23}
24
25#endif /* XS_IMPLEMENTATION */
26
27#endif /* _XS_FORMDATA_H */