UNPKG

@trustcomponent/trustcaptcha-frontend

Version:

TrustCaptcha – Privacy-first CAPTCHA solution. GDPR-compliant, bot protection made in Europe.

140 lines (139 loc) 6.06 kB
import { ApiManager } from "./api/api-manager"; import { Status } from "./status"; import { EventTracker } from "./information-collector/event_tracker"; import { ErrorModel } from "./api/error/error-model"; import { ErrorCode } from "./api/error/error-code"; import { SimpleEventEmitter } from "./simple-event-emitter"; export class CaptchaBox { constructor(config, htmlElement) { this.statusChangedEvent = new SimpleEventEmitter(); this.captchaFinishEvent = new SimpleEventEmitter(); this.status = Status.START; this.boxCreationTimestamp = new Date(); this.eventTracker = new EventTracker(); this.verificationToken = null; this.apiManager = null; this.config = config; this.htmlElement = htmlElement; } setup() { this.formElement = this.htmlElement.closest('form'); if (this.formElement != null) { this.honeypotField = this.createHoneypotField(); this.verificationTokenField = this.createVerificationTokenField(); this.registerElementFocusListeners(); } else { this.setErrorStatus(new ErrorModel(ErrorCode.NO_FORM_FOUND, "No parent form element found.")); } } createHoneypotField() { const honeypotField = document.createElement('input'); honeypotField.setAttribute('type', 'text'); honeypotField.setAttribute('name', this.generateHoneypotName()); honeypotField.setAttribute('style', 'display:none'); honeypotField.setAttribute('tabindex', '-1'); this.formElement.appendChild(honeypotField); return honeypotField; } generateHoneypotName() { const baseNames = [ "userDetail", "confirmAction", "userData", "verifyContact", "sessionInfo", "profileUpdate", "accountVerify", "securityCheck", "membershipInfo", "customerPreference", "siteFeedback", "userExperience", "navigationData", "serviceUsage", "interactionTrack", "clientDetail", "transactionVerify", "operationStatus", "activityLog", "registrationData", "processCheck", "confirmationStatus", "userContribution", "accessValidation", "engagementLevel", "validationCode", "preferenceSetting", "userEngage", "activityConfirm", "serviceInteraction" ]; const randomIndex = Math.floor(Math.random() * baseNames.length); const randomNumber = Math.floor(Math.random() * 1000); return baseNames[randomIndex] + randomNumber; } createVerificationTokenField() { const verificationTokenField = document.createElement('input'); verificationTokenField.setAttribute('type', 'text'); verificationTokenField.setAttribute('name', this.config.tokenFieldName); verificationTokenField.setAttribute('style', 'display:none'); verificationTokenField.setAttribute('tabindex', '-1'); return verificationTokenField; } registerElementFocusListeners() { this.formElement.addEventListener('keydown', (event) => { if (event instanceof KeyboardEvent) { this.autostartVerification(); } }); this.formElement.querySelectorAll('input:not([data-autostart="false"]), select:not([data-autostart="false"]), textarea:not([data-autostart="false"])').forEach(element => { element.addEventListener('focusin', () => { this.autostartVerification(); }); }); } autostartVerification() { if (this.config.autostart) { this.startVerification(); } } startVerification() { if (this.status !== Status.START) { return; } this.switchStatus(Status.RUNNING); this.apiManager = new ApiManager(this, (verificationToken) => { this.eventTracker.stop(); this.finishVerification(verificationToken); this.apiManager = null; }, (reason) => { this.eventTracker.stop(); this.setErrorStatus(reason); this.apiManager = null; }); this.apiManager.verify(); } finishVerification(verificationToken) { const jsonString = JSON.stringify(verificationToken, ['apiEndpoint', 'verificationId', 'encryptedAccessToken']); const base64String = btoa(jsonString); this.verificationToken = base64String; this.verificationTokenField.setAttribute("value", base64String); this.formElement.appendChild(this.verificationTokenField); if (this.timerId) clearTimeout(this.timerId); this.timerId = window.setTimeout(() => this.reset(), Math.max(0, (verificationToken.expiresInMs || 900000) - 30000)); this.handleCaptchaSolved(); } handleCaptchaSolved() { if (this.verificationToken) { this.captchaFinishEvent.emit("captchaSolved", this.verificationToken); this.switchStatus(Status.DONE); } } switchStatus(nextStatus) { this.status = nextStatus; this.statusChangedEvent.emit('statusChanged', nextStatus); } setErrorStatus(errorModel) { this.switchStatus(Status.FAILED); this.captchaFinishEvent.emit("captchaFailed", errorModel); } reset() { if (this.timerId) clearTimeout(this.timerId); if (this.apiManager) { this.apiManager.reset(); this.apiManager = null; } this.honeypotField.removeAttribute("value"); this.verificationToken = null; this.verificationTokenField.removeAttribute("value"); if (this.verificationTokenField && this.formElement.contains(this.verificationTokenField)) { this.formElement.removeChild(this.verificationTokenField); } this.eventTracker.reset(); this.switchStatus(Status.START); this.captchaFinishEvent.emit("captchaReset"); } setNewConfig(config) { this.config = config; } } //# sourceMappingURL=captcha-box.js.map