forked from cory/tildefriends
Remove auth.js. #7
This commit is contained in:
@ -36,6 +36,7 @@
|
||||
const int64_t k_refresh_interval = 1ULL * 7 * 24 * 60 * 60 * 1000;
|
||||
|
||||
static JSValue _authenticate_jwt(JSContext* context, const char* jwt);
|
||||
static const char* _get_property(tf_ssb_t* ssb, const char* id, const char* key);
|
||||
static JSValue _httpd_websocket_upgrade(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv);
|
||||
static const char* _make_session_jwt(tf_ssb_t* ssb, const char* name);
|
||||
static const char* _make_set_session_cookie_header(tf_http_request_t* request, const char* session_cookie);
|
||||
@ -443,6 +444,58 @@ static JSValue _httpd_set_http_redirect(JSContext* context, JSValueConst this_va
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
static JSValue _httpd_auth_query(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||
{
|
||||
tf_task_t* task = tf_task_get(context);
|
||||
tf_ssb_t* ssb = tf_task_get_ssb(task);
|
||||
JSValue headers = argv[0];
|
||||
if (JS_IsUndefined(headers))
|
||||
{
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
JSValue cookie = JS_GetPropertyStr(context, headers, "cookie");
|
||||
const char* cookie_string = JS_ToCString(context, cookie);
|
||||
const char* session = tf_http_get_cookie(cookie_string, "session");
|
||||
JSValue entry = _authenticate_jwt(context, session);
|
||||
tf_free((void*)session);
|
||||
JS_FreeCString(context, cookie_string);
|
||||
JS_FreeValue(context, cookie);
|
||||
|
||||
JSValue result = JS_UNDEFINED;
|
||||
if (!JS_IsUndefined(entry))
|
||||
{
|
||||
result = JS_NewObject(context);
|
||||
JS_SetPropertyStr(context, result, "session", entry);
|
||||
JSValue out_permissions = JS_NewObject(context);
|
||||
JS_SetPropertyStr(context, result, "permissions", out_permissions);
|
||||
|
||||
JSValue name = JS_GetPropertyStr(context, entry, "name");
|
||||
const char* name_string = JS_ToCString(context, name);
|
||||
|
||||
const char* settings = _get_property(ssb, "core", "settings");
|
||||
JSValue settings_value = settings ? JS_ParseJSON(context, settings, strlen(settings), NULL) : JS_UNDEFINED;
|
||||
JSValue permissions = JS_GetPropertyStr(context, settings_value, "permissions");
|
||||
JSValue user_permissions = JS_GetPropertyStr(context, permissions, name_string);
|
||||
int length = tf_util_get_length(context, user_permissions);
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
JSValue permission = JS_GetPropertyUint32(context, user_permissions, i);
|
||||
const char* permission_string = JS_ToCString(context, permission);
|
||||
JS_SetPropertyStr(context, out_permissions, permission_string, JS_TRUE);
|
||||
JS_FreeCString(context, permission_string);
|
||||
JS_FreeValue(context, permission);
|
||||
}
|
||||
JS_FreeValue(context, user_permissions);
|
||||
JS_FreeValue(context, permissions);
|
||||
JS_FreeValue(context, settings_value);
|
||||
tf_free((void*)settings);
|
||||
JS_FreeCString(context, name_string);
|
||||
JS_FreeValue(context, name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void _httpd_finalizer(JSRuntime* runtime, JSValue value)
|
||||
{
|
||||
tf_http_t* http = JS_GetOpaque(value, _httpd_class_id);
|
||||
@ -965,13 +1018,14 @@ static JSValue _authenticate_jwt(JSContext* context, const char* jwt)
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
uint8_t header[256];
|
||||
uint8_t header[256] = { 0 };
|
||||
size_t actual_length = 0;
|
||||
if (sodium_base642bin(header, sizeof(header), jwt, dot[0], NULL, &actual_length, NULL, sodium_base64_VARIANT_URLSAFE_NO_PADDING) != 0)
|
||||
if (sodium_base642bin(header, sizeof(header), jwt, dot[0], NULL, &actual_length, NULL, sodium_base64_VARIANT_URLSAFE_NO_PADDING) != 0 || actual_length >= sizeof(header))
|
||||
{
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
header[actual_length] = '\0';
|
||||
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");
|
||||
JS_FreeValue(context, header_value);
|
||||
@ -986,19 +1040,21 @@ static JSValue _authenticate_jwt(JSContext* context, const char* jwt)
|
||||
tf_ssb_db_identity_visit(ssb, ":auth", _public_key_visit, public_key_b64);
|
||||
|
||||
const char* payload = jwt + dot[0] + 1;
|
||||
size_t payload_length = dot[1] - dot[0];
|
||||
if (!tf_ssb_hmacsha256_verify(public_key_b64, payload, payload_length, jwt + dot[1] + 1))
|
||||
size_t payload_length = dot[1] - dot[0] - 1;
|
||||
if (!tf_ssb_hmacsha256_verify(public_key_b64, payload, payload_length, jwt + dot[1] + 1, true))
|
||||
{
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
uint8_t payload_bin[256];
|
||||
size_t actual_payload_length = 0;
|
||||
if (sodium_base642bin(payload_bin, sizeof(payload_bin), payload, payload_length, NULL, &actual_payload_length, NULL, sodium_base64_VARIANT_URLSAFE_NO_PADDING) != 0)
|
||||
if (sodium_base642bin(payload_bin, sizeof(payload_bin), payload, payload_length, NULL, &actual_payload_length, NULL, sodium_base64_VARIANT_URLSAFE_NO_PADDING) != 0 ||
|
||||
actual_payload_length >= sizeof(payload_bin))
|
||||
{
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
payload_bin[actual_payload_length] = '\0';
|
||||
JSValue parsed = JS_ParseJSON(context, (const char*)payload_bin, actual_payload_length, NULL);
|
||||
JSValue exp = JS_GetPropertyStr(context, parsed, "exp");
|
||||
int64_t exp_value = 0;
|
||||
@ -1539,6 +1595,7 @@ void tf_httpd_register(JSContext* context)
|
||||
JS_SetPropertyStr(context, httpd, "all", JS_NewCFunction(context, _httpd_endpoint_all, "all", 2));
|
||||
JS_SetPropertyStr(context, httpd, "start", JS_NewCFunction(context, _httpd_endpoint_start, "start", 2));
|
||||
JS_SetPropertyStr(context, httpd, "set_http_redirect", JS_NewCFunction(context, _httpd_set_http_redirect, "set_http_redirect", 1));
|
||||
JS_SetPropertyStr(context, httpd, "auth_query", JS_NewCFunction(context, _httpd_auth_query, "auth_query", 1));
|
||||
JS_SetPropertyStr(context, global, "httpd", httpd);
|
||||
JS_FreeValue(context, global);
|
||||
}
|
||||
|
Reference in New Issue
Block a user