mirror of
https://github.com/Jackett/Jackett
synced 2025-02-24 15:21:06 +00:00
Implement recaptcha for torrentday (This will only work for localhost)
This commit is contained in:
parent
6ea759aeab
commit
d1ff05ac13
7 changed files with 172 additions and 100 deletions
|
@ -197,8 +197,8 @@ function reloadIndexers() {
|
|||
}
|
||||
|
||||
function displayIndexers(items) {
|
||||
var indexerTemplate = Handlebars.compile($("#templates > .configured-indexer")[0].outerHTML);
|
||||
var unconfiguredIndexerTemplate = Handlebars.compile($("#templates > .unconfigured-indexer")[0].outerHTML);
|
||||
var indexerTemplate = Handlebars.compile($("#configured-indexer").html());
|
||||
var unconfiguredIndexerTemplate = Handlebars.compile($("#unconfigured-indexer").html());
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
item.torznab_host = resolveUrl("/torznab/" + item.id);
|
||||
|
@ -209,7 +209,7 @@ function displayIndexers(items) {
|
|||
$('#unconfigured-indexers').append($(unconfiguredIndexerTemplate(item)));
|
||||
}
|
||||
|
||||
var addIndexerButton = $("#templates > .add-indexer")[0].outerHTML;
|
||||
var addIndexerButton = $('#add-indexer').html();
|
||||
$('#indexers').append(addIndexerButton);
|
||||
|
||||
$('#indexers').fadeIn();
|
||||
|
@ -293,12 +293,22 @@ function populateConfigItems(configForm, config) {
|
|||
}
|
||||
var $formItemContainer = configForm.find(".config-setup-form");
|
||||
$formItemContainer.empty();
|
||||
var setupItemTemplate = Handlebars.compile($("#templates > .setup-item")[0].outerHTML);
|
||||
var setupItemTemplate = Handlebars.compile($("#setup-item").html());
|
||||
for (var i = 0; i < config.length; i++) {
|
||||
var item = config[i];
|
||||
var setupValueTemplate = Handlebars.compile($("#templates > .setup-item-" + item.type)[0].outerHTML);
|
||||
var setupValueTemplate = Handlebars.compile($("#setup-item-" + item.type).html());
|
||||
|
||||
|
||||
item.value_element = setupValueTemplate(item);
|
||||
$formItemContainer.append(setupItemTemplate(item));
|
||||
var template = setupItemTemplate(item);
|
||||
|
||||
$formItemContainer.append(template);
|
||||
|
||||
if (item.type === 'recaptcha') {
|
||||
grecaptcha.render($('.jackettrecaptcha')[0], {
|
||||
'sitekey': item.sitekey
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,6 +337,9 @@ function getConfigModalJson(configForm) {
|
|||
case "inputbool":
|
||||
itemEntry.value = $el.find(".setup-item-inputbool input").is(":checked");
|
||||
break;
|
||||
case "recaptcha":
|
||||
itemEntry.value = $('.g-recaptcha-response').val();
|
||||
break;
|
||||
}
|
||||
configJson.push(itemEntry)
|
||||
});
|
||||
|
@ -342,7 +355,7 @@ function populateSetupForm(indexerId, name, config, caps) {
|
|||
|
||||
var originalBtnText = $goButton.html();
|
||||
$goButton.prop('disabled', true);
|
||||
$goButton.html($('#templates > .spinner')[0].outerHTML);
|
||||
$goButton.html($('#spinner').html());
|
||||
|
||||
var jqxhr = $.post("/admin/configure_indexer", JSON.stringify(data), function (data) {
|
||||
if (data.result == "error") {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
<script src="/libs/handlebarsmoment.js"></script>
|
||||
<script src="/bootstrap/bootstrap.min.js"></script>
|
||||
<script src="/libs/bootstrap-notify.js"></script>
|
||||
<script src='https://www.google.com/recaptcha/api.js'></script>
|
||||
|
||||
<link href="/bootstrap/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="/animate.css" rel="stylesheet">
|
||||
|
@ -20,6 +21,85 @@
|
|||
<link href="/css/jquery.dataTables.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/css/font-awesome.min.css">
|
||||
|
||||
<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>
|
||||
<div class="setup-item-value">{{{value_element}}}</div>
|
||||
</div>
|
||||
</script>
|
||||
<script id="setup-item-inputstring" type="text/x-handlebars-template">
|
||||
<div class="setup-item-inputstring">
|
||||
{{#if ispassword}}
|
||||
<input class="form-control" type="password" value="{{{value}}}" />
|
||||
{{else}}
|
||||
<input class="form-control" type="text" value="{{{value}}}" />
|
||||
{{/if}}
|
||||
</div>
|
||||
</script>
|
||||
<script id="setup-item-inputbool" type="text/x-handlebars-template">
|
||||
<div class="setup-item-inputbool">
|
||||
{{#if value}}
|
||||
<input type="checkbox" data-id="{{id}}" class="form-control" checked />
|
||||
{{else}}
|
||||
<input type="checkbox" data-id="{{id}}" class="form-control" />
|
||||
{{/if}}
|
||||
</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}}}" />
|
||||
</script>
|
||||
<script id="setup-item-displayinfo" type="text/x-handlebars-template">
|
||||
<div class="setup-item-displayinfo alert alert-info" role="alert">{{{value}}}</div>
|
||||
</script>
|
||||
<script id="setup-item-hiddendata" type="text/x-handlebars-template">
|
||||
<div class="setup-item-hiddendata">
|
||||
<input class="form-control" type="text" value="{{{value}}}" />
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script id="configured-indexer" type="text/x-handlebars-template">
|
||||
<div class="configured-indexer indexer card">
|
||||
<div class="indexer-logo"><img alt="{{name}}" title="{{name}}" src="/logos/{{id}}.png" /></div>
|
||||
<div class="indexer-buttons">
|
||||
<button class="btn btn-primary btn-sm indexer-setup" data-id="{{id}}">
|
||||
<span class="glyphicon glyphicon-wrench" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button class="btn btn-danger btn-sm indexer-button-delete" data-id="{{id}}">
|
||||
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
|
||||
</button>
|
||||
<a class="btn btn-info btn-sm" target="_blank" href="{{site_link}}">
|
||||
<span class="glyphicon glyphicon-new-window" aria-hidden="true"></span>
|
||||
</a>
|
||||
<button class="btn btn-warning btn-sm indexer-button-test" data-id="{{id}}">
|
||||
Test <span class="glyphicon glyphicon-screenshot" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="indexer-host">
|
||||
<b>Torznab Host:</b>
|
||||
<input class="form-control" type="text" value="{{torznab_host}}" placeholder="Torznab Host" readonly="">
|
||||
<b>CouchPotato Host:</b>
|
||||
{{#if potatoenabled}}
|
||||
|
||||
<input class="form-control" type="text" value="{{potato_host}}" placeholder="Torznab Host" readonly="">
|
||||
{{else}}
|
||||
<input class="form-control" type="text" value="Not availible" placeholder="Torznab Host" readonly="">
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<script id="unconfigured-indexer" type="text/x-handlebars-template">
|
||||
<div class="unconfigured-indexer card">
|
||||
<div class="indexer-logo"><img alt="{{name}}" title="{{name}}" src="/logos/{{id}}.png" /></div>
|
||||
<div class="indexer-buttons">
|
||||
<a class="btn btn-info" target="_blank" href="{{site_link}}">Visit <span class="glyphicon glyphicon-new-window" aria-hidden="true"></span></a>
|
||||
<button class="indexer-setup btn btn-success" data-id="{{id}}">Setup <span class="glyphicon glyphicon-ok" aria-hidden="true"></span></button>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<script id="jackett-releases" type="text/x-handlebars-template">
|
||||
<div id="select-indexer-modal" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg modal-fillwidth">
|
||||
|
@ -164,6 +244,17 @@
|
|||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<script id="add-indexer" type="text/x-handlebars-template">
|
||||
<button class="indexer card add-indexer" data-toggle="modal" data-target="#select-indexer-modal">
|
||||
<div class="indexer-add-content">
|
||||
<span class="glyphicon glyphicon glyphicon-plus" aria-hidden="true"></span>
|
||||
<div class="light-text">Add</div>
|
||||
</div>
|
||||
</button>
|
||||
</script>
|
||||
<script id="spinner" type="text/x-handlebars-template">
|
||||
<span class="spinner glyphicon glyphicon-refresh"></span>
|
||||
</script>
|
||||
|
||||
<title>Jackett</title>
|
||||
</head>
|
||||
|
@ -248,85 +339,6 @@
|
|||
</div>
|
||||
|
||||
<div id="modals"></div>
|
||||
|
||||
<div id="templates">
|
||||
<button class="indexer card add-indexer" data-toggle="modal" data-target="#select-indexer-modal">
|
||||
<div class="indexer-add-content">
|
||||
<span class="glyphicon glyphicon glyphicon-plus" aria-hidden="true"></span>
|
||||
<div class="light-text">Add</div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div class="configured-indexer indexer card">
|
||||
<div class="indexer-logo"><img alt="{{name}}" title="{{name}}" src="/logos/{{id}}.png" /></div>
|
||||
<div class="indexer-buttons">
|
||||
<button class="btn btn-primary btn-sm indexer-setup" data-id="{{id}}">
|
||||
<span class="glyphicon glyphicon-wrench" aria-hidden="true"></span>
|
||||
</button>
|
||||
<button class="btn btn-danger btn-sm indexer-button-delete" data-id="{{id}}">
|
||||
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
|
||||
</button>
|
||||
<a class="btn btn-info btn-sm" target="_blank" href="{{site_link}}">
|
||||
<span class="glyphicon glyphicon-new-window" aria-hidden="true"></span>
|
||||
</a>
|
||||
<button class="btn btn-warning btn-sm indexer-button-test" data-id="{{id}}">
|
||||
Test <span class="glyphicon glyphicon-screenshot" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="indexer-host">
|
||||
<b>Torznab Host:</b>
|
||||
<input class="form-control" type="text" value="{{torznab_host}}" placeholder="Torznab Host" readonly="">
|
||||
<b>CouchPotato Host:</b>
|
||||
{{#if potatoenabled}}
|
||||
|
||||
<input class="form-control" type="text" value="{{potato_host}}" placeholder="Torznab Host" readonly="">
|
||||
{{else}}
|
||||
<input class="form-control" type="text" value="Not availible" placeholder="Torznab Host" readonly="">
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="unconfigured-indexer card">
|
||||
<div class="indexer-logo"><img alt="{{name}}" title="{{name}}" src="/logos/{{id}}.png" /></div>
|
||||
<div class="indexer-buttons">
|
||||
<a class="btn btn-info" target="_blank" href="{{site_link}}">Visit <span class="glyphicon glyphicon-new-window" aria-hidden="true"></span></a>
|
||||
<button class="indexer-setup btn btn-success" data-id="{{id}}">Setup <span class="glyphicon glyphicon-ok" aria-hidden="true"></span></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="setup-item form-group" data-id="{{id}}" data-value="{{value}}" data-type="{{type}}">
|
||||
<div class="setup-item-label">{{name}}</div>
|
||||
<div class="setup-item-value">{{{value_element}}}</div>
|
||||
</div>
|
||||
<div class="setup-item-inputstring">
|
||||
{{#if ispassword}}
|
||||
<input class="form-control" type="password" value="{{{value}}}" />
|
||||
{{else}}
|
||||
<input class="form-control" type="text" value="{{{value}}}" />
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="setup-item-inputbool">
|
||||
{{#if value}}
|
||||
<input type="checkbox" data-id="{{id}}" class="form-control" checked />
|
||||
{{else}}
|
||||
<input type="checkbox" data-id="{{id}}" class="form-control" />
|
||||
{{/if}}
|
||||
</div>
|
||||
<img class="setup-item-displayimage" src="{{{value}}}" />
|
||||
<div class="setup-item-displayinfo alert alert-info" role="alert">{{{value}}}</div>
|
||||
<div class="setup-item-hiddendata">
|
||||
<input class="form-control" type="text" value="{{{value}}}" />
|
||||
</div>
|
||||
|
||||
<span class="spinner glyphicon glyphicon-refresh"></span>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script src="/custom.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -30,5 +30,4 @@ Handlebars.registerHelper('jacketTimespan', function (context, block) {
|
|||
|
||||
var years = timeSpan.asYears();
|
||||
return Math.round(years) + 'y ago';
|
||||
});
|
||||
|
||||
});
|
|
@ -25,9 +25,9 @@ namespace Jackett.Indexers
|
|||
private string LoginUrl { get { return SiteLink + "tak3login.php"; } }
|
||||
private string SearchUrl { get { return SiteLink + "browse.php"; } }
|
||||
|
||||
new ConfigurationDataBasicLogin configData
|
||||
new ConfigurationDataRecaptchaLogin configData
|
||||
{
|
||||
get { return (ConfigurationDataBasicLogin)base.configData; }
|
||||
get { return (ConfigurationDataRecaptchaLogin)base.configData; }
|
||||
set { base.configData = value; }
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,7 @@ namespace Jackett.Indexers
|
|||
client: wc,
|
||||
logger: l,
|
||||
p: ps,
|
||||
configData: new ConfigurationDataBasicLogin())
|
||||
configData: new ConfigurationDataRecaptchaLogin())
|
||||
{
|
||||
|
||||
AddCategoryMapping(29, TorznabCatType.Anime);
|
||||
|
@ -84,19 +84,26 @@ namespace Jackett.Indexers
|
|||
AddCategoryMapping(15, TorznabCatType.XXX);
|
||||
}
|
||||
|
||||
public override async Task<ConfigurationData> GetConfigurationForSetup()
|
||||
{
|
||||
var loginPage = await RequestStringWithCookies(StartPageUrl, string.Empty);
|
||||
CQ cq = loginPage.Content;
|
||||
var result = new ConfigurationDataRecaptchaLogin();
|
||||
result.CookieHeader.Value = loginPage.Cookies;
|
||||
result.Captcha.SiteKey = cq.Find(".g-recaptcha").Attr("data-sitekey");
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task ApplyConfiguration(JToken configJson)
|
||||
{
|
||||
configData.LoadValuesFromJson(configJson);
|
||||
|
||||
var startMessage = await RequestStringWithCookies(StartPageUrl, string.Empty);
|
||||
|
||||
|
||||
var pairs = new Dictionary<string, string> {
|
||||
{ "username", configData.Username.Value },
|
||||
{ "password", configData.Password.Value }
|
||||
{ "password", configData.Password.Value },
|
||||
{ "g-recaptcha-response", configData.Captcha.Value }
|
||||
};
|
||||
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, SiteLink, LoginUrl);
|
||||
var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, configData.CookieHeader.Value, true, SiteLink, LoginUrl);
|
||||
await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
|
||||
{
|
||||
CQ dom = result.Content;
|
||||
|
|
|
@ -213,6 +213,7 @@
|
|||
<Compile Include="Models\CachedLog.cs" />
|
||||
<Compile Include="Models\CachedResult.cs" />
|
||||
<Compile Include="Models\CategoryMapping.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataRecaptchaLogin.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataLoginTokin.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataNCore.cs" />
|
||||
<Compile Include="Models\IndexerConfig\ConfigurationDataCaptchaLogin.cs" />
|
||||
|
|
|
@ -20,7 +20,8 @@ namespace Jackett.Models.IndexerConfig
|
|||
InputBool,
|
||||
DisplayImage,
|
||||
DisplayInfo,
|
||||
HiddenData
|
||||
HiddenData,
|
||||
Recaptcha
|
||||
}
|
||||
|
||||
public HiddenItem CookieHeader { get; private set; } = new HiddenItem { Name = "CookieHeader" };
|
||||
|
@ -69,6 +70,9 @@ namespace Jackett.Models.IndexerConfig
|
|||
case ItemType.InputBool:
|
||||
((BoolItem)item).Value = arrItem.Value<bool>("value");
|
||||
break;
|
||||
case ItemType.Recaptcha:
|
||||
((RecaptchaItem)item).Value = arrItem.Value<string>("value");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -85,6 +89,9 @@ namespace Jackett.Models.IndexerConfig
|
|||
jObject["name"] = item.Name;
|
||||
switch (item.ItemType)
|
||||
{
|
||||
case ItemType.Recaptcha:
|
||||
jObject["sitekey"] = ((RecaptchaItem)item).SiteKey;
|
||||
break;
|
||||
case ItemType.InputString:
|
||||
case ItemType.HiddenData:
|
||||
case ItemType.DisplayInfo:
|
||||
|
@ -98,7 +105,6 @@ namespace Jackett.Models.IndexerConfig
|
|||
else if (ps != null)
|
||||
value = ps.Protect(value);
|
||||
}
|
||||
|
||||
jObject["value"] = value;
|
||||
break;
|
||||
case ItemType.InputBool:
|
||||
|
@ -125,7 +131,7 @@ namespace Jackett.Models.IndexerConfig
|
|||
if (!forDisplay)
|
||||
{
|
||||
properties = properties
|
||||
.Where(p => p.ItemType == ItemType.HiddenData || p.ItemType == ItemType.InputBool || p.ItemType == ItemType.InputString)
|
||||
.Where(p => p.ItemType == ItemType.HiddenData || p.ItemType == ItemType.InputBool || p.ItemType == ItemType.InputString || p.ItemType == ItemType.Recaptcha)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
|
@ -159,6 +165,7 @@ namespace Jackett.Models.IndexerConfig
|
|||
|
||||
public class StringItem : Item
|
||||
{
|
||||
public string SiteKey { get; set; }
|
||||
public string Value { get; set; }
|
||||
public StringItem()
|
||||
{
|
||||
|
@ -166,6 +173,14 @@ namespace Jackett.Models.IndexerConfig
|
|||
}
|
||||
}
|
||||
|
||||
public class RecaptchaItem : StringItem
|
||||
{
|
||||
public RecaptchaItem()
|
||||
{
|
||||
ItemType = ConfigurationData.ItemType.Recaptcha;
|
||||
}
|
||||
}
|
||||
|
||||
public class BoolItem : Item
|
||||
{
|
||||
public bool Value { get; set; }
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Jackett.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 ConfigurationDataRecaptchaLogin()
|
||||
{
|
||||
Username = new StringItem { Name = "Username" };
|
||||
Password = new StringItem { Name = "Password" };
|
||||
Captcha = new RecaptchaItem() { Name = "Recaptcha" };
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue