From 15df4ac2360970b6a322083e579d2544d5fa3bcd Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Wed, 12 Feb 2025 19:25:05 -0500 Subject: [PATCH] auth: Skip auth on mobile. #97 --- .../tildefriends/TildeFriendsActivity.java | 2 +- src/httpd.js.c | 114 ++++++++++++++++++ src/ssb.db.c | 4 +- src/util.js.c | 5 + src/util.js.h | 8 +- 5 files changed, 129 insertions(+), 4 deletions(-) diff --git a/src/android/com/unprompted/tildefriends/TildeFriendsActivity.java b/src/android/com/unprompted/tildefriends/TildeFriendsActivity.java index 4bdb460f..a8cb829c 100644 --- a/src/android/com/unprompted/tildefriends/TildeFriendsActivity.java +++ b/src/android/com/unprompted/tildefriends/TildeFriendsActivity.java @@ -421,7 +421,7 @@ public class TildeFriendsActivity extends Activity { base_url = "http://127.0.0.1:" + String.valueOf(port) + "/"; runOnUiThread(() -> { hide_status(); - web_view.loadUrl(base_url); + web_view.loadUrl(base_url + "login/auto"); }); observer = null; } else { diff --git a/src/httpd.js.c b/src/httpd.js.c index ce4e9d85..d25cb43a 100644 --- a/src/httpd.js.c +++ b/src/httpd.js.c @@ -2166,6 +2166,119 @@ static void _httpd_endpoint_logout(tf_http_request_t* request) tf_http_respond(request, 303, headers, tf_countof(headers) / 2, NULL, 0); } +static bool _task_arg_is_mobile(tf_task_t* task) +{ + bool result = false; + JSContext* context = tf_task_get_context(task); + JSValue global = JS_GetGlobalObject(context); + JSValue tildefriends = JS_GetPropertyStr(context, global, "tildefriends"); + JSValue args = JS_GetPropertyStr(context, tildefriends, "args"); + JSValue mobile = JS_GetPropertyStr(context, args, "mobile"); + result = JS_ToBool(context, mobile) != 0; + JS_FreeValue(context, mobile); + JS_FreeValue(context, args); + JS_FreeValue(context, tildefriends); + JS_FreeValue(context, global); + return result; +} + +typedef struct _auto_login_t +{ + tf_http_request_t* request; + const char* users; +} auto_login_t; + +static void _httpd_auto_login_work(tf_ssb_t* ssb, void* user_data) +{ + tf_printf("AUTO LOGIN\n"); + auto_login_t* request = user_data; + request->users = tf_ssb_db_get_property(ssb, "auth", "users"); + if (request->users && strcmp(request->users, "[]") == 0) + { + tf_printf("AUTO LOGIN NO USERS\n"); + tf_free((void*)request->users); + request->users = NULL; + } + + if (!request->users) + { + sqlite3* db = tf_ssb_acquire_db_writer(ssb); + JSMallocFunctions funcs = { 0 }; + tf_get_js_malloc_functions(&funcs); + JSRuntime* runtime = JS_NewRuntime2(&funcs, NULL); + JSContext* context = JS_NewContext(runtime); + tf_ssb_db_register_account(tf_ssb_get_loop(ssb), db, context, "mobile", "mobile"); + tf_ssb_release_db_writer(ssb, db); + JS_FreeContext(context); + JS_FreeRuntime(runtime); + + request->users = tf_ssb_db_get_property(ssb, "auth", "users"); + tf_printf("AUTO LOGIN USERS = %s\n", request->users); + } +} + +static void _httpd_auto_login_after_work(tf_ssb_t* ssb, int status, void* user_data) +{ + auto_login_t* work = user_data; + JSContext* context = tf_ssb_get_context(ssb); + const char* session_token = NULL; + if (work->users) + { + JSValue json = JS_ParseJSON(context, work->users, strlen(work->users), NULL); + JSValue user = JS_GetPropertyUint32(context, json, 0); + const char* user_string = JS_ToCString(context, user); + tf_printf("AUTO LOGIN %s\n", user_string); + session_token = _make_session_jwt(context, ssb, user_string); + JS_FreeCString(context, user_string); + JS_FreeValue(context, user); + JS_FreeValue(context, json); + } + if (session_token) + { + const char* cookie = _make_set_session_cookie_header(work->request, session_token); + tf_printf("COOKIE = %s\n", session_token); + tf_free((void*)session_token); + const char* headers[] = { + "Set-Cookie", + cookie, + "Location", + "/", + }; + tf_http_respond(work->request, 303, headers, tf_countof(headers) / 2, NULL, 0); + tf_free((void*)cookie); + } + else + { + tf_printf("NO COOKIE FOR YOU\n"); + const char* headers[] = { + "Location", + "/", + }; + tf_http_respond(work->request, 303, headers, tf_countof(headers) / 2, NULL, 0); + } + tf_http_request_unref(work->request); + tf_free(work); +} + +static void _httpd_endpoint_login_auto(tf_http_request_t* request) +{ + tf_task_t* task = request->user_data; + if (tf_util_is_mobile() || _task_arg_is_mobile(task)) + { + tf_http_request_ref(request); + tf_ssb_t* ssb = tf_task_get_ssb(task); + + auto_login_t* work = tf_malloc(sizeof(auto_login_t)); + *work = (auto_login_t) { .request = request }; + tf_ssb_run_work(ssb, _httpd_auto_login_work, _httpd_auto_login_after_work, work); + } + else + { + const char* k_payload = tf_http_status_text(404); + tf_http_respond(request, 404, NULL, 0, k_payload, strlen(k_payload)); + } +} + static void _httpd_endpoint_app_socket(tf_http_request_t* request) { tf_task_t* task = request->user_data; @@ -2341,6 +2454,7 @@ void tf_httpd_register(JSContext* context) tf_http_add_handler(http, "/trace", _httpd_endpoint_trace, NULL, task); tf_http_add_handler(http, "/login/logout", _httpd_endpoint_logout, NULL, task); + tf_http_add_handler(http, "/login/auto", _httpd_endpoint_login_auto, NULL, task); tf_http_add_handler(http, "/login", _httpd_endpoint_login, NULL, task); tf_http_add_handler(http, "/app/socket", _httpd_endpoint_app_socket, NULL, task); diff --git a/src/ssb.db.c b/src/ssb.db.c index 800d347b..48ae8335 100644 --- a/src/ssb.db.c +++ b/src/ssb.db.c @@ -2255,8 +2255,8 @@ bool tf_ssb_db_use_invite(sqlite3* db, const char* id) { bool used = false; sqlite3_stmt* statement; - if (sqlite3_prepare(db, "UPDATE invites SET use_count = use_count - 1 WHERE invite_public_key = ? AND (expires < 0 OR expires >= ?) AND (use_count > 0 OR use_count = -1)", -1, &statement, - NULL) == SQLITE_OK) + if (sqlite3_prepare(db, "UPDATE invites SET use_count = use_count - 1 WHERE invite_public_key = ? AND (expires < 0 OR expires >= ?) AND (use_count > 0 OR use_count = -1)", -1, + &statement, NULL) == SQLITE_OK) { if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK && sqlite3_bind_int64(statement, 2, (int64_t)time(NULL)) == SQLITE_OK) { diff --git a/src/util.js.c b/src/util.js.c index 5dac6d0b..e0e06a1f 100644 --- a/src/util.js.c +++ b/src/util.js.c @@ -639,3 +639,8 @@ int tf_util_backtrace(void** buffer, int count) return backtrace(buffer, count); #endif } + +bool tf_util_is_mobile() +{ + return TF_IS_MOBILE != 0; +} diff --git a/src/util.js.h b/src/util.js.h index 2c434d1f..1cb2be3a 100644 --- a/src/util.js.h +++ b/src/util.js.h @@ -188,10 +188,16 @@ bool tf_util_get_default_global_setting_bool(const char* name); int tf_util_get_default_global_setting_int(const char* name); /** -** Get teh default value of a global setting as a string. +** Get the default value of a global setting as a string. ** @param name The setting name. ** @return The default value. */ const char* tf_util_get_default_global_setting_string(const char* name); +/** +** Check if the app is running on a mobile device. +** @return true for iPhone/Android, false otherwise. +*/ +bool tf_util_is_mobile(); + /** @} */