diff --git a/web/app/controllers/subdomain/api/remote_judge/custom_account_validator.php b/web/app/controllers/subdomain/api/remote_judge/custom_account_validator.php new file mode 100644 index 0000000..f655b20 --- /dev/null +++ b/web/app/controllers/subdomain/api/remote_judge/custom_account_validator.php @@ -0,0 +1,86 @@ +setUserAgent(UOJRemoteProblem::USER_AGENT); +$res = false; + +function validateLuogu($response) { + $response = json_decode(json_encode($response), true); + + return $response['currentTemplate'] !== 'AuthLogin'; +} + +if ($type == 'luogu') { + $curl->setFollowLocation(); + $curl->setCookie('_uid', UOJRequest::post('_uid', 'is_string', '')); + $curl->setCookie('__client_id', UOJRequest::post('__client_id', 'is_string', '')); + + retry_loop(function () use (&$curl, &$res) { + $curl->get(UOJRemoteProblem::$providers['luogu']['url'] . '/user/setting?_contentOnly=1'); + + if ($curl->error) { + return false; + } + + if ($curl->responseHeaders['Content-Type'] == 'text/html') { + $sec = $curl->getResponseCookie('sec'); + + if ($sec) { + $curl->setCookie('sec', $sec); + $curl->get(UOJRemoteProblem::$providers['luogu']['url'] . '/user/setting?_contentOnly=1'); + + if ($curl->responseHeaders['Content-Type'] == 'application/json') { + $res = validateLuogu($curl->response); + + return true; + } + + return false; + } + + return false; + } else if ($curl->responseHeaders['Content-Type'] == 'application/json') { + $res = validateLuogu($curl->response); + + return true; + } + + return false; + }, 3); + + die(json_encode(['ok' => $res === true])); +} else if ($type == 'codeforces') { + $curl->setFollowLocation(); + $curl->setCookie('JSESSIONID', UOJRequest::post('JSESSIONID', 'is_string', '')); + + retry_loop(function () use (&$curl, &$res) { + $curl->get(UOJRemoteProblem::$providers['codeforces']['url'] . '/enter'); + + if ($curl->error) { + return false; + } + + if (str_starts_with($curl->responseHeaders['Content-Type'], 'text/html')) { + if (str_contains($curl->response, 'Login into Codeforces')) { + return false; + } + + if (strlen($curl->response) < 1000 && str_contains($curl->response, 'Redirecting...')) { + return false; + } + + $res = true; + + return true; + } + + return false; + }, 3); +} else { + UOJResponse::page406(); +} + +die(json_encode(['ok' => $res === true])); diff --git a/web/app/controllers/subdomain/api/route.php b/web/app/controllers/subdomain/api/route.php new file mode 100644 index 0000000..ae169a7 --- /dev/null +++ b/web/app/controllers/subdomain/api/route.php @@ -0,0 +1,12 @@ + UOJConfig::$data['web']['main']['host'], + ], + function () { + Route::post("/api/remote_judge/custom_account_validator", '/subdomain/api/remote_judge/custom_account_validator.php'); + } + ); +}); diff --git a/web/index.php b/web/index.php index 6e29eca..0953945 100644 --- a/web/index.php +++ b/web/index.php @@ -5,6 +5,7 @@ require $_SERVER['DOCUMENT_ROOT'] . '/app/libs/uoj-lib.php'; require UOJContext::documentRoot().'/app/route.php'; require UOJContext::documentRoot().'/app/controllers/subdomain/blog/route.php'; +require UOJContext::documentRoot().'/app/controllers/subdomain/api/route.php'; include UOJContext::documentRoot().'/app/controllers'.call_user_func(function() { $route = Route::dispatch(); diff --git a/web/js/uoj.js b/web/js/uoj.js index 43ba550..cec7c0e 100644 --- a/web/js/uoj.js +++ b/web/js/uoj.js @@ -958,11 +958,48 @@ $.fn.remote_submit_type_group = function(oj, pid, url, submit_type) { var input_submit_type_bot = $(''); var input_submit_type_my = $(''); var input_my_account_data = $(''); + + var my_account_validation_status = $('').append('待验证'); + var my_account_validation_btn = $(''); + + var validate_my_account = function(data) { + my_account_validation_btn.html(''); + my_account_validation_btn.addClass('disabled'); + + $.ajax({ + type: 'POST', + url: '/api/remote_judge/custom_account_validator?type=' + oj, + data: data, + success: function(res) { + my_account_validation_btn.html('验证'); + my_account_validation_btn.removeClass('disabled'); + + console.log('Validation status', res); + + if (res.ok) { + my_account_validation_status.html('可用'); + } else { + my_account_validation_status.html('不可用'); + } + }, + error: function() { + my_account_validation_btn.html('验证'); + my_account_validation_btn.removeClass('disabled'); + my_account_validation_status.html('待验证'); + }, + dataType: 'json', + }); + }; var div_submit_type_bot = $('
') .append('_uid
。')))
+ .append($('').append($('').append('请填入 Cookie 中的 _uid
。')))
).append(
$('')
.append($('').append(''))
.append($('').append(input_luogu_client_id))
- .append($('').append($('').append('请填入 Cookie 中的 __client_id
。')))
+ .append($('').append($('').append('请填入 Cookie 中的 __client_id
。')))
).append(input_my_account_data);
} else if (oj == 'codeforces') {
var codeforces_account_data = {"JSESSIONID": ""};
@@ -1079,16 +1134,31 @@ $.fn.remote_submit_type_group = function(oj, pid, url, submit_type) {
codeforces_account_data.JSESSIONID = $(this).val();
input_my_account_data.val(JSON.stringify(codeforces_account_data));
save_codeforces_account_data();
+ my_account_validation_status.html('待验证');
+ });
+
+ my_account_validation_btn.click(function() {
+ validate_my_account({
+ type: 'codeforces',
+ JSESSIONID: input_codeforces_jsessionid.val(),
+ });
});
input_my_account_data.val(JSON.stringify(codeforces_account_data));
input_codeforces_jsessionid.val(codeforces_account_data.JSESSIONID);
+ if (codeforces_account_data.JSESSIONID) {
+ validate_my_account({
+ type: 'codeforces',
+ JSESSIONID: codeforces_account_data.JSESSIONID,
+ });
+ }
+
div_submit_type_my.append(
$('')
.append($('').append(''))
.append($('').append(input_codeforces_jsessionid))
- .append($('').append($('').append('请填入 Cookie 中的 JSESSIONID
。')))
+ .append($('').append($('').append('请填入 Cookie 中的 JSESSIONID
。')))
).append(input_my_account_data);
}