diff --git a/package.json b/package.json index 422eac6f3..0b89ad010 100644 --- a/package.json +++ b/package.json @@ -40,8 +40,7 @@ "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/bframe?*&k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*", - "*://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*", - "*://www.google.com/recaptcha/api/noscript?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*" + "*://www.google.com/recaptcha/api/fallback?k=6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc*" ], "exclude_matches": [ "*://www.4chan.org/pass", diff --git a/src/Menu/ReportLink.coffee b/src/Menu/ReportLink.coffee index 42b927826..c354b8def 100644 --- a/src/Menu/ReportLink.coffee +++ b/src/Menu/ReportLink.coffee @@ -13,8 +13,7 @@ ReportLink = order: 10 open: (post) -> ReportLink.url = "//sys.4chan.org/#{post.board}/imgboard.php?mode=report&no=#{post}" - if (Conf['Use Recaptcha v1 in Reports'] and Main.jsEnabled) or d.cookie.indexOf('pass_enabled=1') >= 0 - ReportLink.url += '&altc=1' + if d.cookie.indexOf('pass_enabled=1') >= 0 ReportLink.dims = 'width=350,height=275' else ReportLink.dims = 'width=400,height=550' diff --git a/src/Posting/Captcha.noscript.coffee b/src/Posting/Captcha.noscript.coffee deleted file mode 100644 index 20783b910..000000000 --- a/src/Posting/Captcha.noscript.coffee +++ /dev/null @@ -1,203 +0,0 @@ -Captcha.noscript = - lifetime: 30 * $.MINUTE - - init: -> - return if d.cookie.indexOf('pass_enabled=1') >= 0 - return if not (@isEnabled = !!$ '#g-recaptcha, #captcha-forced-noscript') - - 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() diff --git a/src/Posting/Captcha.replace.coffee b/src/Posting/Captcha.replace.coffee index eb6c7e90f..6326bc0bf 100644 --- a/src/Posting/Captcha.replace.coffee +++ b/src/Posting/Captcha.replace.coffee @@ -2,16 +2,6 @@ Captcha.replace = init: -> return unless d.cookie.indexOf('pass_enabled=1') < 0 - if location.hostname is 'sys.4chan.org' and /[?&]altc\b/.test(location.search) and Main.jsEnabled - $.onExists doc, 'script[src="//www.google.com/recaptcha/api/js/recaptcha_ajax.js"]', -> - $.global -> window.el.onload = null - Captcha.v1.create() - return - - if location.hostname is 'sys.4chan.org' and Conf['Use Recaptcha v1 in Reports'] and Main.jsEnabled - $.ready Captcha.replace.v1 - return - if Conf['Force Noscript Captcha'] and Main.jsEnabled $.ready Captcha.replace.noscript return @@ -36,16 +26,6 @@ Captcha.replace = else insert() - v1: -> - return if not (old = $.id 'g-recaptcha') - script = $.el 'script', - src: '//www.google.com/recaptcha/api/js/recaptcha_ajax.js' - $.add d.head, script - container = $.el 'div', - id: 'captchaContainerAlt' - $.replace old, container - Captcha.v1.create() - iframe: (iframe) -> if (lang = Conf['captchaLanguage'].trim()) src = if /[?&]hl=/.test iframe.src diff --git a/src/Posting/Captcha.v1.coffee b/src/Posting/Captcha.v1.coffee deleted file mode 100644 index 446cea881..000000000 --- a/src/Posting/Captcha.v1.coffee +++ /dev/null @@ -1,198 +0,0 @@ -Captcha.v1 = - blank: "data:image/svg+xml," - - init: -> - return if d.cookie.indexOf('pass_enabled=1') >= 0 - return if not (@isEnabled = !!$ '#g-recaptcha, #captcha-forced-noscript') - - imgContainer = $.el 'div', - className: 'captcha-img' - title: 'Reload reCAPTCHA' - $.extend imgContainer, <%= html('') %> - input = $.el 'input', - className: 'captcha-input field' - title: 'Verification' - autocomplete: 'off' - spellcheck: false - @nodes = - img: imgContainer.firstChild - input: input - - $.on input, 'blur', QR.focusout - $.on input, 'focus', QR.focusin - $.on input, 'keydown', QR.captcha.keydown.bind QR.captcha - # 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.img.parentNode, 'click', QR.captcha.reload.bind QR.captcha - - $.addClass QR.nodes.el, 'has-captcha', 'captcha-v1' - $.after QR.nodes.com.parentNode, [imgContainer, input] - - Captcha.cache.init() - $.on d, 'CaptchaCount', @count.bind(@) - - @script = $.el 'script', - src: '//www.google.com/recaptcha/api/js/recaptcha_ajax.js' - $.add d.head, @script - - container = $.el 'div', - id: 'captchaContainerAlt' - hidden: true - $.add d.body, container - - @beforeSetup() - @setup() if Conf['Auto-load captcha'] - new MutationObserver(@afterSetup).observe container, childList: true - @afterSetup() # reCAPTCHA might have loaded before the QR. - - create: -> - cont = $.id 'captchaContainerAlt' - return if @occupied - - @occupied = true - - if (lang = Conf['captchaLanguage'].trim()) - cont.dataset.lang = lang - - $.onExists cont, '#recaptcha_image', (image) -> - $.on image, 'click', -> - if $.id 'recaptcha_challenge_image' - $.global -> window.Recaptcha.reload() - $.onExists cont, '#recaptcha_response_field', (field) -> - $.on field, 'keydown', (e) -> - if e.keyCode is 8 and not field.value - $.global -> window.Recaptcha.reload() - (field.focus() if location.hostname is 'sys.4chan.org') - - $.global -> - container = document.getElementById 'captchaContainerAlt' - options = - theme: 'clean' - lang: container.dataset.lang - if window.Recaptcha - window.Recaptcha.create '<%= meta.recaptchaKey %>', container, options - else - script = document.head.querySelector 'script[src="//www.google.com/recaptcha/api/js/recaptcha_ajax.js"]' - script.addEventListener 'load', -> - window.Recaptcha.create '<%= meta.recaptchaKey %>', container, options - , false - - cb: - focus: -> QR.captcha.setup false, true - - beforeSetup: -> - {img, input} = @nodes - img.parentNode.hidden = true - img.src = @blank - 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()) - @create() - if focus - $.addClass QR.nodes.el, 'focus' - @nodes.input.focus() - - afterSetup: -> - return if not (challenge = $.id 'recaptcha_challenge_field_holder') - return if challenge is QR.captcha.nodes.challenge - - setLifetime = (e) -> QR.captcha.lifetime = e.detail - $.on window, 'captcha:timeout', setLifetime - $.global -> window.dispatchEvent new CustomEvent 'captcha:timeout', {detail: window.RecaptchaState.timeout} - $.off window, 'captcha:timeout', setLifetime - - {img, input} = QR.captcha.nodes - img.parentNode.hidden = false - input.placeholder = 'Verification' - QR.captcha.count() - $.off input, 'focus click', QR.captcha.cb.focus - - QR.captcha.nodes.challenge = challenge - new MutationObserver(QR.captcha.load.bind QR.captcha).observe challenge, - childList: true - subtree: true - attributes: true - QR.captcha.load() - - if QR.nodes.el.getBoundingClientRect().bottom > doc.clientHeight - QR.nodes.el.style.top = '' - QR.nodes.el.style.bottom = '0px' - - destroy: -> - return unless @script - $.global -> window.Recaptcha.destroy() - delete @occupied - @beforeSetup() if @nodes - - getOne: (isReply) -> - if (captcha = Captcha.cache.getOne isReply) - captcha - else - challenge = @nodes.img.alt - timeout = @timeout - if /\S/.test(response = @nodes.input.value) - @destroy() - {challenge, response, timeout} - else - null - - save: -> - return unless /\S/.test(response = @nodes.input.value) - @nodes.input.value = '' - Captcha.cache.save - challenge: @nodes.img.alt - response: response - timeout: @timeout - @destroy() - @setup false, true - - load: -> - if $('#captchaContainerAlt[class~="recaptcha_is_showing_audio"]') - @nodes.img.src = @blank - return - return unless @nodes.challenge.firstChild - return if not (challenge_image = $.id 'recaptcha_challenge_image') - # -1 minute to give upload some time. - @timeout = Date.now() + @lifetime * $.SECOND - $.MINUTE - challenge = @nodes.challenge.firstChild.value - @nodes.img.alt = challenge - @nodes.img.src = challenge_image.src - @nodes.input.value = '' - - 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. - - reload: (focus) -> - # Recaptcha.should_focus = false: Hack to prevent the input from being focused - $.global -> - if window.Recaptcha.type is 'image' - window.Recaptcha.reload() - else - window.Recaptcha.switch_type 'image' - window.Recaptcha.should_focus = false - @nodes.input.focus() if focus - - keydown: (e) -> - if e.keyCode is 8 and not @nodes.input.value - @reload() - else if e.keyCode is 13 and e.shiftKey - @save() - else - return - e.preventDefault() diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee index fa3830119..69395fc76 100644 --- a/src/Posting/QR.coffee +++ b/src/Posting/QR.coffee @@ -28,14 +28,7 @@ QR = 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 or location.protocol is 'https:') - noscript = location.protocol is 'https:' and (Conf['Force Noscript Captcha for v1'] or not Main.jsEnabled) - # XXX Frames not yet supported in GM4. - noscript = false if (info = GM?.info) and info.scriptHandler is 'Greasemonkey' and /^4\./.test(info.version) - if noscript then 'noscript' else 'v1' - else - 'v2' - @captcha = Captcha[version] + @captcha = Captcha.v2 $.on d, '4chanXInitFinished', -> BoardConfig.ready QR.initReady diff --git a/src/css/style.css b/src/css/style.css index 2c0920fdb..602f233b3 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -1653,23 +1653,6 @@ input.field.tripped:not(:hover):not(:focus) { top: 2px; } -/* Recaptcha v1 */ -.captcha-img { - margin: 0px; - text-align: center; - background-image: #fff; - font-size: 0px; - min-height: 59px; - min-width: 302px; -} -.captcha-input { - width: 100%; - margin: 1px 0 0; -} -#qr.captcha-v1 #qr-captcha-iframe { - display: none; -} - /* Recaptcha v2 */ #qr .captcha-root { position: relative; diff --git a/src/main/Main.coffee b/src/main/Main.coffee index 532201a63..37c812e87 100644 --- a/src/main/Main.coffee +++ b/src/main/Main.coffee @@ -12,9 +12,6 @@ Main = w['<%= meta.name %> antidup'] = true 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}) -> if enabled $.ready -> Captcha.fixes.init()