diff --git a/Gruntfile.coffee b/Gruntfile.coffee index 43a8425db..f11582ef9 100755 --- a/Gruntfile.coffee +++ b/Gruntfile.coffee @@ -61,7 +61,6 @@ module.exports = (grunt) -> 'src/Filtering/**/*.coffee' 'src/Quotelinks/**/*.coffee' 'src/Posting/QR.coffee' - 'src/Posting/Captcha.coffee' 'src/Posting/**/*.coffee' 'src/Images/**/*.coffee' 'src/Linkification/**/*.coffee' diff --git a/src/General/Config.coffee b/src/General/Config.coffee index ed0a784a1..36d913beb 100755 --- a/src/General/Config.coffee +++ b/src/General/Config.coffee @@ -371,10 +371,6 @@ Config = true 'Show notifications on successful post creation or file uploading.' ] - 'Use Recaptcha v1': [ - false - 'Use the old version of Recaptcha before the introduction of the checkbox.' - ] 'Captcha Warning Notifications': [ true 'When disabled, shows a red border on the CAPTCHA input until a key is pressed instead of a notification.' diff --git a/src/General/css/style.css b/src/General/css/style.css index 792bd3a70..c0d90b3cd 100755 --- a/src/General/css/style.css +++ b/src/General/css/style.css @@ -10,7 +10,6 @@ #thread-watcher { box-shadow: -1px 2px 2px rgba(0, 0, 0, 0.25); } -.captcha-img, .field { background-color: #FFF; border: 1px solid #CCC; @@ -28,7 +27,6 @@ font-size: 13px !important; opacity: 1.0 !important; } -.captch-img:hover, .field:hover { border-color: #999; } @@ -971,8 +969,7 @@ span.hide-announcement { #qr select, #dump-button, #url-button, -.remove, -.captcha-img { +.remove { cursor: pointer; } #qr { @@ -1065,23 +1062,6 @@ input.field.tripped:not(:hover):not(:focus) { #qr textarea { resize: both; } -/* 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; -} -.captcha-input.error:focus { - border-color: rgb(255,0,0) !important; -} -/* Recaptcha v2 */ #qr .captcha-root { position: relative; } diff --git a/src/Posting/Captcha.coffee b/src/Posting/Captcha.coffee deleted file mode 100644 index 5bcab40bb..000000000 --- a/src/Posting/Captcha.coffee +++ /dev/null @@ -1 +0,0 @@ -Captcha = {} diff --git a/src/Posting/Captcha.v1.coffee b/src/Posting/Captcha.v1.coffee deleted file mode 100644 index fa9822543..000000000 --- a/src/Posting/Captcha.v1.coffee +++ /dev/null @@ -1,176 +0,0 @@ -Captcha.v1 = - init: -> - return if d.cookie.indexOf('pass_enabled=1') >= 0 - return unless @isEnabled = !!$.id 'g-recaptcha' - - script = $.el 'script', - src: '//www.google.com/recaptcha/api/js/recaptcha_ajax.js' - $.add d.head, script - captchaContainer = $.el 'div', - id: 'captchaContainer' - hidden: true - $.add d.body, captchaContainer - - @setup() if Conf['Auto-load captcha'] - - 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 - $.on @nodes.img.parentNode, 'click', QR.captcha.reload.bind QR.captcha - - $.addClass QR.nodes.el, 'has-captcha' - $.after QR.nodes.com.parentNode, [imgContainer, input] - - @captchas = [] - $.get 'captchas', [], ({captchas}) -> - QR.captcha.sync captchas - QR.captcha.clear() - $.sync 'captchas', @sync - - new MutationObserver(@afterSetup).observe $.id('captchaContainer'), childList: true - - @beforeSetup() - @afterSetup() # reCAPTCHA might have loaded before the QR. - beforeSetup: -> - {img, input} = @nodes - img.parentNode.hidden = true - input.value = '' - input.placeholder = 'Focus to load reCAPTCHA' - @count() - $.on input, 'focus', @setup - setup: -> - $.globalEval ''' - (function() { - var captchaContainer = document.getElementById("captchaContainer"); - if (captchaContainer.firstChild) return; - function setup() { - if (window.Recaptcha) { - Recaptcha.create(recaptchaKey, captchaContainer, {theme: "clean"}); - } else { - setTimeout(setup, 25); - } - } - setup(); - })() - ''' - afterSetup: -> - return unless 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 - $.globalEval 'window.dispatchEvent(new CustomEvent("captcha:timeout", {detail: 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', QR.captcha.setup - - 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 = null - QR.nodes.el.style.bottom = '0px' - destroy: -> - $.globalEval 'Recaptcha.destroy()' - @beforeSetup() - - sync: (captchas) -> - QR.captcha.captchas = captchas - QR.captcha.count() - - getOne: -> - @clear() - if captcha = @captchas.shift() - {challenge, response} = captcha - @count() - $.set 'captchas', @captchas - else - challenge = @nodes.img.alt - if response = @nodes.input.value - if Conf['Auto-load captcha'] then @reload() else @destroy() - # Duplicate one-word captchas. - # Don't duplicate street numbers for now (needs testing). - if response and !/\s|^\d$/.test response - response = "#{response} #{response}" - {challenge, response} - - save: -> - return unless /\S/.test(response = @nodes.input.value) - @nodes.input.value = '' - @captchas.push - challenge: @nodes.img.alt - response: response - timeout: @timeout - @count() - @reload() - $.set 'captchas', @captchas - - clear: -> - return unless @captchas.length - now = Date.now() - for captcha, i in @captchas - break if captcha.timeout > now - return unless i - @captchas = @captchas[i..] - @count() - $.set 'captchas', @captchas - - load: -> - return unless @nodes.challenge.firstChild - return unless 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 = null - @clear() - - count: -> - count = if @captchas then @captchas.length else 0 - 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) -> - # Hack to prevent the input from being focused - $.globalEval 'Recaptcha.reload(); Recaptcha.should_focus = false;' - # Focus if we meant to. - @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/Captcha.v2.coffee b/src/Posting/QR.captcha.coffee similarity index 98% rename from src/Posting/Captcha.v2.coffee rename to src/Posting/QR.captcha.coffee index a66cccd14..4135efc26 100644 --- a/src/Posting/Captcha.v2.coffee +++ b/src/Posting/QR.captcha.coffee @@ -1,4 +1,4 @@ -Captcha.v2 = +QR.captcha = init: -> return if d.cookie.indexOf('pass_enabled=1') >= 0 return unless @isEnabled = !!$.id 'g-recaptcha' @@ -117,9 +117,9 @@ Captcha.v2 = if captcha = @captchas.shift() @count() $.set 'captchas', @captchas - {response: captcha.response} + captcha.response else - {} + null save: (pasted) -> reload = QR.cooldown.auto and @needed() diff --git a/src/Posting/QR.coffee b/src/Posting/QR.coffee index efdfaa3d1..88cf9865e 100644 --- a/src/Posting/QR.coffee +++ b/src/Posting/QR.coffee @@ -7,8 +7,6 @@ QR = @db = new DataBoard 'yourPosts' @posts = [] - @captcha = Captcha[if Conf['Use Recaptcha v1'] then 'v1' else 'v2'] - if Conf['QR Shortcut'] sc = $.el 'a', className: "qr-shortcut fa fa-comment-o #{unless Conf['Persistent QR'] then 'disabled' else ''}" @@ -97,7 +95,7 @@ QR = if QR.nodes QR.nodes.el.hidden = false QR.unhide() - QR.captcha.setup() unless Conf['Use Recaptcha v1'] + QR.captcha.setup() return try QR.dialog() @@ -114,8 +112,6 @@ QR = QR.cleanNotifications() d.activeElement.blur() $.rmClass QR.nodes.el, 'dump' - if Conf['Use Recaptcha v1'] and !Conf['Captcha Warning Notifications'] - $.rmClass QR.captcha.nodes.input, 'error' if QR.captcha.isEnabled if Conf['QR Shortcut'] $.toggleClass $('.qr-shortcut'), 'disabled' new QR.post true @@ -123,8 +119,7 @@ QR = post.delete() QR.cooldown.auto = false QR.status() - if !Conf['Use Recaptcha v1'] or (QR.captcha.isEnabled and not Conf['Auto-load captcha']) - QR.captcha.destroy() + QR.captcha.destroy() focusin: -> $.addClass QR.nodes.el, 'focus' focusout: -> @@ -149,21 +144,9 @@ QR = else el = err el.removeAttribute 'style' - captchaErr = QR.captcha.isEnabled and /captcha|verification/i.test el.textContent - if captchaErr and Conf['Use Recaptcha v1'] - if QR.captcha.captchas.length is 0 - # Focus the captcha input on captcha error. - QR.captcha.nodes.input.focus() - QR.captcha.setup() - if Conf['Captcha Warning Notifications'] and !d.hidden - QR.notify el - else - $.addClass QR.captcha.nodes.input, 'error' - $.on QR.captcha.nodes.input, 'keydown', -> - $.rmClass QR.captcha.nodes.input, 'error' - else - QR.captcha.setup true if captchaErr and !Conf['Use Recaptcha v1'] - QR.notify el + if QR.captcha.isEnabled and /captcha|verification/i.test el.textContent + QR.captcha.setup true + QR.notify el alert el.textContent if d.hidden notify: (el) -> @@ -566,7 +549,7 @@ QR = QR.cooldown.init() QR.captcha.init() $.add d.body, dialog - QR.captcha.setup() unless Conf['Use Recaptcha v1'] + QR.captcha.setup() # Create a custom event when the QR dialog is first initialized. # Use it to extend the QR's functionalities, or for XTRM RICE. @@ -657,7 +640,7 @@ QR = err = 'Max limit of image replies has been reached.' if QR.captcha.isEnabled and !err - {challenge, response} = QR.captcha.getOne() + response = QR.captcha.getOne() err = 'No valid captcha.' unless response QR.cleanNotifications() @@ -691,7 +674,6 @@ QR = textonly: textOnly mode: 'regist' pwd: QR.persona.pwd - recaptcha_challenge_field: challenge 'g-recaptcha-response': response options = @@ -821,7 +803,6 @@ QR = icon: Favicon.logo notif.onclick = -> QR.open() - QR.captcha.nodes.input.focus() if Conf['Use Recaptcha v1'] window.focus() notif.onshow = -> setTimeout -> @@ -831,10 +812,8 @@ QR = unless Conf['Persistent QR'] or postsCount QR.close() else - if Conf['Use Recaptcha v1'] and QR.posts.length > 1 and QR.captcha.isEnabled and QR.captcha.captchas.length is 0 - QR.captcha.setup() post.rm() - QR.captcha.setup true unless Conf['Use Recaptcha v1'] + QR.captcha.setup true QR.cooldown.add req.uploadEndTime, threadID, postID diff --git a/src/Posting/QR.post.coffee b/src/Posting/QR.post.coffee index 91c7dc115..ef7a4da22 100644 --- a/src/Posting/QR.post.coffee +++ b/src/Posting/QR.post.coffee @@ -70,7 +70,7 @@ QR.post = class @select() if select @unlock() # Post count temporarily off by 1 when called from QR.post.rm - $.queueTask -> QR.captcha.setup() unless Conf['Use Recaptcha v1'] + $.queueTask -> QR.captcha.setup() rm: -> @delete() @@ -133,7 +133,7 @@ QR.post = class QR.status() when 'com' @nodes.span.textContent = @com - QR.captcha.onPostChange() unless Conf['Use Recaptcha v1'] + QR.captcha.onPostChange() QR.characterCount() # Disable auto-posting if you're typing in the first post # during the last 5 seconds of the cooldown. @@ -162,7 +162,7 @@ QR.post = class @filename = file.name @filesize = $.bytesToString file.size @nodes.label.hidden = false if QR.spoiler - QR.captcha.onPostChange() unless Conf['Use Recaptcha v1'] + QR.captcha.onPostChange() URL.revokeObjectURL @URL if @ is QR.selected @showFileData()