persistent captchas

This commit is contained in:
James Campos 2011-08-10 19:22:50 -07:00
parent 9d24204502
commit 208e0b071c
2 changed files with 62 additions and 27 deletions

View File

@ -59,7 +59,7 @@
*/ */
(function() { (function() {
var $, $$, Favicon, NAMESPACE, Recaptcha, Time, anonymize, conf, config, cooldown, d, expandComment, expandThread, firstRun, g, imgExpand, imgGif, imgHover, imgPreloading, key, keybinds, log, main, nav, nodeInserted, options, qr, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher, _ref; var $, $$, DAY, Favicon, HOUR, MINUTE, NAMESPACE, Recaptcha, SECOND, Time, anonymize, conf, config, cooldown, d, expandComment, expandThread, firstRun, g, imgExpand, imgGif, imgHover, imgPreloading, key, keybinds, log, main, nav, nodeInserted, options, qr, quoteBacklink, quoteInline, quoteOP, quotePreview, redirect, replyHiding, reportButton, revealSpoilers, sauce, threadHiding, threadStats, threading, titlePost, ui, unread, updater, val, watcher, _ref;
var __slice = Array.prototype.slice; var __slice = Array.prototype.slice;
config = { config = {
main: { main: {
@ -183,6 +183,10 @@
}; };
} }
NAMESPACE = 'AEOS.4chan_x.'; NAMESPACE = 'AEOS.4chan_x.';
SECOND = 1000;
MINUTE = 60 * SECOND;
HOUR = 60 * MINUTE;
DAY = 24 * HOUR;
d = document; d = document;
g = { g = {
callbacks: [] callbacks: []
@ -1215,7 +1219,7 @@
g.callbacks.push(qr.node); g.callbacks.push(qr.node);
$.bind(window, 'message', qr.message); $.bind(window, 'message', qr.message);
$.bind($('#recaptcha_challenge_field_holder'), 'DOMNodeInserted', qr.captchaNode); $.bind($('#recaptcha_challenge_field_holder'), 'DOMNodeInserted', qr.captchaNode);
qr.captcha = []; qr.captchaTime = Date.now();
iframe = $.el('iframe', { iframe = $.el('iframe', {
name: 'iframe', name: 'iframe',
hidden: true hidden: true
@ -1243,14 +1247,27 @@
return $.replace(oldFile, file); return $.replace(oldFile, file);
}, },
autoPost: function() { autoPost: function() {
var captcha, responseField; /*
if (!(captcha = qr.captcha.shift())) { captchas expire after 5 hours (couldn't find an official source, so
anonymous empirically verified). cutoff 5 minutes before then, b/c posting
takes time.
*/
var captcha, captchas, cutoff, responseField;
cutoff = Date.now() - 5 * HOUR + 5 * MINUTE;
captchas = $.getValue('captchas', []);
while (captcha = captchas.shift()) {
if (captcha.time > cutoff) {
break;
}
}
$.setValue('captchas', captchas);
responseField = $('#recaptcha_response_field', qr.el);
responseField.nextSibling.textContent = captchas.length + ' captchas';
if (!captcha) {
return; return;
} }
$('#recaptcha_challenge_field', qr.el).value = captcha.challenge; $('#recaptcha_challenge_field', qr.el).value = captcha.challenge;
responseField = $('#recaptcha_response_field', qr.el);
responseField.value = captcha.response; responseField.value = captcha.response;
responseField.nextSibling.textContent = qr.captcha.length + ' captcha cached';
return qr.submit.call($('form', qr.el)); return qr.submit.call($('form', qr.el));
}, },
captchaNode: function(e) { captchaNode: function(e) {
@ -1260,10 +1277,11 @@
} }
target = e.target; target = e.target;
$('img', qr.el).src = "http://www.google.com/recaptcha/api/image?c=" + target.value; $('img', qr.el).src = "http://www.google.com/recaptcha/api/image?c=" + target.value;
return $('#recaptcha_challenge_field', qr.el).value = target.value; $('#recaptcha_challenge_field', qr.el).value = target.value;
return qr.captchaTime = Date.now();
}, },
captchaKeydown: function(e) { captchaKeydown: function(e) {
var blank; var blank, captcha, l;
if (!(e.keyCode === 13 && this.value)) { if (!(e.keyCode === 13 && this.value)) {
return; return;
} }
@ -1275,13 +1293,11 @@
if (conf['Auto Hide QR']) { if (conf['Auto Hide QR']) {
$('#autohide', qr.el).checked = true; $('#autohide', qr.el).checked = true;
} }
return qr.captchaPush.call(this); captcha = $.getValue('captcha', []);
}, l = captcha.push({
captchaPush: function() {
var l;
l = qr.captcha.push({
challenge: $('#recaptcha_challenge_field', qr.el).value, challenge: $('#recaptcha_challenge_field', qr.el).value,
response: this.value response: this.value,
time: qr.captchaTime
}); });
this.nextSibling.textContent = l + ' captcha cached'; this.nextSibling.textContent = l + ' captcha cached';
Recaptcha.reload(); Recaptcha.reload();
@ -1298,7 +1314,7 @@
THREAD_ID = g.THREAD_ID || $.x('ancestor::div[@class="thread"]/div', link).id; THREAD_ID = g.THREAD_ID || $.x('ancestor::div[@class="thread"]/div', link).id;
spoiler = $('.postarea label') ? '<label> [<input type=checkbox name=spoiler>Spoiler Image?]</label>' : ''; spoiler = $('.postarea label') ? '<label> [<input type=checkbox name=spoiler>Spoiler Image?]</label>' : '';
challenge = $('#recaptcha_challenge_field').value; challenge = $('#recaptcha_challenge_field').value;
html = " <a id=close title=close>X</a> <input type=checkbox id=autohide title=autohide> <div class=move> <input class=inputtext type=text name=name placeholder=Name form=qr_form> Quick Reply </div> <form name=post action=http://sys.4chan.org/" + g.BOARD + "/post method=POST enctype=multipart/form-data target=iframe id=qr_form> <input type=hidden name=resto value=" + THREAD_ID + "> <input type=hidden name=recaptcha_challenge_field id=recaptcha_challenge_field value=" + challenge + "> <div><input class=inputtext type=text name=email placeholder=E-mail>" + spoiler + "</div> <div><input class=inputtext type=text name=sub placeholder=Subject><input type=submit value=" + submitValue + " id=com_submit " + submitDisabled + "><label><input type=checkbox id=auto>auto</label></div> <div><textarea class=inputtext name=com placeholder=Comment></textarea></div> <div><img src=http://www.google.com/recaptcha/api/image?c=" + challenge + "></div> <div><input class=inputtext type=text name=recaptcha_response_field placeholder=Verification required autocomplete=off id=recaptcha_response_field><span class=captcha>" + qr.captcha.length + " captcha cached</span></div> <div><input type=file name=upfile></div> <div><input class=inputtext type=password name=pwd maxlength=8 placeholder=Password><input type=hidden name=mode value=regist><a name=attach>attach another file</a></div> </form> <div id=files></div> <a id=error class=error></a> "; html = " <a id=close title=close>X</a> <input type=checkbox id=autohide title=autohide> <div class=move> <input class=inputtext type=text name=name placeholder=Name form=qr_form> Quick Reply </div> <form name=post action=http://sys.4chan.org/" + g.BOARD + "/post method=POST enctype=multipart/form-data target=iframe id=qr_form> <input type=hidden name=resto value=" + THREAD_ID + "> <input type=hidden name=recaptcha_challenge_field id=recaptcha_challenge_field value=" + challenge + "> <div><input class=inputtext type=text name=email placeholder=E-mail>" + spoiler + "</div> <div><input class=inputtext type=text name=sub placeholder=Subject><input type=submit value=" + submitValue + " id=com_submit " + submitDisabled + "><label><input type=checkbox id=auto>auto</label></div> <div><textarea class=inputtext name=com placeholder=Comment></textarea></div> <div><img src=http://www.google.com/recaptcha/api/image?c=" + challenge + "></div> <div><input class=inputtext type=text name=recaptcha_response_field placeholder=Verification required autocomplete=off id=recaptcha_response_field><span class=captcha>" + ($.getValue('captcha', []).length) + " captcha cached</span></div> <div><input type=file name=upfile></div> <div><input class=inputtext type=password name=pwd maxlength=8 placeholder=Password><input type=hidden name=mode value=regist><a name=attach>attach another file</a></div> </form> <div id=files></div> <a id=error class=error></a> ";
qr.el = ui.dialog('qr', { qr.el = ui.dialog('qr', {
top: '0px', top: '0px',
left: '0px' left: '0px'
@ -2685,7 +2701,7 @@
}; };
main = { main = {
init: function() { init: function() {
var DAY, callback, canPost, cutoff, form, hiddenThreads, id, lastChecked, now, op, pathname, table, temp, timestamp, tzOffset, _i, _j, _k, _l, _len, _len2, _len3, _len4, _ref2, _ref3, _ref4, _ref5, _ref6; var callback, canPost, cutoff, form, hiddenThreads, id, lastChecked, now, op, pathname, table, temp, timestamp, tzOffset, _i, _j, _k, _l, _len, _len2, _len3, _len4, _ref2, _ref3, _ref4, _ref5, _ref6;
pathname = location.pathname.substring(1).split('/'); pathname = location.pathname.substring(1).split('/');
g.BOARD = pathname[0], temp = pathname[1]; g.BOARD = pathname[0], temp = pathname[1];
if (temp === 'res') { if (temp === 'res') {
@ -2715,7 +2731,6 @@
} }
lastChecked = $.getValue('lastChecked', 0); lastChecked = $.getValue('lastChecked', 0);
now = Date.now(); now = Date.now();
DAY = 1000 * 60 * 60 * 24;
if (lastChecked < now - 1 * DAY) { if (lastChecked < now - 1 * DAY) {
cutoff = now - 7 * DAY; cutoff = now - 7 * DAY;
hiddenThreads = $.getValue("hiddenThreads/" + g.BOARD + "/", {}); hiddenThreads = $.getValue("hiddenThreads/" + g.BOARD + "/", {});

View File

@ -107,6 +107,10 @@ if not Object.keys
key for key in o key for key in o
NAMESPACE = 'AEOS.4chan_x.' NAMESPACE = 'AEOS.4chan_x.'
SECOND = 1000
MINUTE = 60*SECOND
HOUR = 60*MINUTE
DAY = 24*HOUR
d = document d = document
g = callbacks: [] g = callbacks: []
@ -959,7 +963,7 @@ qr =
g.callbacks.push qr.node g.callbacks.push qr.node
$.bind window, 'message', qr.message $.bind window, 'message', qr.message
$.bind $('#recaptcha_challenge_field_holder'), 'DOMNodeInserted', qr.captchaNode $.bind $('#recaptcha_challenge_field_holder'), 'DOMNodeInserted', qr.captchaNode
qr.captcha = [] qr.captchaTime = Date.now()
iframe = $.el 'iframe', iframe = $.el 'iframe',
name: 'iframe' name: 'iframe'
@ -983,11 +987,27 @@ qr =
$.replace oldFile, file $.replace oldFile, file
autoPost: -> autoPost: ->
return unless captcha = qr.captcha.shift() ###
$('#recaptcha_challenge_field', qr.el).value = captcha.challenge captchas expire after 5 hours (couldn't find an official source, so
anonymous empirically verified). cutoff 5 minutes before then, b/c posting
takes time.
###
cutoff = Date.now() - 5*HOUR + 5*MINUTE
captchas = $.getValue 'captchas', []
while captcha = captchas.shift()
if captcha.time > cutoff
break
$.setValue 'captchas', captchas
responseField = $ '#recaptcha_response_field', qr.el responseField = $ '#recaptcha_response_field', qr.el
responseField.nextSibling.textContent = captchas.length + ' captchas'
return unless captcha
$('#recaptcha_challenge_field', qr.el).value = captcha.challenge
responseField.value = captcha.response responseField.value = captcha.response
responseField.nextSibling.textContent = qr.captcha.length + ' captcha cached'
qr.submit.call $ 'form', qr.el qr.submit.call $ 'form', qr.el
captchaNode: (e) -> captchaNode: (e) ->
@ -995,21 +1015,22 @@ qr =
{target} = e {target} = e
$('img', qr.el).src = "http://www.google.com/recaptcha/api/image?c=" + target.value $('img', qr.el).src = "http://www.google.com/recaptcha/api/image?c=" + target.value
$('#recaptcha_challenge_field', qr.el).value = target.value $('#recaptcha_challenge_field', qr.el).value = target.value
qr.captchaTime = Date.now()
captchaKeydown: (e) -> captchaKeydown: (e) ->
return unless e.keyCode is 13 and @value #enter return unless e.keyCode is 13 and @value #enter, captcha filled
blank = !$('textarea', qr.el).value and !$('input[type=file]', qr.el).files.length blank = !$('textarea', qr.el).value and !$('input[type=file]', qr.el).files.length
return unless blank or cooldown.duration return unless blank or cooldown.duration
$('#auto', qr.el).checked = true $('#auto', qr.el).checked = true
$('#autohide', qr.el).checked = true if conf['Auto Hide QR'] $('#autohide', qr.el).checked = true if conf['Auto Hide QR']
qr.captchaPush.call this
captchaPush: -> captcha = $.getValue 'captcha', []
l = qr.captcha.push l = captcha.push
challenge: $('#recaptcha_challenge_field', qr.el).value challenge: $('#recaptcha_challenge_field', qr.el).value
response: @value response: @value
time: qr.captchaTime
@nextSibling.textContent = l + ' captcha cached' @nextSibling.textContent = l + ' captcha cached'
Recaptcha.reload() Recaptcha.reload()
@value = '' @value = ''
@ -1039,7 +1060,7 @@ qr =
<div><input class=inputtext type=text name=sub placeholder=Subject><input type=submit value=#{submitValue} id=com_submit #{submitDisabled}><label><input type=checkbox id=auto>auto</label></div> <div><input class=inputtext type=text name=sub placeholder=Subject><input type=submit value=#{submitValue} id=com_submit #{submitDisabled}><label><input type=checkbox id=auto>auto</label></div>
<div><textarea class=inputtext name=com placeholder=Comment></textarea></div> <div><textarea class=inputtext name=com placeholder=Comment></textarea></div>
<div><img src=http://www.google.com/recaptcha/api/image?c=#{challenge}></div> <div><img src=http://www.google.com/recaptcha/api/image?c=#{challenge}></div>
<div><input class=inputtext type=text name=recaptcha_response_field placeholder=Verification required autocomplete=off id=recaptcha_response_field><span class=captcha>#{qr.captcha.length} captcha cached</span></div> <div><input class=inputtext type=text name=recaptcha_response_field placeholder=Verification required autocomplete=off id=recaptcha_response_field><span class=captcha>#{$.getValue('captcha', []).length} captcha cached</span></div>
<div><input type=file name=upfile></div> <div><input type=file name=upfile></div>
<div><input class=inputtext type=password name=pwd maxlength=8 placeholder=Password><input type=hidden name=mode value=regist><a name=attach>attach another file</a></div> <div><input class=inputtext type=password name=pwd maxlength=8 placeholder=Password><input type=hidden name=mode value=regist><a name=attach>attach another file</a></div>
</form> </form>
@ -2117,7 +2138,6 @@ main =
lastChecked = $.getValue 'lastChecked', 0 lastChecked = $.getValue 'lastChecked', 0
now = Date.now() now = Date.now()
DAY = 1000 * 60 * 60 * 24
if lastChecked < now - 1*DAY if lastChecked < now - 1*DAY
cutoff = now - 7*DAY cutoff = now - 7*DAY
hiddenThreads = $.getValue "hiddenThreads/#{g.BOARD}/", {} hiddenThreads = $.getValue "hiddenThreads/#{g.BOARD}/", {}