UNPKG

react-anticapture

Version:

A lightweight React component that helps prevent users from capturing (copying, selecting, printing, or screenshotting) sensitive information rendered on your website. Perfect for privacy, security, and content protection in React applications.

154 lines (153 loc) 6.28 kB
import { jsxs as D, Fragment as A, jsx as C } from "react/jsx-runtime"; import T from "devtools-detect"; import { useState as h, useEffect as f } from "react"; const l = "CLIPBOARD", m = "COPY", a = "ENTER", g = "DEFAULT", M = () => { document.body.innerHTML = '<p class="font-weight-bold">Please close devtools/console to continue.</p>', document.body.style.margin = "0", document.body.style.overflow = "hidden", document.body.style.height = "100vh", document.body.style.display = "flex", document.body.style.alignItems = "center", document.body.style.justifyContent = "center", document.body.style.backgroundColor = "#f0f0f0", document.body.style.color = "#333"; }, O = (c) => { const d = [ // Screenshot/Screen Recording (using event.code for precision) ["PrintScreen"], ["Meta"], ["Alt", "PrintScreen"], // This will be handled specially ["Meta", "PrintScreen"], // This will be handled specially ["Meta", "Shift"], // This will be handled specially ["Meta", "Shift", "KeyS"], ["Meta", "Shift", "Digit3"], ["Meta", "Shift", "Digit4"], ["Control", "Shift", "KeyP"], // This will be handled specially ["Meta", "KeyG"], ["Meta", "Alt", "KeyR"], ["Shift", "Meta", "Digit5"], // Inspect Element / Developer Tools ["F12"], ["Control", "Shift", "KeyI"], ["Control", "Shift", "KeyC"], ["Control", "Shift", "KeyJ"], ["Control", "KeyU"] ], s = (r) => r === "MetaLeft" || r === "MetaRight" ? "Meta" : r === "AltLeft" || r === "AltRight" ? "Alt" : r === "ShiftLeft" || r === "ShiftRight" ? "Shift" : r === "ControlLeft" || r === "ControlRight" ? "Control" : r, i = [...c.map(s)].sort(); return d.some((r) => { const n = [...r].map(s).sort(); return n.length === i.length && n.every((y, b) => y === i[b]); }); }, R = ({ targetClick: c, clipboardPrevent: d = !1, devtoolsPrevent: s = !1, screenshotPrevent: u = !0 }) => { const [i, r] = h({}), [n, y] = h({ text: "Press enter to continue.", color: "black", type: a }), [b, k] = h(T.isOpen), [L, p] = h(!0), S = (t) => r((o) => ({ ...o, [t]: !0 })), K = (t) => r((o) => { const e = { ...o }; return delete e[t], e; }), x = () => r({}), w = (t) => { switch (t) { case m: y({ text: "This page is prohibited from being copied or captured!", color: "red", type: m }); break; case l: y({ text: "Please allow clipboard on your browser to continue.", color: "red", type: l }); break; case a: y({ text: "Press enter to continue.", color: "black", type: a }); break; case g: y({ text: "", color: "", type: g }); break; } }, P = () => Object.keys(i); f(() => { i && Object.keys(i).length > 0 && n.type !== l && O(P()) && (p(!0), w(m), x()); }, [i]), s && f(() => { const t = (e) => { e.detail.isOpen ? k(!0) : window.location.reload(); }; window.addEventListener("devtoolschange", t); let o; return b && (console.clear(), o = setInterval(() => { console.log("%c Close your devtools/console!", "background: #222; color: #bada55; font-size: 50px; text-align: end"), setTimeout(() => { console.clear(); }, 900); }, 1e3), M()), () => { o && clearInterval(o), window.removeEventListener("devtoolschange", t); }; }, [b, s]), d && f(() => { const t = (e) => e.preventDefault(), o = (e) => { e.preventDefault(), navigator.clipboard.writeText(""), w(m), p(!0); }; return window.addEventListener("contextmenu", t), window.addEventListener("copy", o), window.addEventListener("paste", o), () => { window.removeEventListener("contextmenu", t), window.removeEventListener("copy", o), window.removeEventListener("paste", o); }; }, [d]), f(() => { const t = (e) => { e.key === "Enter" ? (n.type === a || n.type === l) && (w(g), p(!1)) : (u && (e.key === "F12" && e.preventDefault(), e.ctrlKey && e.code === "KeyU" && e.preventDefault(), e.ctrlKey && e.shiftKey && ["KeyI", "KeyC", "KeyJ"].includes(e.code) && e.preventDefault()), S(e.code)); }, o = (e) => { if (n.type === a || n.type === l) { K(e.code); return; } u && e.key === "PrintScreen" ? (e.preventDefault(), p(!0), w(m), navigator.clipboard.writeText("")) : K(e.code); }; return document.addEventListener("keydown", t), window.addEventListener("keyup", o), () => { window.removeEventListener("keydown", t), window.removeEventListener("keyup", o); }; }, [n.type, u]), f(() => { var o; const t = () => { [a, l].includes(n.type) || p(!0); }; return (o = document.querySelector("html")) == null || o.addEventListener("mouseleave", t), () => { var e; (e = document.querySelector("html")) == null || e.removeEventListener("mouseleave", t); }; }, [n.type]); const E = () => { L && ![a, l].includes(n.type) && (p(!1), n.type === m && w(g)); }; return f(() => { let t = c || document.querySelector("html"); return t && t.addEventListener("click", E), () => { t && t.removeEventListener("click", E); }; }, [n, L, c]), { blurPage: L, alertText: n }; }, _ = "_anticapture-wrapper_o02wf_15", j = "_alert-anticapture_o02wf_23", B = "_anticapture-blur-page_o02wf_61", v = { anticaptureWrapper: _, alertAnticapture: j, anticaptureBlurPage: B }, N = ({ children: c, userSelect: d = !0, ...s // Destructure remaining props to pass directly to the hook }) => { const { blurPage: u, alertText: i } = R(s); return /* @__PURE__ */ D(A, { children: [ /* @__PURE__ */ C("div", { className: v.alertAnticapture, style: { display: i.text ? "block" : "none" }, children: i.text && /* @__PURE__ */ C("p", { style: { fontWeight: "bolder", color: i.color, margin: 0 }, children: i.text }) }), /* @__PURE__ */ C( "div", { id: "anticapture-wrapper", className: ` ${v.anticaptureWrapper} ${u ? v.anticaptureBlurPage : ""} ${d ? v.userSelect : ""} `, style: { transition: "filter 0.1s ease-in-out" }, children: c } ) ] }); }; export { N as default }; //# sourceMappingURL=index.js.map