snac2

Fork of https://codeberg.org/grunfink/snac2
git clone https://git.inz.fi/snac2
Log | Files | Refs | README | LICENSE

commit b993e26346f885586ff0533a3b309ed7d1e910cf
parent ba4c3508f76466e79e9f3b5f665d72f0e425c4aa
Author: default <nobody@localhost>
Date:   Thu, 16 Jan 2025 14:20:07 +0100

Implemented Mastodon-like /authorize_interaction.

Diffstat:
Mhtml.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mhttpd.c | 42++++++++++++++++++++++++++++++++++++++++++
2 files changed, 103 insertions(+), 0 deletions(-)

diff --git a/html.c b/html.c @@ -3124,6 +3124,21 @@ int html_get_handler(const xs_dict *req, const char *q_path, else return HTTP_STATUS_NOT_FOUND; } + else + if (strcmp(v, "auth-int-bridge") == 0) { + const char *login = xs_dict_get(q_vars, "login"); + const char *id = xs_dict_get(q_vars, "id"); + const char *action = xs_dict_get(q_vars, "action"); + + if (xs_is_string(login) && xs_is_string(id) && xs_is_string(action)) { + *body = xs_fmt("%s/%s/authorize_interaction?action=%s&id=%s", + srv_baseurl, login, action, id); + + return HTTP_STATUS_SEE_OTHER; + } + else + return HTTP_STATUS_NOT_FOUND; + } uid = xs_dup(v); @@ -3696,6 +3711,52 @@ int html_get_handler(const xs_dict *req, const char *q_path, } } else + if (strcmp(p_path, "authorize_interaction") == 0) { /** follow, like or boost from Mastodon **/ + if (!login(&snac, req)) { + *body = xs_dup(uid); + status = HTTP_STATUS_UNAUTHORIZED; + } + else { + status = HTTP_STATUS_NOT_FOUND; + + const char *id = xs_dict_get(q_vars, "id"); + const char *action = xs_dict_get(q_vars, "action"); + + if (xs_is_string(id) && xs_is_string(action)) { + if (strcmp(action, "Follow") == 0) { + xs *msg = msg_follow(&snac, id); + + if (msg != NULL) { + const char *actor = xs_dict_get(msg, "object"); + + following_add(&snac, actor, msg); + + enqueue_output_by_actor(&snac, msg, actor, 0); + + status = HTTP_STATUS_SEE_OTHER; + } + } + else + if (xs_match(action, "Like|Boost|Announce")) { + /* bring the post */ + xs *msg = msg_admiration(&snac, id, *action == 'L' ? "Like" : "Announce"); + + if (msg != NULL) { + enqueue_message(&snac, msg); + timeline_admire(&snac, xs_dict_get(msg, "object"), snac.actor, *action == 'L' ? 1 : 0); + + status = HTTP_STATUS_SEE_OTHER; + } + } + } + + if (status == HTTP_STATUS_SEE_OTHER) { + *body = xs_fmt("%s/admin", snac.actor); + *b_size = strlen(*body); + } + } + } + else status = HTTP_STATUS_NOT_FOUND; user_free(&snac); diff --git a/httpd.c b/httpd.c @@ -182,6 +182,29 @@ const char *share_page = "" ""; +const char *authorize_interaction_page = "" +"<!DOCTYPE html>\n" +"<html>\n" +"<head>\n" +"<title>%s - snac</title>\n" +"<meta content=\"width=device-width, initial-scale=1, minimum-scale=1, user-scalable=no\" name=\"viewport\">\n" +"<link rel=\"stylesheet\" type=\"text/css\" href=\"%s/style.css\"/>\n" +"<style>:root {color-scheme: light dark}</style>\n" +"</head>\n" +"<body><h1>%s authorize interaction</h1>\n" +"<form method=\"get\" action=\"%s/auth-int-bridge\">\n" +"<select name=\"action\">\n" +"<option value=\"Follow\">Follow</option>\n" +"<option value=\"Like\">Like</option>\n" +"<option value=\"Boost\">Boost</option>\n" +"</select> %s\n" +"<input type=\"hidden\" name=\"id\" value=\"%s\">\n" +"<p>Login: <input type=\"text\" name=\"login\" autocapitalize=\"off\" required=\"required\"></p>\n" +"<input type=\"submit\" value=\"OK\">\n" +"</form><p>%s</p></body></html>\n" +""; + + int server_get_handler(xs_dict *req, const char *q_path, char **body, int *b_size, char **ctype) /* basic server services */ @@ -318,6 +341,25 @@ int server_get_handler(xs_dict *req, const char *q_path, USER_AGENT ); } + else + if (strcmp(q_path, "/authorize_interaction") == 0) { + const xs_dict *q_vars = xs_dict_get(req, "q_vars"); + const char *uri = xs_dict_get(q_vars, "uri"); + + if (xs_is_string(uri)) { + status = HTTP_STATUS_OK; + *ctype = "text/html; charset=utf-8"; + *body = xs_fmt(authorize_interaction_page, + xs_dict_get(srv_config, "host"), + srv_baseurl, + xs_dict_get(srv_config, "host"), + srv_baseurl, + uri, + uri, + USER_AGENT + ); + } + } if (status != 0) srv_debug(1, xs_fmt("server_get_handler serving '%s' %d", q_path, status));