diff --git a/gulp/res/css/nscaptcha.css b/gulp/res/css/nscaptcha.css index 32b5ec72..e2ae343f 100644 --- a/gulp/res/css/nscaptcha.css +++ b/gulp/res/css/nscaptcha.css @@ -1,19 +1,21 @@ img { - width:200px; - height:80px; - margin:0 auto; + width: 200px; + height: 80px; + margin: 0 auto; } input { - position:fixed; - left:-1px; - bottom:-1px; - opacity:0.9; + position: fixed; + left: -3px; + bottom: 0; + opacity: 0.9; border: none; background: none; + font-size: 18px; + cursor: pointer; } body { font-family: arial, helvetica, sans-serif; font-size: 10pt; margin: 0; - padding: 0 + padding: 0; } diff --git a/gulp/res/css/style.css b/gulp/res/css/style.css index 2821d31b..fe99297d 100644 --- a/gulp/res/css/style.css +++ b/gulp/res/css/style.css @@ -844,13 +844,13 @@ input:invalid, textarea:invalid { line-height: 3em; } -.button { +a.button { -webkit-appearance: button; -moz-appearance: button; appearance: button; text-decoration: none; cursor: pointer; - color: initial; + color: black; } .button:hover { @@ -929,7 +929,7 @@ iframe.captcha, iframe.bypass { } iframe.bypass { - height: 215px; + height: 235px; width: 330px; } @@ -943,6 +943,14 @@ iframe.bypass { overflow: hidden; } +.captcharefresh { + position: absolute; + bottom: 0; + left: 5px; + font-size: 18px; + cursor: pointer; +} + .label, .rlabel { padding: 3px; border: 1px solid var(--box-border-color); diff --git a/gulp/res/js/captcha.js b/gulp/res/js/captcha.js index bd3c6909..cd6fa5be 100644 --- a/gulp/res/js/captcha.js +++ b/gulp/res/js/captcha.js @@ -33,14 +33,18 @@ window.addEventListener('DOMContentLoaded', (event) => { const loadCaptcha = function(e) { const captchaDiv = this.previousSibling; const captchaImg = document.createElement('img'); + const refreshDiv = document.createElement('div'); + refreshDiv.classList.add('captcharefresh', 'noselect'); + refreshDiv.addEventListener('click', refreshCaptchas, true); + refreshDiv.textContent = '↻'; const field = this; field.placeholder = 'loading'; captchaImg.src = '/captcha'; captchaImg.onload = function() { - field.placeholder = 'double click image to refresh'; + field.placeholder = ''; captchaDiv.appendChild(captchaImg); + captchaDiv.appendChild(refreshDiv); captchaDiv.style.display = ''; - captchaImg.addEventListener('dblclick', refreshCaptchas, true); } }; diff --git a/helpers/captcha/captchaverify.js b/helpers/captcha/captchaverify.js index f6f17421..4c215aa3 100644 --- a/helpers/captcha/captchaverify.js +++ b/helpers/captcha/captchaverify.js @@ -8,6 +8,8 @@ const { Captchas, Ratelimits } = require(__dirname+'/../../db/') module.exports = async (req, res, next) => { + const isBypass = req.path === '/blockbypass'; + //skip captcha if disabled on board for posts only if (res.locals.board && req.path === `/board/${res.locals.board._id}/post`) { @@ -20,6 +22,12 @@ module.exports = async (req, res, next) => { //check if captcha field in form is valid const input = req.body.captcha; if (!input || input.length !== 6) { + if (isBypass) { + return res.status(403).render('bypass', { + 'minimal': req.body.minimal, + 'message': 'Incorrect captcha', + }); + } return dynamicResponse(req, res, 403, 'message', { 'title': 'Forbidden', 'message': 'Incorrect captcha', @@ -30,6 +38,12 @@ module.exports = async (req, res, next) => { //make sure they have captcha cookie and its 24 chars const captchaId = req.cookies.captchaid; if (!captchaId || captchaId.length !== 24) { + if (isBypass) { + return res.status(403).render('bypass', { + 'minimal': req.body.minimal, + 'message': 'Captcha expired', + }); + } return dynamicResponse(req, res, 403, 'message', { 'title': 'Forbidden', 'message': 'Captcha expired', @@ -48,6 +62,12 @@ module.exports = async (req, res, next) => { //check that it exists and matches captcha in DB if (!captcha || !captcha.value || captcha.value.text !== input) { + if (isBypass) { + return res.status(403).render('bypass', { + 'minimal': req.body.minimal, + 'message': 'Incorrect captcha', + }); + } return dynamicResponse(req, res, 403, 'message', { 'title': 'Forbidden', 'message': 'Incorrect captcha', diff --git a/helpers/timediffstring.js b/helpers/timediffstring.js index d68fa7c6..cbdc4030 100644 --- a/helpers/timediffstring.js +++ b/helpers/timediffstring.js @@ -1,5 +1,5 @@ 'use strict'; module.exports = (label, end) => { - return `${label} -> ${end[0] > 0 ? end[0]+'s ' : ''}${(end[1]/1000000).toFixed(2)}ms`; + return (`${end[0] > 0 ? end[0]+'s' : ''}${Math.trunc(end[1]/1000000)}ms `).padStart(9) + label; } diff --git a/views/pages/bypass.pug b/views/pages/bypass.pug index 74ebec0b..450aa4f7 100644 --- a/views/pages/bypass.pug +++ b/views/pages/bypass.pug @@ -6,6 +6,8 @@ block head block content h1.board-title Block Bypass .form-wrapper.flex-center.mv-10 + if message + p.title #{message} form.form-post(action='/forms/blockbypass' method='POST') .row .label Captcha