Restore support for noscript fallback version of Recaptcha v1. Can be activated through new Force Noscript Captcha for v1 option.
Effectively reverts 0feb6637cf0d4e72eb5470734153c4c549c4fcce, 909f70c6e61eabe064a8374ce32c1a35d564a09f.
This commit is contained in:
parent
379137fbc0
commit
daae2f0236
@ -38,7 +38,8 @@
|
|||||||
"https://www.google.com/recaptcha/api2/frame?*&k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*",
|
"https://www.google.com/recaptcha/api2/frame?*&k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*",
|
||||||
"https://www.google.com/recaptcha/api2/frame?*&k=887877714&*",
|
"https://www.google.com/recaptcha/api2/frame?*&k=887877714&*",
|
||||||
"https://www.google.com/recaptcha/api2/bframe?*&k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*",
|
"https://www.google.com/recaptcha/api2/bframe?*&k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*",
|
||||||
"*://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*"
|
"*://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*",
|
||||||
|
"*://www.google.com/recaptcha/api/noscript?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*"
|
||||||
],
|
],
|
||||||
"exclude_matches": [
|
"exclude_matches": [
|
||||||
"*://www.4chan.org/pass",
|
"*://www.4chan.org/pass",
|
||||||
|
|||||||
203
src/Posting/Captcha.noscript.coffee
Normal file
203
src/Posting/Captcha.noscript.coffee
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
Captcha.noscript =
|
||||||
|
lifetime: 30 * $.MINUTE
|
||||||
|
|
||||||
|
init: ->
|
||||||
|
return if d.cookie.indexOf('pass_enabled=1') >= 0
|
||||||
|
return if not (@isEnabled = !!$ '#g-recaptcha, #captchaContainerAlt')
|
||||||
|
|
||||||
|
container = $.el 'div',
|
||||||
|
className: 'captcha-img'
|
||||||
|
title: 'Reload reCAPTCHA'
|
||||||
|
|
||||||
|
input = $.el 'input',
|
||||||
|
className: 'captcha-input field'
|
||||||
|
title: 'Verification'
|
||||||
|
autocomplete: 'off'
|
||||||
|
spellcheck: false
|
||||||
|
@nodes = {container, input}
|
||||||
|
|
||||||
|
$.on input, 'blur', QR.focusout
|
||||||
|
$.on input, 'focus', QR.focusin
|
||||||
|
$.on input, 'keydown', @keydown.bind @
|
||||||
|
# Disable auto-posting if you're typing the captcha during the last 5 seconds of the cooldown.
|
||||||
|
$.on input, 'input', -> QR.posts[0].preventAutoPost() unless Captcha.cache.getCount()
|
||||||
|
$.on @nodes.container, 'click', =>
|
||||||
|
@reload()
|
||||||
|
@nodes.input.focus()
|
||||||
|
|
||||||
|
@conn = new Connection null, 'https://www.google.com',
|
||||||
|
challenge: @load.bind @
|
||||||
|
token: @save.bind @
|
||||||
|
error: @error.bind @
|
||||||
|
|
||||||
|
$.addClass QR.nodes.el, 'has-captcha', 'captcha-v1', 'noscript-captcha'
|
||||||
|
$.after QR.nodes.com.parentNode, [container, input]
|
||||||
|
|
||||||
|
Captcha.cache.init()
|
||||||
|
$.on d, 'CaptchaCount', @count.bind(@)
|
||||||
|
|
||||||
|
@beforeSetup()
|
||||||
|
@setup()
|
||||||
|
|
||||||
|
initFrame: ->
|
||||||
|
conn = new Connection window.parent, 'https://boards.4chan.org',
|
||||||
|
response: (response) ->
|
||||||
|
$.id('recaptcha_response_field').value = response
|
||||||
|
# The form has a field named 'submit'
|
||||||
|
HTMLFormElement.prototype.submit.call $('form')
|
||||||
|
if location.hash is '#response'
|
||||||
|
conn.send
|
||||||
|
token: $('textarea')?.value
|
||||||
|
error: $('.recaptcha_input_area')?.textContent.replace(/:$/, '')
|
||||||
|
return unless img = $ 'img'
|
||||||
|
$('form').action = '#response'
|
||||||
|
cb = ->
|
||||||
|
canvas = $.el 'canvas'
|
||||||
|
canvas.width = img.width
|
||||||
|
canvas.height = img.height
|
||||||
|
canvas.getContext('2d').drawImage(img, 0, 0)
|
||||||
|
conn.send {challenge: canvas.toDataURL()}
|
||||||
|
if img.complete
|
||||||
|
cb()
|
||||||
|
else
|
||||||
|
$.on img, 'load', cb
|
||||||
|
|
||||||
|
timers: {}
|
||||||
|
|
||||||
|
iframeURL: ->
|
||||||
|
url = 'https://www.google.com/recaptcha/api/noscript?k=<%= meta.recaptchaKey %>'
|
||||||
|
if lang = Conf['captchaLanguage'].trim()
|
||||||
|
url += "&hl=#{encodeURIComponent lang}"
|
||||||
|
url
|
||||||
|
|
||||||
|
cb:
|
||||||
|
focus: -> QR.captcha.setup false, true
|
||||||
|
|
||||||
|
beforeSetup: ->
|
||||||
|
{container, input} = @nodes
|
||||||
|
container.hidden = true
|
||||||
|
input.value = ''
|
||||||
|
input.placeholder = 'Focus to load reCAPTCHA'
|
||||||
|
@count()
|
||||||
|
$.on input, 'focus click', @cb.focus
|
||||||
|
|
||||||
|
moreNeeded: ->
|
||||||
|
|
||||||
|
setup: (focus, force) ->
|
||||||
|
return unless @isEnabled and (force or Captcha.cache.needed())
|
||||||
|
if !@nodes.iframe
|
||||||
|
@nodes.iframe = $.el 'iframe',
|
||||||
|
id: 'qr-captcha-iframe'
|
||||||
|
src: @iframeURL()
|
||||||
|
$.add QR.nodes.el, @nodes.iframe
|
||||||
|
@conn.target = @nodes.iframe
|
||||||
|
else if !@occupied or force
|
||||||
|
@nodes.iframe.src = @iframeURL()
|
||||||
|
@occupied = true
|
||||||
|
@nodes.input.focus() if focus
|
||||||
|
|
||||||
|
afterSetup: ->
|
||||||
|
{container, input} = @nodes
|
||||||
|
container.hidden = false
|
||||||
|
input.placeholder = 'Verification'
|
||||||
|
@count()
|
||||||
|
$.off input, 'focus click', @cb.focus
|
||||||
|
|
||||||
|
if QR.nodes.el.getBoundingClientRect().bottom > doc.clientHeight
|
||||||
|
QR.nodes.el.style.top = ''
|
||||||
|
QR.nodes.el.style.bottom = '0px'
|
||||||
|
|
||||||
|
destroy: ->
|
||||||
|
return unless @isEnabled
|
||||||
|
$.rm @nodes.img
|
||||||
|
delete @nodes.img
|
||||||
|
$.rm @nodes.iframe
|
||||||
|
delete @nodes.iframe
|
||||||
|
delete @occupied
|
||||||
|
@beforeSetup()
|
||||||
|
|
||||||
|
getOne: (isReply) ->
|
||||||
|
if (captcha = Captcha.cache.getOne isReply)
|
||||||
|
captcha
|
||||||
|
else if /\S/.test @nodes.input.value
|
||||||
|
(cb) =>
|
||||||
|
@submitCB = cb
|
||||||
|
@sendResponse()
|
||||||
|
else
|
||||||
|
null
|
||||||
|
|
||||||
|
sendResponse: ->
|
||||||
|
response = @nodes.input.value
|
||||||
|
if /\S/.test response
|
||||||
|
@conn.send {response}
|
||||||
|
|
||||||
|
save: (token) ->
|
||||||
|
delete @occupied
|
||||||
|
@nodes.input.value = ''
|
||||||
|
captcha =
|
||||||
|
challenge: token
|
||||||
|
response: 'manual_challenge'
|
||||||
|
timeout: @timeout
|
||||||
|
if @submitCB
|
||||||
|
@submitCB captcha
|
||||||
|
delete @submitCB
|
||||||
|
if Captcha.cache.needed() then @reload() else @destroy()
|
||||||
|
else
|
||||||
|
Captcha.cache.save captcha
|
||||||
|
@reload()
|
||||||
|
|
||||||
|
error: (message) ->
|
||||||
|
@occupied = true
|
||||||
|
@nodes.input.value = ''
|
||||||
|
if @submitCB
|
||||||
|
@submitCB()
|
||||||
|
delete @submitCB
|
||||||
|
QR.error "Captcha Error: #{message}"
|
||||||
|
|
||||||
|
load: (src) ->
|
||||||
|
{container, input, img} = @nodes
|
||||||
|
@occupied = true
|
||||||
|
@timeout = Date.now() + @lifetime
|
||||||
|
unless img
|
||||||
|
img = @nodes.img = new Image()
|
||||||
|
$.one img, 'load', @afterSetup.bind @
|
||||||
|
$.on img, 'load', -> @hidden = false
|
||||||
|
$.add container, img
|
||||||
|
img.src = src
|
||||||
|
input.value = ''
|
||||||
|
clearTimeout @timers.expire
|
||||||
|
@timers.expire = setTimeout @expire.bind(@), @lifetime
|
||||||
|
|
||||||
|
count: ->
|
||||||
|
count = Captcha.cache.getCount()
|
||||||
|
placeholder = @nodes.input.placeholder.replace /\ \(.*\)$/, ''
|
||||||
|
placeholder += switch count
|
||||||
|
when 0
|
||||||
|
if placeholder is 'Verification' then ' (Shift + Enter to cache)' else ''
|
||||||
|
when 1
|
||||||
|
' (1 cached captcha)'
|
||||||
|
else
|
||||||
|
" (#{count} cached captchas)"
|
||||||
|
@nodes.input.placeholder = placeholder
|
||||||
|
@nodes.input.alt = count # For XTRM RICE.
|
||||||
|
|
||||||
|
expire: ->
|
||||||
|
return unless @nodes.iframe
|
||||||
|
if not d.hidden and (Captcha.cache.needed() or d.activeElement is @nodes.input)
|
||||||
|
@reload()
|
||||||
|
else
|
||||||
|
@destroy()
|
||||||
|
|
||||||
|
reload: ->
|
||||||
|
@nodes.iframe.src = @iframeURL()
|
||||||
|
@occupied = true
|
||||||
|
@nodes.img?.hidden = true
|
||||||
|
|
||||||
|
keydown: (e) ->
|
||||||
|
if e.keyCode is 8 and not @nodes.input.value
|
||||||
|
if @nodes.iframe then @reload() else @setup()
|
||||||
|
else if e.keyCode is 13 and e.shiftKey
|
||||||
|
@sendResponse()
|
||||||
|
else
|
||||||
|
return
|
||||||
|
e.preventDefault()
|
||||||
@ -28,7 +28,11 @@ QR =
|
|||||||
|
|
||||||
return if g.VIEW is 'archive'
|
return if g.VIEW is 'archive'
|
||||||
|
|
||||||
version = if Conf[if g.VIEW is 'thread' then 'Use Recaptcha v1' else 'Use Recaptcha v1 on Index'] and Main.jsEnabled then 'v1' else 'v2'
|
version = if Conf[if g.VIEW is 'thread' then 'Use Recaptcha v1' else 'Use Recaptcha v1 on Index'] and (Main.jsEnabled or location.protocol is 'https:')
|
||||||
|
noscript = location.protocol is 'https:' and (Conf['Force Noscript Captcha for v1'] or not Main.jsEnabled)
|
||||||
|
if noscript then 'noscript' else 'v1'
|
||||||
|
else
|
||||||
|
'v2'
|
||||||
@captcha = Captcha[version]
|
@captcha = Captcha[version]
|
||||||
|
|
||||||
$.on d, '4chanXInitFinished', -> BoardConfig.ready QR.initReady
|
$.on d, '4chanXInitFinished', -> BoardConfig.ready QR.initReady
|
||||||
@ -680,15 +684,32 @@ QR =
|
|||||||
QR.req.progress = "#{Math.round e.loaded / e.total * 100}%"
|
QR.req.progress = "#{Math.round e.loaded / e.total * 100}%"
|
||||||
QR.status()
|
QR.status()
|
||||||
|
|
||||||
if captcha?
|
cb = (response) ->
|
||||||
QR.currentCaptcha = captcha
|
if response?
|
||||||
if captcha.challenge?
|
QR.currentCaptcha = response
|
||||||
extra.form.append 'recaptcha_challenge_field', captcha.challenge
|
if response.challenge?
|
||||||
extra.form.append 'recaptcha_response_field', captcha.response
|
extra.form.append 'recaptcha_challenge_field', response.challenge
|
||||||
else
|
extra.form.append 'recaptcha_response_field', response.response
|
||||||
extra.form.append 'g-recaptcha-response', captcha.response
|
else
|
||||||
QR.req = $.ajax "https://sys.4chan.org/#{g.BOARD}/post", options, extra
|
extra.form.append 'g-recaptcha-response', response.response
|
||||||
QR.req.progress = '...'
|
QR.req = $.ajax "https://sys.4chan.org/#{g.BOARD}/post", options, extra
|
||||||
|
QR.req.progress = '...'
|
||||||
|
|
||||||
|
if typeof captcha is 'function'
|
||||||
|
# Wait for captcha to be verified before submitting post.
|
||||||
|
QR.req =
|
||||||
|
progress: '...'
|
||||||
|
abort: -> cb = null
|
||||||
|
captcha (response) ->
|
||||||
|
if response
|
||||||
|
cb? response
|
||||||
|
else
|
||||||
|
delete QR.req
|
||||||
|
post.unlock()
|
||||||
|
QR.cooldown.auto = !!Captcha.cache.getCount()
|
||||||
|
QR.status()
|
||||||
|
else
|
||||||
|
cb captcha
|
||||||
|
|
||||||
# Starting to upload might take some time.
|
# Starting to upload might take some time.
|
||||||
# Provide some feedback that we're starting to submit.
|
# Provide some feedback that we're starting to submit.
|
||||||
|
|||||||
@ -509,6 +509,10 @@ Config =
|
|||||||
false
|
false
|
||||||
'Use the non-Javascript fallback captcha even if Javascript is enabled (Recaptcha v2 only).'
|
'Use the non-Javascript fallback captcha even if Javascript is enabled (Recaptcha v2 only).'
|
||||||
]
|
]
|
||||||
|
'Force Noscript Captcha for v1': [
|
||||||
|
false
|
||||||
|
'Force the non-Javascript fallback captcha for Recaptcha v1. Currently only works on HTTPS.'
|
||||||
|
]
|
||||||
'Pass Link': [
|
'Pass Link': [
|
||||||
false
|
false
|
||||||
'Add a 4chan Pass login link to the bottom of the page.'
|
'Add a 4chan Pass login link to the bottom of the page.'
|
||||||
|
|||||||
@ -8,6 +8,9 @@ Main =
|
|||||||
window['<%= meta.name %> antidup'] = true
|
window['<%= meta.name %> antidup'] = true
|
||||||
|
|
||||||
if location.hostname is 'www.google.com'
|
if location.hostname is 'www.google.com'
|
||||||
|
if location.pathname is '/recaptcha/api/noscript'
|
||||||
|
$.ready -> Captcha.noscript.initFrame()
|
||||||
|
return
|
||||||
$.get 'Captcha Fixes', true, ({'Captcha Fixes': enabled}) ->
|
$.get 'Captcha Fixes', true, ({'Captcha Fixes': enabled}) ->
|
||||||
if enabled
|
if enabled
|
||||||
$.ready -> Captcha.fixes.init()
|
$.ready -> Captcha.fixes.init()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user