forked from cory/tildefriends
		
	Format the new auth code.
This commit is contained in:
		@@ -1040,7 +1040,7 @@ const char* tf_http_get_cookie(const char* cookie_header, const char* name)
 | 
			
		||||
 | 
			
		||||
	int name_start = 0;
 | 
			
		||||
	int equals = 0;
 | 
			
		||||
	for (int i = 0; ; i++)
 | 
			
		||||
	for (int i = 0;; i++)
 | 
			
		||||
	{
 | 
			
		||||
		if (cookie_header[i] == '=')
 | 
			
		||||
		{
 | 
			
		||||
@@ -1048,9 +1048,7 @@ const char* tf_http_get_cookie(const char* cookie_header, const char* name)
 | 
			
		||||
		}
 | 
			
		||||
		else if (cookie_header[i] == ',' || cookie_header[i] == ';' || cookie_header[i] == '\0')
 | 
			
		||||
		{
 | 
			
		||||
			if (equals > name_start &&
 | 
			
		||||
				strncmp(cookie_header + name_start, name, equals - name_start) == 0 &&
 | 
			
		||||
				(int)strlen(name) == equals - name_start)
 | 
			
		||||
			if (equals > name_start && strncmp(cookie_header + name_start, name, equals - name_start) == 0 && (int)strlen(name) == equals - name_start)
 | 
			
		||||
			{
 | 
			
		||||
				int length = i - equals - 1;
 | 
			
		||||
				char* result = tf_malloc(length + 1);
 | 
			
		||||
 
 | 
			
		||||
@@ -846,10 +846,11 @@ static void _httpd_endpoint_login_file_read_callback(tf_task_t* task, const char
 | 
			
		||||
		{
 | 
			
		||||
			snprintf(cookie, length + 1, k_pattern, login->session_cookie, k_refresh_interval, request->is_tls ? "Secure; " : "");
 | 
			
		||||
		}
 | 
			
		||||
		const char* headers[] =
 | 
			
		||||
		{
 | 
			
		||||
			"Content-Type", "text/html; charset=utf-8",
 | 
			
		||||
			"Set-Cookie", cookie ? cookie : "",
 | 
			
		||||
		const char* headers[] = {
 | 
			
		||||
			"Content-Type",
 | 
			
		||||
			"text/html; charset=utf-8",
 | 
			
		||||
			"Set-Cookie",
 | 
			
		||||
			cookie ? cookie : "",
 | 
			
		||||
		};
 | 
			
		||||
		const char* replace_me = "$AUTH_DATA";
 | 
			
		||||
		const char* auth = strstr(data, replace_me);
 | 
			
		||||
@@ -945,9 +946,7 @@ static JSValue _authenticate_jwt(JSContext* context, const char* jwt)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	JSValue header_value = JS_ParseJSON(context, (const char*)header, actual_length, NULL);
 | 
			
		||||
	bool header_valid =
 | 
			
		||||
		_string_property_equals(context, header_value, "typ", "JWT") &&
 | 
			
		||||
		_string_property_equals(context, header_value, "alg", "HS256");
 | 
			
		||||
	bool header_valid = _string_property_equals(context, header_value, "typ", "JWT") && _string_property_equals(context, header_value, "alg", "HS256");
 | 
			
		||||
	JS_FreeValue(context, header_value);
 | 
			
		||||
	if (!header_valid)
 | 
			
		||||
	{
 | 
			
		||||
@@ -999,17 +998,13 @@ static bool _session_is_authenticated_as_user(JSContext* context, JSValue sessio
 | 
			
		||||
 | 
			
		||||
static bool _is_name_valid(const char* name)
 | 
			
		||||
{
 | 
			
		||||
	if (!name ||
 | 
			
		||||
		!((*name >= 'a' && *name <= 'z') || (*name >= 'A' && *name <= 'Z')))
 | 
			
		||||
	if (!name || !((*name >= 'a' && *name <= 'z') || (*name >= 'A' && *name <= 'Z')))
 | 
			
		||||
	{
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	for (const char* p = name; *p; p++)
 | 
			
		||||
	{
 | 
			
		||||
		bool in_range =
 | 
			
		||||
			(*p >= 'a' && *p <= 'z') ||
 | 
			
		||||
			(*p >= 'A' && *p <= 'Z') ||
 | 
			
		||||
			(*p >= '0' && *p <= '9');
 | 
			
		||||
		bool in_range = (*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9');
 | 
			
		||||
		if (!in_range)
 | 
			
		||||
		{
 | 
			
		||||
			return false;
 | 
			
		||||
@@ -1061,8 +1056,7 @@ static bool _set_account_password(JSContext* context, sqlite3* db, const char* n
 | 
			
		||||
	sqlite3_stmt* statement = NULL;
 | 
			
		||||
	if (sqlite3_prepare(db, "INSERT OR REPLACE INTO properties (id, key, value) VALUES ('auth', 'user:' || ?, ?)", -1, &statement, NULL) == SQLITE_OK)
 | 
			
		||||
	{
 | 
			
		||||
		if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK &&
 | 
			
		||||
			sqlite3_bind_text(statement, 2, user_string, user_length, NULL) == SQLITE_OK)
 | 
			
		||||
		if (sqlite3_bind_text(statement, 1, name, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, user_string, user_length, NULL) == SQLITE_OK)
 | 
			
		||||
		{
 | 
			
		||||
			result = sqlite3_step(statement) == SQLITE_DONE;
 | 
			
		||||
		}
 | 
			
		||||
@@ -1201,8 +1195,7 @@ static const char* _get_property(tf_ssb_t* ssb, const char* id, const char* key)
 | 
			
		||||
	sqlite3_stmt* statement = NULL;
 | 
			
		||||
	if (sqlite3_prepare(db, "SELECT value FROM properties WHERE id = ? AND key = ?", -1, &statement, NULL) == SQLITE_OK)
 | 
			
		||||
	{
 | 
			
		||||
		if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK &&
 | 
			
		||||
			sqlite3_bind_text(statement, 2, key, -1, NULL) == SQLITE_OK)
 | 
			
		||||
		if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, key, -1, NULL) == SQLITE_OK)
 | 
			
		||||
		{
 | 
			
		||||
			if (sqlite3_step(statement) == SQLITE_ROW)
 | 
			
		||||
			{
 | 
			
		||||
@@ -1225,8 +1218,7 @@ static bool _set_property(tf_ssb_t* ssb, const char* id, const char* key, const
 | 
			
		||||
	sqlite3_stmt* statement = NULL;
 | 
			
		||||
	if (sqlite3_prepare(db, "INSERT OR REPLACE INTO properties (id, key, value) VALUES (?, ?, ?)", -1, &statement, NULL) == SQLITE_OK)
 | 
			
		||||
	{
 | 
			
		||||
		if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK &&
 | 
			
		||||
			sqlite3_bind_text(statement, 2, key, -1, NULL) == SQLITE_OK &&
 | 
			
		||||
		if (sqlite3_bind_text(statement, 1, id, -1, NULL) == SQLITE_OK && sqlite3_bind_text(statement, 2, key, -1, NULL) == SQLITE_OK &&
 | 
			
		||||
			sqlite3_bind_text(statement, 3, value, -1, NULL) == SQLITE_OK)
 | 
			
		||||
		{
 | 
			
		||||
			result = sqlite3_step(statement) == SQLITE_DONE;
 | 
			
		||||
@@ -1256,9 +1248,9 @@ static void _httpd_endpoint_login(tf_http_request_t* request)
 | 
			
		||||
			snprintf(url, sizeof(url), "%s%s/", request->is_tls ? "https://" : "http://", tf_http_request_get_header(request, "host"));
 | 
			
		||||
			return_url = url;
 | 
			
		||||
		}
 | 
			
		||||
		const char* headers[] =
 | 
			
		||||
		{
 | 
			
		||||
			"Location", return_url,
 | 
			
		||||
		const char* headers[] = {
 | 
			
		||||
			"Location",
 | 
			
		||||
			return_url,
 | 
			
		||||
		};
 | 
			
		||||
		tf_http_respond(request, 303, headers, tf_countof(headers) / 2, NULL, 0);
 | 
			
		||||
		goto done;
 | 
			
		||||
@@ -1283,20 +1275,11 @@ static void _httpd_endpoint_login(tf_http_request_t* request)
 | 
			
		||||
			const char* change = _form_data_get(post_form_data, "change");
 | 
			
		||||
			const char* form_register = _form_data_get(post_form_data, "register");
 | 
			
		||||
			char account_passwd[256] = { 0 };
 | 
			
		||||
			bool have_account = _read_account(
 | 
			
		||||
				ssb,
 | 
			
		||||
				_form_data_get(post_form_data, "name"),
 | 
			
		||||
				account_passwd,
 | 
			
		||||
				sizeof(account_passwd));
 | 
			
		||||
			bool have_account = _read_account(ssb, _form_data_get(post_form_data, "name"), account_passwd, sizeof(account_passwd));
 | 
			
		||||
 | 
			
		||||
			if (form_register && strcmp(form_register, "1") == 0)
 | 
			
		||||
			{
 | 
			
		||||
				if (!have_account &&
 | 
			
		||||
					_is_name_valid(account_name) &&
 | 
			
		||||
					password &&
 | 
			
		||||
					confirm &&
 | 
			
		||||
					strcmp(password, confirm) == 0 &&
 | 
			
		||||
					_register_account(ssb, account_name, password))
 | 
			
		||||
				if (!have_account && _is_name_valid(account_name) && password && confirm && strcmp(password, confirm) == 0 && _register_account(ssb, account_name, password))
 | 
			
		||||
				{
 | 
			
		||||
					send_session = _make_session_jwt(ssb, account_name);
 | 
			
		||||
					may_become_first_admin = true;
 | 
			
		||||
@@ -1309,12 +1292,7 @@ static void _httpd_endpoint_login(tf_http_request_t* request)
 | 
			
		||||
			else if (change && strcmp(change, "1") == 0)
 | 
			
		||||
			{
 | 
			
		||||
				sqlite3* db = tf_ssb_acquire_db_writer(ssb);
 | 
			
		||||
				if (have_account &&
 | 
			
		||||
					_is_name_valid(account_name) &&
 | 
			
		||||
					new_password &&
 | 
			
		||||
					confirm &&
 | 
			
		||||
					strcmp(new_password, confirm) == 0 &&
 | 
			
		||||
					_verify_password(password, account_passwd) &&
 | 
			
		||||
				if (have_account && _is_name_valid(account_name) && new_password && confirm && strcmp(new_password, confirm) == 0 && _verify_password(password, account_passwd) &&
 | 
			
		||||
					_set_account_password(context, db, account_name, new_password))
 | 
			
		||||
				{
 | 
			
		||||
					send_session = _make_session_jwt(ssb, account_name);
 | 
			
		||||
@@ -1361,10 +1339,11 @@ static void _httpd_endpoint_login(tf_http_request_t* request)
 | 
			
		||||
		{
 | 
			
		||||
			snprintf(cookie, length + 1, k_pattern, send_session, k_refresh_interval, request->is_tls ? "Secure; " : "");
 | 
			
		||||
		}
 | 
			
		||||
		const char* headers[] =
 | 
			
		||||
		{
 | 
			
		||||
			"Location", return_url,
 | 
			
		||||
			"Set-Cookie", cookie ? cookie : "",
 | 
			
		||||
		const char* headers[] = {
 | 
			
		||||
			"Location",
 | 
			
		||||
			return_url,
 | 
			
		||||
			"Set-Cookie",
 | 
			
		||||
			cookie ? cookie : "",
 | 
			
		||||
		};
 | 
			
		||||
		tf_http_respond(request, 303, headers, tf_countof(headers) / 2, NULL, 0);
 | 
			
		||||
		tf_free(cookie);
 | 
			
		||||
@@ -1437,8 +1416,7 @@ static void _httpd_endpoint_login(tf_http_request_t* request)
 | 
			
		||||
		JS_FreeValue(context, permissions);
 | 
			
		||||
 | 
			
		||||
		login_request_t* login = tf_malloc(sizeof(login_request_t));
 | 
			
		||||
		*login = (login_request_t)
 | 
			
		||||
		{
 | 
			
		||||
		*login = (login_request_t) {
 | 
			
		||||
			.request = request,
 | 
			
		||||
			.name = account_name_copy,
 | 
			
		||||
			.jwt = jwt,
 | 
			
		||||
@@ -1467,17 +1445,17 @@ done:
 | 
			
		||||
 | 
			
		||||
static void _httpd_endpoint_logout(tf_http_request_t* request)
 | 
			
		||||
{
 | 
			
		||||
	const char* k_set_cookie = request->is_tls ?
 | 
			
		||||
		"session=; path=/; Secure; SameSite=Strict; expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly" :
 | 
			
		||||
		"session=; path=/; SameSite=Strict; expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly";
 | 
			
		||||
	const char* k_set_cookie = request->is_tls ? "session=; path=/; Secure; SameSite=Strict; expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly"
 | 
			
		||||
											   : "session=; path=/; SameSite=Strict; expires=Thu, 01 Jan 1970 00:00:00 GMT; HttpOnly";
 | 
			
		||||
	const char* k_location_format = "/login%s%s";
 | 
			
		||||
	int length = snprintf(NULL, 0, k_location_format, request->query ? "?" : "", request->query);
 | 
			
		||||
	char* location = alloca(length + 1);
 | 
			
		||||
	snprintf(location, length + 1, k_location_format, request->query ? "?" : "", request->query ? request->query : "");
 | 
			
		||||
	const char* headers[] =
 | 
			
		||||
	{
 | 
			
		||||
		"Set-Cookie", k_set_cookie,
 | 
			
		||||
		"Location", location,
 | 
			
		||||
	const char* headers[] = {
 | 
			
		||||
		"Set-Cookie",
 | 
			
		||||
		k_set_cookie,
 | 
			
		||||
		"Location",
 | 
			
		||||
		location,
 | 
			
		||||
	};
 | 
			
		||||
	tf_http_respond(request, 303, headers, tf_countof(headers) / 2, NULL, 0);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user