service-captcha-gui/exmplate/script.js
Leonid Nikitin 4bac5c10a0
Adjust style.css path.
Adjusted the path to style.css to be dynamically set using 'data-static-path' attribute. This change allows stylesheets to be fetched from the correct path based on the consumed API.
2023-12-02 01:44:21 +06:00

204 lines
9.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(function (document) {
const captchaBlocks = document.querySelectorAll('div.captcha-service-kor-elf');
captchaBlocks.forEach(function (element) {
const shadow = element.attachShadow({ mode: 'closed' });
const button = document.createElement("button");
const style = document.createElement('link');
const domain = element.getAttribute('data-domain');
const token = element.getAttribute('data-token');
const staticPath = element.getAttribute('data-static-path');
let windowCaptcha = null;
style.rel = 'stylesheet';
style.type = 'text/css';
style.href = staticPath + '/style.css';
shadow.appendChild(style);
button.textContent = 'Я не робот!';
button.type = 'button';
button.classList.add('button-open-window-captcha');
shadow.appendChild(button);
button.addEventListener('click', function () {
if (windowCaptcha === null) {
windowCaptcha = createWindowCaptcha(shadow, domain, token);
}
windowCaptcha.style.display = 'block';
actionGetCaptcha(windowCaptcha, domain, token, shadow);
});
});
function createWindowCaptcha (shadow, domain, token) {
const windowCaptcha = document.createElement('div');
windowCaptcha.classList.add('window-captcha');
windowCaptcha.innerHTML = `<div class="window-captcha__content">
<div class="window-captcha__content__header">Я не робот! <button type="button" class="window-captcha__reload"></button><button type="button" class="window-captcha__close">X</button></div>
<div class="window-captcha__content__body"></div>
</div>`;
shadow.appendChild(windowCaptcha);
windowCaptcha.addEventListener('click', function (event) {
if (event.target !== windowCaptcha) {
return null;
}
actionClose(windowCaptcha);
});
windowCaptcha.querySelector('button.window-captcha__close').addEventListener('click', function () {
actionClose(windowCaptcha);
});
windowCaptcha.querySelector('button.window-captcha__reload').addEventListener('click', function () {
actionGetCaptcha(windowCaptcha, domain, token, shadow);
});
return windowCaptcha;
}
function actionClose(windowCaptcha)
{
windowCaptcha.style.display = 'none';
}
function actionGetCaptcha(windowCaptcha, domain, token, shadow)
{
let bodyBlock = windowCaptcha.querySelector('div.window-captcha__content__body');
if (bodyBlock.querySelectorAll('.loading').length > 0) {
return null;
}
bodyBlock.innerHTML = '<div class="loading"></div>';
fetch(domain + '/api/v1/captcha', {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'public-token': token
}
})
.then(response => response.json())
.then(function (data) {
let originalWidth = data.image_body.width;
let originalHeight = data.image_body.height;
bodyBlock.innerHTML = `
<form method="post">
<div class="window-captcha__content__body__head"><img src="${ data.image_head.base64 }" width="100%"></div>
<p>Выберите значение в том порядке, на котором на картинке выше:</p>
<div class="window-captcha__content__body__coordinator"><img src="${ data.image_body.base64 }" width="100%" /></div>
<input type="hidden" name="captcha_key" class="captcha_key" value="${ data.captcha_key }" />
<button type="button" class="window-captcha__content__body__button">Я не робот!</button>
</form>
`;
let blockCoordinator = bodyBlock.querySelector('div.window-captcha__content__body__coordinator');
let blockCoordinatorImg = blockCoordinator.querySelector('img');
blockCoordinatorImg.addEventListener('click', function (event) {
let pointer = document.createElement('div');
pointer.style.left = ( event.offsetX / blockCoordinatorImg.width * 100 ) + '%';
pointer.style.top = ( event.offsetY / blockCoordinatorImg.height * 100 ) + '%';
pointer.classList.add('pointer');
let coordinatorX = event.offsetX * (originalWidth / blockCoordinatorImg.width)
let coordinatorY = event.offsetY * (originalHeight / blockCoordinatorImg.height)
let pointerNumber = blockCoordinator.querySelectorAll('.pointer').length + 1
pointer.innerHTML = `
<span class="pounter__number">${ pointerNumber }</span>
<input type="hidden" class="x" name="pointer[][x]" value="${ Math.round(coordinatorX) }" />
<input type="hidden" class="y" name="pointer[][y]" value="${ Math.round(coordinatorY) }" />
`;
pointer.addEventListener('click', function () {
pointer.remove();
blockCoordinator.querySelectorAll('.pointer').forEach(function (elementPointer, pointIndex) {
elementPointer.querySelector('span.pounter__number').textContent = pointIndex + 1;
});
});
blockCoordinator.appendChild(pointer);
});
bodyBlock.querySelector('.window-captcha__content__body__button').addEventListener('click', function () {
checkingCaptcha(bodyBlock, domain, token, shadow);
});
})
.catch(error => {
bodyBlock.innerHTML = `<div class="window-captcha__content__body__error">Произошла ошибка, сервис с каптчей не ответил. Попробуйте ещё раз!</div>`;
});
}
function checkingCaptcha (bodyBlock, domain, token, shadow) {
let button = bodyBlock.querySelector('button.window-captcha__content__body__button');
if (button.querySelectorAll('.loading').length > 0) {
return null;
}
let loadingSpan = document.createElement('span');
loadingSpan.classList.add('loading');
button.appendChild(loadingSpan);
let data = {
captcha_key: bodyBlock.querySelector('.captcha_key').value,
verification: []
};
bodyBlock.querySelectorAll('.pointer').forEach(function (elementPointer) {
data["verification"].push({
x: elementPointer.querySelector('.x').value,
y: elementPointer.querySelector('.y').value
});
});
fetch(domain + '/api/v1/captcha', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'public-token': token
},
body: JSON.stringify(data)
})
.then(response => {
if (response.status === 429) {
setError('Вы превысили количество попыток. Обновите каптчу.', button);
return
}
return response.json();
})
.then(function (data) {
if (typeof data.errors !== 'undefined') {
let errorMessage = '';
for (let key in data.errors) {
errorMessage += data.errors[key] + '<br>';
}
if (errorMessage === '') {
errorMessage = data.message;
}
setError(errorMessage, button);
return
}
if (typeof data.captcha_key === 'undefined') {
setError('Произошла ошибка!', button);
return
}
shadow.querySelector('button.button-open-window-captcha').remove();
let captchaVerified = document.createElement('div');
captchaVerified.innerHTML = `<span class="captcha-verified">Ура!!! Проверку прошли!</span><input type="hidden" name="captcha-verified" value="${ data.captcha_key }">`;
shadow.appendChild(captchaVerified);
shadow.querySelector('.window-captcha').remove();
})
.catch(error => {
setError('Произошла ошибка!', button)
}).finally(function () {
loadingSpan.remove();
});
}
function setError(message, button) {
let errorBlock = document.createElement('div');
errorBlock.classList.add("error-message");
errorBlock.innerHTML = message;
button.before(errorBlock);
setTimeout( function () {
errorBlock.remove();
}, 3000);
}
})(document);