Compare commits
	
		
			2 Commits
		
	
	
		
			017a74c4e4
			...
			e491798ff1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e491798ff1 | |||
| 15df4ac236 | 
| @@ -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 { | ||||
|   | ||||
							
								
								
									
										114
									
								
								src/httpd.js.c
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								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) | ||||
| { | ||||
| 	auto_login_t* request = user_data; | ||||
| 	request->users = tf_ssb_db_get_property(ssb, "auth", "users"); | ||||
| 	if (request->users && strcmp(request->users, "[]") == 0) | ||||
| 	{ | ||||
| 		tf_free((void*)request->users); | ||||
| 		request->users = NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (!request->users) | ||||
| 	{ | ||||
| 		JSMallocFunctions funcs = { 0 }; | ||||
| 		tf_get_js_malloc_functions(&funcs); | ||||
| 		JSRuntime* runtime = JS_NewRuntime2(&funcs, NULL); | ||||
| 		JSContext* context = JS_NewContext(runtime); | ||||
| 		static const char* k_account_name = "mobile"; | ||||
| 		sqlite3* db = tf_ssb_acquire_db_writer(ssb); | ||||
| 		bool registered = tf_ssb_db_register_account(tf_ssb_get_loop(ssb), db, context, k_account_name, k_account_name); | ||||
| 		tf_ssb_release_db_writer(ssb, db); | ||||
| 		if (registered) | ||||
| 		{ | ||||
| 			_make_administrator_if_first(ssb, context, k_account_name, true); | ||||
| 		} | ||||
| 		JS_FreeContext(context); | ||||
| 		JS_FreeRuntime(runtime); | ||||
|  | ||||
| 		request->users = tf_ssb_db_get_property(ssb, "auth", "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); | ||||
| 		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_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 | ||||
| 	{ | ||||
| 		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((void*)work->users); | ||||
| 	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); | ||||
|   | ||||
| @@ -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) | ||||
| 		{ | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -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(); | ||||
|  | ||||
| /** @} */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user