mirror of https://gitgud.io/fatchan/jschan.git
captcha added to page when missing (enabled after page load) and cleaned captcha handling closes #189
parent
9f47b05f0d
commit
21191a3811
7 changed files with 83 additions and 40 deletions
@ -1,60 +1,83 @@ |
||||
window.addEventListener('DOMContentLoaded', (event) => { |
||||
class CaptchaController { |
||||
|
||||
const captchaFields = document.getElementsByClassName('captchafield'); |
||||
let refreshing = false; |
||||
constructor() { |
||||
this.captchaFields = []; |
||||
this.refreshing = false; |
||||
} |
||||
|
||||
const updateCaptchaImages = (url) => { |
||||
for (let i = 0; i < captchaFields.length; i++) { |
||||
if (captchaFields[i].previousSibling.children.length > 0) { |
||||
captchaFields[i].previousSibling.children[0].src = url; |
||||
} |
||||
init() { |
||||
this.captchaFields = document.getElementsByClassName('captchafield'); |
||||
this.refreshing = false; |
||||
for (let captcha of this.captchaFields) { |
||||
this.setupCaptchaField(captcha); |
||||
} |
||||
} |
||||
|
||||
setupCaptchaField(captcha) { |
||||
if (captcha.form.dataset.captchaPreload == 'true') { |
||||
this.loadCaptcha(captcha); |
||||
} else { |
||||
captcha.placeholder = 'focus to load captcha'; |
||||
captcha.addEventListener('focus', () => this.loadCaptcha(captcha), { once: true }); |
||||
} |
||||
}; |
||||
} |
||||
|
||||
const refreshCaptchas = function(e) { |
||||
if (refreshing) { |
||||
return; |
||||
refreshCaptchas() { |
||||
if (this.refreshing) { |
||||
return null; |
||||
} |
||||
refreshing = true; |
||||
this.refreshing = true; |
||||
document.cookie = 'captchaid=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;'; |
||||
const captchaImg = this; |
||||
const xhr = new XMLHttpRequest(); |
||||
xhr.onload = () => { |
||||
refreshing = false; |
||||
updateCaptchaImages(xhr.responseURL); |
||||
for (let captcha of this.captchaFields) { |
||||
const existingImage = captcha.previousSibling.children[0]; |
||||
if (existingImage) { |
||||
captcha.previousSibling.children[0].src = xhr.responseURL; |
||||
} |
||||
} |
||||
this.refreshing = false; |
||||
} |
||||
xhr.onerror = () => { |
||||
refreshing = false; |
||||
this.refreshing = false; |
||||
} |
||||
xhr.open('GET', '/captcha', true); |
||||
xhr.send(null); |
||||
}; |
||||
} |
||||
|
||||
const loadCaptcha = function(e) { |
||||
const field = e.target; |
||||
addMissingCaptcha() { |
||||
const postSubmitButton = document.getElementById('submitpost'); |
||||
const captchaFormSectionHtml = captchaformsection(); |
||||
postSubmitButton.insertAdjacentHTML('beforebegin', captchaFormSectionHtml); |
||||
const captchaFormSection = postSubmitButton.previousSibling; |
||||
const captchaField = captchaFormSection.querySelector('.captchafield'); |
||||
this.loadCaptcha(captchaField); |
||||
} |
||||
|
||||
loadCaptcha(field) { |
||||
console.log(field) |
||||
const captchaDiv = field.previousSibling; |
||||
const captchaImg = document.createElement('img'); |
||||
const refreshDiv = document.createElement('div'); |
||||
refreshDiv.classList.add('captcharefresh', 'noselect'); |
||||
refreshDiv.addEventListener('click', refreshCaptchas, true); |
||||
refreshDiv.addEventListener('click', () => this.refreshCaptchas(), true); |
||||
refreshDiv.textContent = '↻'; |
||||
field.placeholder = 'loading'; |
||||
captchaImg.src = '/captcha'; |
||||
captchaImg.onload = function() { |
||||
field.placeholder = ''; |
||||
captchaDiv.appendChild(captchaImg); |
||||
captchaDiv.appendChild(refreshDiv); |
||||
captchaDiv.style.display = ''; |
||||
} |
||||
}; |
||||
|
||||
for (let i = 0; i < captchaFields.length; i++) { |
||||
const field = captchaFields[i]; |
||||
if (field.form.action.endsWith('/forms/blockbypass')) { |
||||
return loadCaptcha({target: field }) |
||||
field.placeholder = ''; |
||||
captchaDiv.appendChild(captchaImg); |
||||
captchaDiv.appendChild(refreshDiv); |
||||
captchaDiv.style.display = ''; |
||||
} |
||||
field.placeholder = 'focus to load captcha'; |
||||
field.addEventListener('focus', loadCaptcha, { once: true }); |
||||
} |
||||
|
||||
} |
||||
|
||||
const captchaController = new CaptchaController(); |
||||
|
||||
window.addEventListener('DOMContentLoaded', () => { |
||||
|
||||
captchaController.init(); |
||||
|
||||
}); |
||||
|
@ -0,0 +1,7 @@ |
||||
function pug_attr(t,e,n,r){if(!1===e||null==e||!e&&("class"===t||"style"===t))return"";if(!0===e)return" "+(r?t:t+'="'+t+'"');var f=typeof e;return"object"!==f&&"function"!==f||"function"!=typeof e.toJSON||(e=e.toJSON()),"string"==typeof e||(e=JSON.stringify(e),n||-1===e.indexOf('"'))?(n&&(e=pug_escape(e))," "+t+'="'+e+'"'):" "+t+"='"+e.replace(/'/g,"'")+"'"} |
||||
function pug_escape(e){var a=""+e,t=pug_match_html.exec(a);if(!t)return e;var r,c,n,s="";for(r=t.index,c=0;r<a.length;r++){switch(a.charCodeAt(r)){case 34:n=""";break;case 38:n="&";break;case 60:n="<";break;case 62:n=">";break;default:continue}c!==r&&(s+=a.substring(c,r)),c=r+1,s+=n}return c!==r?s+a.substring(c,r):s} |
||||
var pug_match_html=/["&<>]/;function captchaformsection(locals) {var pug_html = "", pug_mixins = {}, pug_interp;pug_mixins["captchaformsection"] = pug_interp = function(){ |
||||
var block = (this && this.block), attributes = (this && this.attributes) || {}; |
||||
pug_html = pug_html + "\u003Csection class=\"row\"\u003E\u003Cdiv class=\"label\"\u003E\u003Cspan\u003ECaptcha\u003Cspan class=\"required\"\u003E*\u003C\u002Fspan\u003E\u003C\u002Fspan\u003E\u003C\u002Fdiv\u003E\u003Cdiv class=\"col\"\u003E\u003Cnoscript class=\"no-m-p\"\u003E\u003Ciframe" + (" class=\"captcha\""+" src=\"\u002Fcaptcha.html\""+pug_attr("width=210", true, true, false)+" height=\"80\" scrolling=\"no\" loading=\"lazy\"") + "\u003E\u003C\u002Fiframe\u003E\u003C\u002Fnoscript\u003E\u003Cdiv class=\"jsonly captcha\" style=\"display:none;\"\u003E\u003C\u002Fdiv\u003E\u003Cinput" + (" class=\"captchafield\""+" type=\"text\" name=\"captcha\" autocomplete=\"off\" placeholder=\"Captcha text\" pattern=\".{6}\""+pug_attr("required", true, true, false)+" title=\"6 characters\"") + "\u002F\u003E\u003C\u002Fdiv\u003E\u003C\u002Fsection\u003E"; |
||||
}; |
||||
pug_mixins["captchaformsection"]();;return pug_html;} |
@ -0,0 +1,2 @@ |
||||
include ../mixins/captchaformsection.pug |
||||
+captchaformsection() |
@ -0,0 +1,7 @@ |
||||
mixin captchaformsection() |
||||
section.row |
||||
.label |
||||
span Captcha |
||||
span.required * |
||||
.col |
||||
include ../includes/captcha.pug |
Loading…
Reference in new issue