@humanmark/sdk-js
Version:
Browser-native JavaScript SDK for Humanmark human verification challenges
283 lines (282 loc) • 7.75 kB
JavaScript
import { p as parseChallengeToken, a as HumanmarkChallengeError, E as ErrorCode } from "./index-AC1SXkK1.js";
const PRIMARY_COLORS = {
200: "#C7BDFF",
500: "#7C63FF"
};
const UI_COLORS = {
white: "#FFFFFF"
};
const NAMESPACES = {
/** SVG namespace for creating SVG elements */
SVG: "http://www.w3.org/2000/svg"
};
const ANIMATION_TIMINGS = {
/** Duration for fade out animations in milliseconds */
FADE_OUT: 300,
/** Duration for modal closing animation in milliseconds */
MODAL_CLOSE: 300,
/** Time to display success state before closing in milliseconds */
SUCCESS_DISPLAY: 1500,
/** Delay before clearing screen reader announcements in milliseconds */
ANNOUNCEMENT_CLEAR: 1e3
};
const DIMENSIONS = {
/** Default QR code width in pixels */
QR_CODE_WIDTH: 256,
/** QR code margin in modules */
QR_CODE_MARGIN: 2
};
const COLORS = {
QR_CODE: {
/** Foreground color for QR code - using primary brand color */
DARK: PRIMARY_COLORS[500],
/** Background color for QR code (transparent) */
LIGHT: "#0000",
/** White background option for QR code */
WHITE: UI_COLORS.white,
/** Primary theme colors for inverted QR code */
PRIMARY: PRIMARY_COLORS[500],
PRIMARY_BG: PRIMARY_COLORS[500],
/** Secondary theme color - not used in new design */
SECONDARY: PRIMARY_COLORS[200]
}
};
const MESSAGES = {
VERIFICATION: {
TITLE: "Verify you're human",
DESKTOP_SUBTITLE: "Scan with the Humanmark app",
MOBILE_SUBTITLE: "Tap to verify with Humanmark",
QR_INSTRUCTIONS: "No personal information will be shared",
BUTTON_TEXT: "Verify with Humanmark",
WHAT_IS_THIS: "What's this? →"
},
SUCCESS: {
TITLE: "Verified!",
SUBTITLE: "Returning to the site..."
},
ACCESSIBILITY: {
QR_ALT_TEXT: "Humanmark Verification QR Code",
MODAL_OPENED: "Human verification modal opened. Scan QR code or use the provided button to verify.",
MODAL_CLOSED: "Verification modal closed",
VERIFICATION_SUCCESS: "Human verification successful",
CLOSE_BUTTON_LABEL: "Close verification modal",
PROGRESS_LABEL: "Time remaining for verification",
TIME_NOTICE: "Scan this code with the Humanmark app to verify you're human."
},
ERRORS: {
QR_GENERATION_FAILED: "Failed to generate QR code"
}
};
const CSS_CLASSES = {
MODAL: {
OVERLAY: "humanmark-modal-overlay",
CONTENT: "humanmark-modal-content",
BODY: "humanmark-modal-body",
CLOSING: "humanmark-closing"
},
BUTTONS: {
CLOSE: "humanmark-modal-close",
VERIFY: "humanmark-verify-button"
},
LINKS: {
WHAT_IS_THIS: "humanmark-what-is-this"
},
PROGRESS: {
CONTAINER: "humanmark-progress-container",
BAR: "humanmark-progress-bar",
HIDDEN: "humanmark-hidden"
},
SUCCESS: {
CONTAINER: "humanmark-success-container",
CHECKMARK: "humanmark-success-checkmark",
MESSAGE: "humanmark-success-message",
SUBMESSAGE: "humanmark-success-submessage",
VISIBLE: "humanmark-success-visible"
},
QR_CODE: {
CONTAINER: "humanmark-qr-container",
WRAPPER: "humanmark-qr-wrapper",
IMAGE: "humanmark-qr-image",
INSTRUCTIONS: "humanmark-modal-instructions"
},
MOBILE: {
CONTAINER: "humanmark-mobile-container"
},
TITLE: {
CONTAINER: "humanmark-modal-title",
BRAND: "humanmark-title-brand"
},
SUBTITLE: "humanmark-modal-description",
ACCESSIBILITY: {
SCREEN_READER_ONLY: "humanmark-sr-only"
},
ANIMATIONS: {
FADE_OUT: "humanmark-fade-out"
}
};
const ARIA = {
PROGRESS: {
VALUE_MIN: "0",
VALUE_MAX: "120",
VALUE_NOW: "120"
}
};
const KEYBOARD_KEYS = {
ESCAPE: "Escape",
TAB: "Tab"
};
const URLS = {
VERIFY_BASE: "https://humanmark.app/verify",
WHAT_IS_THIS: "https://humanmark.app"
};
const BROWSER_TARGETS = {
BLANK: "_blank"
};
const ELEMENT_IDS = {
MODAL: "humanmark-verification-modal",
TITLE: "humanmark-modal-title",
DESCRIPTION: "humanmark-modal-description"
};
const SVG_DIMENSIONS = {
VIEWBOX: "0 0 52 52",
CIRCLE: {
CX: "26",
CY: "26",
R: "25"
},
CHECK_PATH: "M14.1 27.2l7.1 7.2 16.7-16.8"
};
const FOCUSABLE_SELECTORS = [
"button:not([disabled])",
"a[href]",
"input:not([disabled])",
"select:not([disabled])",
"textarea:not([disabled])",
'[tabindex]:not([tabindex="-1"])'
];
const QR_CONFIG = {
ERROR_CORRECTION_LEVEL: "L"
};
function querySelector(parent, selector) {
return parent.querySelector(selector);
}
function removeAllChildren(parent) {
while (parent.firstChild) {
parent.removeChild(parent.firstChild);
}
}
function createElement(tagName, options) {
const element = document.createElement(tagName);
if (options?.className) {
element.className = options.className;
}
if (options?.attributes) {
Object.entries(options.attributes).forEach(([key, value]) => {
element.setAttribute(key, value);
});
}
if (options?.textContent) {
element.textContent = options.textContent;
}
return element;
}
function createSVGElement(tagName, attributes) {
const element = document.createElementNS(NAMESPACES.SVG, tagName);
if (attributes) {
Object.entries(attributes).forEach(([key, value]) => {
element.setAttribute(key, value);
});
}
return element;
}
function addClass(element, className) {
element?.classList.add(className);
}
function removeClass(element, className) {
element?.classList.remove(className);
}
function isInDOM(element) {
return element ? document.body.contains(element) : false;
}
function focusElement(element, temporary = false) {
if (!element) return;
if (temporary && !element.hasAttribute("tabindex")) {
element.setAttribute("tabindex", "-1");
element.focus();
element.removeAttribute("tabindex");
} else {
element.focus();
}
}
function appendChildren(parent, ...children) {
children.forEach((child) => parent.appendChild(child));
}
const _DeepLinkHandler = class _DeepLinkHandler {
static generateVerifyLink(token) {
try {
parseChallengeToken(token);
} catch {
throw new HumanmarkChallengeError(
"Invalid challenge token",
ErrorCode.INVALID_CHALLENGE_FORMAT
);
}
const url = new URL(this.VERIFY_BASE_URL);
url.searchParams.set("token", token);
return url.toString();
}
static createVerifyButton(token) {
try {
parseChallengeToken(token);
} catch {
throw new HumanmarkChallengeError(
"Invalid challenge token",
ErrorCode.INVALID_CHALLENGE_FORMAT
);
}
const button = createElement("button", {
className: CSS_CLASSES.BUTTONS.VERIFY,
textContent: MESSAGES.VERIFICATION.BUTTON_TEXT
});
button.addEventListener("click", () => {
this.handleVerifyClick(token);
});
return button;
}
static handleVerifyClick(token) {
const verifyLink = this.generateVerifyLink(token);
window.open(verifyLink, BROWSER_TARGETS.BLANK);
}
};
_DeepLinkHandler.VERIFY_BASE_URL = URLS.VERIFY_BASE;
let DeepLinkHandler = _DeepLinkHandler;
const DeepLinkHandler$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
DeepLinkHandler
}, Symbol.toStringTag, { value: "Module" }));
export {
ANIMATION_TIMINGS as A,
CSS_CLASSES as C,
DeepLinkHandler as D,
ELEMENT_IDS as E,
FOCUSABLE_SELECTORS as F,
KEYBOARD_KEYS as K,
MESSAGES as M,
QR_CONFIG as Q,
SVG_DIMENSIONS as S,
URLS as U,
createElement as a,
appendChildren as b,
createSVGElement as c,
ARIA as d,
addClass as e,
removeClass as f,
focusElement as g,
COLORS as h,
isInDOM as i,
DIMENSIONS as j,
DeepLinkHandler$1 as k,
querySelector as q,
removeAllChildren as r
};
//# sourceMappingURL=DeepLinkHandler-DqDFWmlg.js.map