core: remove recaptcha legacy code. resolves #8268 (#10111)

This commit is contained in:
Diego Heras 2020-11-05 03:19:09 +01:00 committed by GitHub
parent 938315cebd
commit ed9d0a8328
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 59 additions and 474 deletions

View File

@ -24,8 +24,6 @@ $.fn.focusWithoutScrolling = function () {
$(document).ready(function () {
$.ajaxSetup({ cache: false });
//window.jackettIsLocal = window.location.hostname === '127.0.0.1';
window.jackettIsLocal = false; // reCaptcha can't be solved via 127.0.0.1 anymore. This loophold was fixed by google around 2.10.2017
Handlebars.registerHelper('if_eq', function(a, b, opts) {
if (a == b)
@ -511,79 +509,13 @@ function populateConfigItems(configForm, config) {
var $formItemContainer = configForm.find(".config-setup-form");
$formItemContainer.empty();
$('.jackettrecaptcha').remove();
var hasReacaptcha = false;
var captchaItem = null;
for (var i = 0; i < config.length; i++) {
if (config[i].type === 'recaptcha') {
hasReacaptcha = true;
captchaItem = config[i];
}
else if (config[i].id === 'cookieheader' && hasReacaptcha) { // inject cookie into captcha item
captchaItem.cookieheader = config[i].value;
console.log(captchaItem);
}
}
var setupItemTemplate = Handlebars.compile($("#setup-item").html());
if (hasReacaptcha && !window.jackettIsLocal && false) { // disable this for now, use inline cookie (below)
var setupValueTemplate = Handlebars.compile($("#setup-item-nonlocalrecaptcha").html());
captchaItem.value_element = setupValueTemplate(captchaItem);
var template = setupItemTemplate(captchaItem);
for (var i = 0; i < config.length; i++) {
var item = config[i];
var setupValueTemplate = Handlebars.compile($("#setup-item-" + item.type).html());
item.value_element = setupValueTemplate(item);
var template = setupItemTemplate(item);
$formItemContainer.append(template);
} else {
for (var i = 0; i < config.length; i++) {
var item = config[i];
if ((item.id === 'username' || item.id === 'password') && hasReacaptcha) {
continue; // skip username/password if there's a recaptcha
}
if (item.type != 'recaptcha') {
var setupValueTemplate = Handlebars.compile($("#setup-item-" + item.type).html());
item.value_element = setupValueTemplate(item);
var template = setupItemTemplate(item);
$formItemContainer.append(template);
}
if (item.type === 'recaptcha') {
// inject cookie dialog until recaptcha can be solved again
var setupValueTemplate = Handlebars.compile($("#setup-item-nonlocalrecaptcha").html());
captchaItem.value_element = setupValueTemplate(captchaItem);
var template = setupItemTemplate(captchaItem);
$formItemContainer.append(template);
/*
var jackettrecaptcha = $('.jackettrecaptcha');
jackettrecaptcha.data("version", item.version);
switch (item.version) {
case "1":
// The v1 reCAPTCHA code uses document.write() calls to write the CAPTCHA to the location where the script was loaded.
// As it's loaded async this doesn't work.
// We use an iframe to work around this problem.
var html = '<script type="text/javascript" src="https://www.google.com/recaptcha/api/challenge?k='+encodeURIComponent(item.sitekey)+'"></script>';
var frame = document.createElement('iframe');
frame.id = "jackettrecaptchaiframe";
frame.style.height = "145px";
frame.style.weight = "326px";
frame.style.border = "none";
frame.onload = function () {
// auto resize iframe to content
frame.style.height = frame.contentWindow.document.body.scrollHeight + 'px';
frame.style.width = frame.contentWindow.document.body.scrollWidth + 'px';
}
jackettrecaptcha.append(frame);
frame.contentDocument.open();
frame.contentDocument.write(html);
frame.contentDocument.close();
break;
case "2":
grecaptcha.render(jackettrecaptcha[0], {
'sitekey': item.sitekey
});
break;
}
*/
}
}
}
}
@ -631,24 +563,6 @@ function getConfigModalJson(configForm) {
case "inputselect":
itemEntry.value = $el.find(".setup-item-inputselect select").val();
break;
case "recaptcha":
if (window.jackettIsLocal) {
var version = $el.find('.jackettrecaptcha').data("version");
switch (version) {
case "1":
var frameDoc = $("#jackettrecaptchaiframe")[0].contentDocument;
itemEntry.version = version;
itemEntry.challenge = $("#recaptcha_challenge_field", frameDoc).val()
itemEntry.value = $("#recaptcha_response_field", frameDoc).val()
break;
case "2":
itemEntry.value = $('.g-recaptcha-response').val();
break;
}
} else {
itemEntry.cookie = $el.find(".setup-item-recaptcha input").val();
}
break;
}
configJson.push(itemEntry)
});

View File

@ -30,7 +30,6 @@
<script type="text/javascript" src="../bootstrap/bootstrap.min.js?changed=2017083001"></script>
<script type="text/javascript" src="../libs/bootstrap-notify.js?changed=2017083001"></script>
<script type="text/javascript" src="../libs/bootstrap-multiselect.js?changed=2017083001"></script>
<!--<script type="text/javascript" src="https://www.google.com/recaptcha/api.js?render=explicit" async defer></script>-->
<link rel="stylesheet" type="text/css" href="../bootstrap/bootstrap.min.css?changed=2017083001">
<link rel="stylesheet" type="text/css" href="../animate.css?changed=2017083001">
@ -205,13 +204,6 @@
<div id="modals"></div>
<script id="setup-item-nonlocalrecaptcha" type="text/x-handlebars-template">
<div class="setup-item-recaptcha">
<p>This site requires you to solve a ReCaptcha. It's no longer possible to solve the captcha in Jackett. Please enter the cookie for the site manually. <a href="https://github.com/Jackett/Jackett/wiki/Finding-cookies" target="_blank">See here</a> on how get the cookies.</p>
<div class="setup-item-label">Full cookie header</div>
<input class="form-control" type="text" value="{{cookieheader}}" />
</div>
</script>
<script id="setup-item" type="text/x-handlebars-template">
<div class="setup-item form-group" data-id="{{id}}" data-value="{{value}}" data-type="{{type}}">
<div class="setup-item-label">{{name}}</div>
@ -262,10 +254,6 @@
</select>
</div>
</script>
<script id="setup-item-recaptcha" type="text/x-handlebars-template">
<div class="jackettrecaptcha">
</div>
</script>
<script id="setup-item-displayimage" type="text/x-handlebars-template">
<img class="setup-item-displayimage" src="{{{value}}}" alt="No image available" />
</script>
@ -692,6 +680,6 @@
</script>
<script type="text/javascript" src="../libs/api.js?changed=2017083001"></script>
<script type="text/javascript" src="../custom.js?changed=20200926"></script>
<script type="text/javascript" src="../custom.js?changed=20201104"></script>
</body>
</html>

View File

@ -524,11 +524,6 @@ namespace Jackett.Common.Indexers
{
throw new Exception("Request to " + response.Request.Url + " failed (Error " + response.Status + ") - The tracker seems to be down.");
}
if (response.Status == System.Net.HttpStatusCode.Forbidden && response.ContentString.Contains("<span data-translate=\"complete_sec_check\">Please complete the security check to access</span>"))
{
throw new Exception("Request to " + response.Request.Url + " failed (Error " + response.Status + ") - The page is protected by an Cloudflare reCaptcha. The page is in aggressive DDoS mitigation mode or your IP might be blacklisted (e.g. in case of shared VPN IPs). There's no easy way of making it usable with Jackett.");
}
}
protected async Task FollowIfRedirect(WebResult response, string referrer = null, string overrideRedirectUrl = null, string overrideCookies = null, bool accumulateCookies = false)

View File

@ -21,11 +21,9 @@ namespace Jackett.Common.Indexers
[ExcludeFromCodeCoverage]
public class BitHDTV : BaseWebIndexer
{
private string LoginUrl => SiteLink + "login.php";
private string TakeLoginUrl => SiteLink + "takelogin.php";
private string SearchUrl => SiteLink + "torrents.php";
private new ConfigurationDataRecaptchaLogin configData => (ConfigurationDataRecaptchaLogin)base.configData;
private new ConfigurationDataCookie configData => (ConfigurationDataCookie)base.configData;
public BitHDTV(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps)
: base(id: "bithdtv",
@ -47,7 +45,7 @@ namespace Jackett.Common.Indexers
client: w,
logger: l,
p: ps,
configData: new ConfigurationDataRecaptchaLogin("For best results, change the 'Torrents per page' setting to 100 in your profile."))
configData: new ConfigurationDataCookie("For best results, change the 'Torrents per page' setting to 100 in your profile."))
{
Encoding = Encoding.GetEncoding("iso-8859-1");
Language = "en-us";
@ -66,59 +64,26 @@ namespace Jackett.Common.Indexers
AddCategoryMapping(11, TorznabCatType.XXX); // XXX
}
public override async Task<ConfigurationData> GetConfigurationForSetup()
{
var result = configData;
var loginPage = await RequestWithCookiesAsync(LoginUrl, configData.CookieHeader.Value);
if (loginPage.IsRedirect)
return result; // already logged in
var parser = new HtmlParser();
var cq = parser.ParseDocument(loginPage.ContentString);
var recaptchaSiteKey = cq.QuerySelector(".g-recaptcha")?.GetAttribute("data-sitekey");
result.CookieHeader.Value = loginPage.Cookies;
result.Captcha.SiteKey = recaptchaSiteKey;
result.Captcha.Version = "2";
return result;
}
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
LoadValuesFromJson(configJson);
var pairs = new Dictionary<string, string>
{
{"username", configData.Username.Value},
{"password", configData.Password.Value},
{"g-recaptcha-response", configData.Captcha.Value}
};
if (!string.IsNullOrWhiteSpace(configData.Captcha.Cookie))
{
// Cookie was manually supplied
CookieHeader = configData.Captcha.Cookie;
try
{
var results = await PerformQuery(new TorznabQuery());
if (!results.Any())
throw new Exception("Found 0 results in the tracker");
IsConfigured = true;
SaveConfig();
return IndexerConfigurationStatus.Completed;
}
catch (Exception e)
{
IsConfigured = false;
throw new Exception("Your cookie did not work: " + e.Message);
}
}
var response = await RequestLoginAndFollowRedirect(TakeLoginUrl, pairs, null, true, referer: SiteLink);
await ConfigureIfOK(response.Cookies, response.ContentString?.Contains("logout.php") == true, () =>
CookieHeader = configData.Cookie.Value;
try
{
var parser = new HtmlParser();
var dom = parser.ParseDocument(response.ContentString);
var errorMessage = dom.QuerySelector("table.detail td.text").FirstChild.TextContent.Trim();
throw new ExceptionWithConfigData(errorMessage, configData);
});
return IndexerConfigurationStatus.RequiresTesting;
var results = await PerformQuery(new TorznabQuery());
if (!results.Any())
throw new Exception("Found 0 results in the tracker");
IsConfigured = true;
SaveConfig();
return IndexerConfigurationStatus.Completed;
}
catch (Exception e)
{
IsConfigured = false;
throw new Exception("Your cookie did not work: " + e.Message);
}
}
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)

View File

@ -502,47 +502,6 @@ namespace Jackett.Common.Indexers
var queryCollection = new NameValueCollection();
var pairs = new Dictionary<string, string>();
var CaptchaConfigItem = (RecaptchaItem)configData.GetDynamic("Captcha");
if (CaptchaConfigItem != null)
{
if (!string.IsNullOrWhiteSpace(CaptchaConfigItem.Cookie))
{
// for remote users just set the cookie and return
CookieHeader = CaptchaConfigItem.Cookie;
return true;
}
var CloudFlareCaptchaChallenge = landingResultDocument.QuerySelector("script[src=\"/cdn-cgi/scripts/cf.challenge.js\"]");
if (CloudFlareCaptchaChallenge != null)
{
var CloudFlareQueryCollection = new NameValueCollection
{
["id"] = CloudFlareCaptchaChallenge.GetAttribute("data-ray"),
["g-recaptcha-response"] = CaptchaConfigItem.Value
};
var ClearanceUrl = resolvePath("/cdn-cgi/l/chk_captcha?" + CloudFlareQueryCollection.GetQueryString());
var ClearanceResult = await RequestWithCookiesAsync(ClearanceUrl.ToString(), referer: SiteLink);
if (ClearanceResult.IsRedirect) // clearance successfull
{
// request real login page again
landingResult = await RequestWithCookiesAsync(LoginUrl, referer: SiteLink);
var htmlParser = new HtmlParser();
landingResultDocument = htmlParser.ParseDocument(landingResult.ContentString);
}
else
{
throw new ExceptionWithConfigData(string.Format("Login failed: Cloudflare clearance failed using cookies {0}: {1}", CookieHeader, ClearanceResult.ContentString), configData);
}
}
else
{
pairs.Add("g-recaptcha-response", CaptchaConfigItem.Value);
}
}
var FormSelector = Login.Form;
if (FormSelector == null)
FormSelector = "form";
@ -886,36 +845,10 @@ namespace Jackett.Common.Indexers
await FollowIfRedirect(landingResult, LoginUrl.AbsoluteUri, overrideCookies: landingResult.Cookies, accumulateCookies: true);
}
var hasCaptcha = false;
var htmlParser = new HtmlParser();
landingResultDocument = htmlParser.ParseDocument(landingResult.ContentString);
var hasCaptcha = false;
var cloudFlareCaptchaScript = landingResultDocument.QuerySelector("script[src*=\"/recaptcha/api.js\"]");
var cloudFlareCaptchaGroup = landingResultDocument.QuerySelector("#recaptca_group");
var cloudFlareCaptchaDisplay = true;
if (cloudFlareCaptchaGroup != null)
{
var cloudFlareCaptchaGroupStyle = cloudFlareCaptchaGroup.GetAttribute("style");
if (cloudFlareCaptchaGroupStyle != null)
cloudFlareCaptchaDisplay = !cloudFlareCaptchaGroupStyle.Contains("display:none;");
}
var grecaptcha = landingResultDocument.QuerySelector(".g-recaptcha");
if (cloudFlareCaptchaScript != null && grecaptcha != null && cloudFlareCaptchaDisplay)
{
hasCaptcha = true;
var CaptchaItem = new RecaptchaItem
{
Name = "Captcha",
Version = "2",
// some sites don't store the sitekey in the .g-recaptcha div (e.g. cloudflare captcha challenge page)
SiteKey = grecaptcha.GetAttribute("data-sitekey") ??
landingResultDocument.QuerySelector("[data-sitekey]").GetAttribute("data-sitekey")
};
configData.AddDynamic("Captcha", CaptchaItem);
}
if (Login.Captcha != null)
{
var Captcha = Login.Captcha;

View File

@ -5,7 +5,6 @@ using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using AngleSharp.Html.Parser;
using Jackett.Common.Helpers;
@ -28,13 +27,8 @@ namespace Jackett.Common.Indexers
};
private string SearchUrl => SiteLink + "browse.php";
private string LoginUrl => SiteLink + "login.php";
private new ConfigurationDataRecaptchaLogin configData
{
get => (ConfigurationDataRecaptchaLogin)base.configData;
set => base.configData = value;
}
private new ConfigurationDataCookie configData => (ConfigurationDataCookie)base.configData;
public Fuzer(IIndexerConfigurationService configService, WebClient w, Logger l, IProtectionService ps)
: base(id: "fuzer",
@ -64,7 +58,7 @@ namespace Jackett.Common.Indexers
client: w,
logger: l,
p: ps,
configData: new ConfigurationDataRecaptchaLogin())
configData: new ConfigurationDataCookie())
{
Encoding = Encoding.GetEncoding("windows-1255");
Language = "he-il";
@ -121,70 +115,26 @@ namespace Jackett.Common.Indexers
AddCategoryMapping(76, TorznabCatType.TV, "סדרות");
}
public override async Task<ConfigurationData> GetConfigurationForSetup()
{
var loginPage = await RequestWithCookiesAsync(LoginUrl, string.Empty);
var parser = new HtmlParser();
var cq = parser.ParseDocument(loginPage.ContentString);
var captcha = cq.QuerySelector(".g-recaptcha"); // invisible recaptcha
if (captcha != null)
{
var result = configData;
result.CookieHeader.Value = loginPage.Cookies;
result.Captcha.SiteKey = captcha.GetAttribute("data-sitekey");
result.Captcha.Version = "2";
return result;
}
else
{
var result = new ConfigurationDataBasicLogin();
result.SiteLink.Value = configData.SiteLink.Value;
result.Instructions.Value = configData.Instructions.Value;
result.Username.Value = configData.Username.Value;
result.Password.Value = configData.Password.Value;
result.CookieHeader.Value = loginPage.Cookies;
return result;
}
}
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
LoadValuesFromJson(configJson);
if (!string.IsNullOrWhiteSpace(configData.Captcha.Cookie))
{
CookieHeader = configData.Captcha.Cookie;
try
{
var results = await PerformQuery(new TorznabQuery());
if (!results.Any())
throw new Exception("Found 0 results in the tracker");
IsConfigured = true;
SaveConfig();
return IndexerConfigurationStatus.Completed;
}
catch (Exception e)
{
IsConfigured = false;
throw new Exception("Your cookie did not work: " + e.Message);
}
}
var loginPage = await RequestWithCookiesAsync(LoginUrl, string.Empty);
var pairs = new Dictionary<string, string>
CookieHeader = configData.Cookie.Value;
try
{
{"vb_login_username", configData.Username.Value},
{"vb_login_password", ""},
{"securitytoken", "guest"},
{"do", "login"},
{"vb_login_md5password", StringUtil.Hash(configData.Password.Value).ToLower()},
{"vb_login_md5password_utf", StringUtil.Hash(configData.Password.Value).ToLower()},
{"cookieuser", "1"}
};
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, null, LoginUrl);
await ConfigureIfOK(result.Cookies, result.ContentString?.Contains("images/loading.gif") == true,
() => throw new ExceptionWithConfigData("Couldn't login", configData));
Thread.Sleep(2);
return IndexerConfigurationStatus.RequiresTesting;
var results = await PerformQuery(new TorznabQuery());
if (!results.Any())
throw new Exception("Found 0 results in the tracker");
IsConfigured = true;
SaveConfig();
return IndexerConfigurationStatus.Completed;
}
catch (Exception e)
{
IsConfigured = false;
throw new Exception("Your cookie did not work: " + e.Message);
}
}
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)

View File

@ -8,7 +8,6 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks;
using AngleSharp.Html.Parser;
using Jackett.Common.Models;
using Jackett.Common.Models.IndexerConfig;
using Jackett.Common.Models.IndexerConfig.Bespoke;
using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils;
@ -21,8 +20,6 @@ namespace Jackett.Common.Indexers
[ExcludeFromCodeCoverage]
public class SceneTime : BaseWebIndexer
{
private string StartPageUrl => SiteLink + "login.php";
private string LoginUrl => SiteLink + "takelogin1.php";
private string SearchUrl => SiteLink + "browse.php";
private string DownloadUrl => SiteLink + "download.php/{0}/download.torrent";
@ -88,80 +85,26 @@ namespace Jackett.Common.Indexers
AddCategoryMapping(116, TorznabCatType.Audio, "Music Pack");
}
public override async Task<ConfigurationData> GetConfigurationForSetup()
{
WebResult loginPage;
try
{
loginPage = await RequestWithCookiesAsync(StartPageUrl, string.Empty);
}
catch (Exception)
{
// The login page is protected by Cloudflare
return configData;
}
var parser = new HtmlParser();
var dom = parser.ParseDocument(loginPage.ContentString);
var recaptcha = dom.QuerySelector(".g-recaptcha");
if (recaptcha != null)
{
var result = configData;
result.Captcha.Version = "2";
result.CookieHeader.Value = loginPage.Cookies;
result.Captcha.SiteKey = recaptcha.GetAttribute("data-sitekey");
return result;
}
var stdResult = new ConfigurationDataBasicLogin
{
SiteLink = { Value = configData.SiteLink.Value },
Username = { Value = configData.Username.Value },
Password = { Value = configData.Password.Value },
CookieHeader = { Value = loginPage.Cookies }
};
return stdResult;
}
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
LoadValuesFromJson(configJson);
var pairs = new Dictionary<string, string> {
{ "username", configData.Username.Value },
{ "password", configData.Password.Value },
{ "g-recaptcha-response", configData.Captcha.Value }
};
if (!string.IsNullOrWhiteSpace(configData.Captcha.Cookie))
CookieHeader = configData.Cookie.Value;
try
{
CookieHeader = configData.Captcha.Cookie;
try
{
var results = await PerformQuery(new TorznabQuery());
if (!results.Any())
throw new Exception("Found 0 results in the tracker");
var results = await PerformQuery(new TorznabQuery());
if (!results.Any())
throw new Exception("Found 0 results in the tracker");
IsConfigured = true;
SaveConfig();
return IndexerConfigurationStatus.Completed;
}
catch (Exception e)
{
IsConfigured = false;
throw new Exception("Your cookie did not work: " + e.Message);
}
IsConfigured = true;
SaveConfig();
return IndexerConfigurationStatus.Completed;
}
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl);
await ConfigureIfOK(result.Cookies, result.ContentString != null && result.ContentString.Contains("logout.php"), () =>
catch (Exception e)
{
var parser = new HtmlParser();
var dom = parser.ParseDocument(result.ContentString);
var errorMessage = dom.QuerySelector("td.text").TextContent.Trim();
throw new ExceptionWithConfigData(errorMessage, configData);
});
return IndexerConfigurationStatus.RequiresTesting;
IsConfigured = false;
throw new Exception("Your cookie did not work: " + e.Message);
}
}
protected override async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)

View File

@ -2,7 +2,6 @@ using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
@ -23,7 +22,7 @@ namespace Jackett.Common.Indexers
{
private string LoginUrl => SiteLink + "user/account/login/";
private string SearchUrl => SiteLink + "torrents/browse/list/";
private new ConfigurationDataRecaptchaLogin configData => (ConfigurationDataRecaptchaLogin)base.configData;
private new ConfigurationDataBasicLogin configData => (ConfigurationDataBasicLogin)base.configData;
public override string[] LegacySiteLinks { get; protected set; } =
{
@ -58,7 +57,7 @@ namespace Jackett.Common.Indexers
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataRecaptchaLogin(
configData: new ConfigurationDataBasicLogin(
"For best results, change the 'Default Number of Torrents per Page' setting to 100 in your Profile."))
{
Encoding = Encoding.UTF8;
@ -119,58 +118,9 @@ namespace Jackett.Common.Indexers
AddCategoryMapping(38, TorznabCatType.Other, "Education");
}
public override async Task<ConfigurationData> GetConfigurationForSetup()
{
var loginPage = await RequestWithCookiesAsync(LoginUrl, string.Empty);
var parser = new HtmlParser();
var dom = parser.ParseDocument(loginPage.ContentString);
var captcha = dom.QuerySelector(".g-recaptcha");
if (captcha != null)
{
var result = configData;
result.CookieHeader.Value = loginPage.Cookies;
result.Captcha.SiteKey = captcha.GetAttribute("data-sitekey");
result.Captcha.Version = "2";
return result;
}
else
{
var result = new ConfigurationDataBasicLogin
{
SiteLink = { Value = configData.SiteLink.Value },
Instructions = { Value = configData.Instructions.Value },
Username = { Value = configData.Username.Value },
Password = { Value = configData.Password.Value },
CookieHeader = { Value = loginPage.Cookies }
};
return result;
}
}
public override async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
{
LoadValuesFromJson(configJson);
if (!string.IsNullOrWhiteSpace(configData.Captcha.Cookie))
{
CookieHeader = configData.Captcha.Cookie;
try
{
var results = await PerformQuery(new TorznabQuery());
if (!results.Any())
throw new Exception("Found 0 results in the tracker");
IsConfigured = true;
SaveConfig();
return IndexerConfigurationStatus.Completed;
}
catch (Exception e)
{
IsConfigured = false;
throw new Exception("Your cookie did not work: " + e.Message);
}
}
await DoLogin();
return IndexerConfigurationStatus.RequiresTesting;
}

View File

@ -6,7 +6,5 @@ namespace Jackett.Common.Models.DTO
public string value { get; set; }
public string[] values { get; set; } // for array data (e.g. checkboxes)
public string cookie { get; set; } // for cookie alternative login (captcha needed + remote host)
public string challenge { get; set; } // for reCaptcha V1 compatibility
public string version { get; set; } // for reCaptcha V1 compatibility
}
}

View File

@ -3,22 +3,14 @@ using System.Diagnostics.CodeAnalysis;
namespace Jackett.Common.Models.IndexerConfig.Bespoke
{
[ExcludeFromCodeCoverage]
internal class ConfigurationDataSceneTime : ConfigurationData
internal class ConfigurationDataSceneTime : ConfigurationDataCookie
{
public StringItem Username { get; private set; }
public StringItem Password { get; private set; }
public RecaptchaItem Captcha { get; private set; }
public BoolItem Freeleech { get; private set; }
public DisplayItem Instructions { get; private set; }
public ConfigurationDataSceneTime()
: base()
: base("For best results, change the 'Torrents per page' setting to the maximum in your profile on the SceneTime webpage.")
{
Username = new StringItem { Name = "Username" };
Password = new StringItem { Name = "Password" };
Captcha = new RecaptchaItem() { Name = "Recaptcha" };
Freeleech = new BoolItem() { Name = "Freeleech Only (Optional)", Value = false };
Instructions = new DisplayItem("For best results, change the 'Torrents per page' setting to the maximum in your profile on the SceneTime webpage.") { Name = "" };
}
}
}

View File

@ -20,8 +20,7 @@ namespace Jackett.Common.Models.IndexerConfig
InputSelect,
DisplayImage,
DisplayInfo,
HiddenData,
Recaptcha
HiddenData
}
public HiddenItem CookieHeader { get; private set; } = new HiddenItem { Name = "CookieHeader" };
@ -89,12 +88,6 @@ namespace Jackett.Common.Models.IndexerConfig
case ItemType.InputSelect:
((SelectItem)item).Value = arrItem.Value<string>("value");
break;
case ItemType.Recaptcha:
((RecaptchaItem)item).Value = arrItem.Value<string>("value");
((RecaptchaItem)item).Cookie = arrItem.Value<string>("cookie");
((RecaptchaItem)item).Version = arrItem.Value<string>("version");
((RecaptchaItem)item).Challenge = arrItem.Value<string>("challenge");
break;
}
}
}
@ -113,10 +106,6 @@ namespace Jackett.Common.Models.IndexerConfig
};
switch (item.ItemType)
{
case ItemType.Recaptcha:
jObject["sitekey"] = ((RecaptchaItem)item).SiteKey;
jObject["version"] = ((RecaptchaItem)item).Version;
break;
case ItemType.InputString:
case ItemType.HiddenData:
case ItemType.DisplayInfo:
@ -181,7 +170,7 @@ namespace Jackett.Common.Models.IndexerConfig
if (!forDisplay)
{
properties = properties
.Where(p => p.ItemType == ItemType.HiddenData || p.ItemType == ItemType.InputBool || p.ItemType == ItemType.InputString || p.ItemType == ItemType.InputCheckbox || p.ItemType == ItemType.InputSelect || p.ItemType == ItemType.Recaptcha || p.ItemType == ItemType.DisplayInfo)
.Where(p => p.ItemType == ItemType.HiddenData || p.ItemType == ItemType.InputBool || p.ItemType == ItemType.InputString || p.ItemType == ItemType.InputCheckbox || p.ItemType == ItemType.InputSelect || p.ItemType == ItemType.DisplayInfo)
.ToList();
}
@ -239,17 +228,6 @@ namespace Jackett.Common.Models.IndexerConfig
public StringItem() => ItemType = ItemType.InputString;
}
public class RecaptchaItem : StringItem
{
public string Version { get; set; }
public string Challenge { get; set; }
public RecaptchaItem()
{
Version = "2";
ItemType = ItemType.Recaptcha;
}
}
public class BoolItem : Item
{
public bool Value { get; set; }

View File

@ -1,20 +0,0 @@
namespace Jackett.Common.Models.IndexerConfig
{
public class ConfigurationDataRecaptchaLogin : ConfigurationData
{
public StringItem Username { get; private set; }
public StringItem Password { get; private set; }
public RecaptchaItem Captcha { get; private set; }
public DisplayItem Instructions { get; private set; }
public ConfigurationDataRecaptchaLogin(string instructionMessageOptional = null)
{
Username = new StringItem { Name = "Username" };
Password = new StringItem { Name = "Password" };
Captcha = new RecaptchaItem() { Name = "Recaptcha" };
Instructions = new DisplayItem(instructionMessageOptional) { Name = "" };
}
}
}

View File

@ -76,7 +76,6 @@ namespace Jackett.Common.Models
{
public string Type { get; set; }
public string Selector { get; set; }
public string Image { get => throw new Exception("Deprecated, please use Login.Captcha.Selector instead"); set => throw new Exception("Deprecated, please use login/captcha/selector instead of image"); }
public string Input { get; set; }
}