esign: ink-reproduction consent gate + patent-risk research
Consent gate (the legal linchpin from the wet-signature memo): - migration 092 adds ink_consent/ink_consent_at/ink_consent_text to esign_records - extract pure, unit-tested gate logic into esign-ink-consent.ts (DRY single source for route + signing page): isInkReproduction / inkConsentRequired / inkConsentSatisfied + verbatim client-safe INK_CONSENT_TEXT - portal-esign-generic.ts: GET surfaces ink_reproduction + consent text; POST gates DRAWN signatures on ink-path docs on explicit consent, stores it - signing page locks the signature block until consent is checked (drawn only) - npi_provider marks cms855/cms10114 esign metadata ink_reproduction=true - 33 unit checks: gate truth table + consent text omits all internal mechanics (plotter/machine/CMS/MAC/etc) and keeps required legal reassurances Patent-risk memo (docs/legal/patent-risk-mechanical-wet-signature.md): - prior-art-dated risk analysis (autopen 1803/1942, plotters, CNC = public domain => low risk on core concept; e-sign workflow space litigious) - firsthand recent-grant sweep (1.58M USPTO grants 2021-2025, queried via DuckDB): ZERO patents on machine-applies-signature-in-ink; e-sign players hold only electronic-workflow patents. Not an FTO; flags where attorney search is needed
This commit is contained in:
parent
f8d2a7f01f
commit
a4bad723bc
7 changed files with 452 additions and 5 deletions
|
|
@ -52,6 +52,8 @@ body{font-family:'Inter',system-ui,sans-serif;color:#1f2937;background:#f1f5f9;l
|
|||
#loading{text-align:center;padding:4rem 1rem;color:#64748b}
|
||||
#error-screen{display:none;text-align:center;padding:3rem 1rem}
|
||||
.hidden{display:none}
|
||||
/* Signature block locked until ink-reproduction consent is given */
|
||||
#sig-block.locked{opacity:.45;pointer-events:none;filter:grayscale(.3)}
|
||||
</style>
|
||||
<script defer src="https://analytics.performancewest.net/script.js" data-website-id="55250014-ee15-44ac-a1f6-81dabad3fe0f"></script><script defer src="/js/pw-analytics.js"></script></head>
|
||||
<body>
|
||||
|
|
@ -76,6 +78,19 @@ body{font-family:'Inter',system-ui,sans-serif;color:#1f2937;background:#f1f5f9;l
|
|||
<!-- Step 2: Sign -->
|
||||
<div class="card">
|
||||
<h2>Step 2 — Your Signature</h2>
|
||||
|
||||
<!-- Ink-reproduction consent gate (shown only for ink-path documents).
|
||||
The signer must authorize use of their signature on the official form
|
||||
BEFORE they can draw it. -->
|
||||
<div id="ink-consent-box" class="hidden" style="padding:1rem;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px;margin-bottom:1rem">
|
||||
<p style="font-size:.85rem;color:#1f2937;margin:0 0 .75rem" id="ink-consent-text"></p>
|
||||
<label style="display:flex;gap:.6rem;align-items:flex-start;font-size:.85rem;color:#1f2937;cursor:pointer">
|
||||
<input type="checkbox" id="ink-consent-chk" style="margin-top:2px;flex-shrink:0;width:16px;height:16px;accent-color:#1e3a5f">
|
||||
<span>I authorize this and confirm the signature I draw is my own.</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div id="sig-block">
|
||||
<div class="sig-tabs">
|
||||
<button type="button" class="sig-tab active" data-mode="draw">Draw</button>
|
||||
<button type="button" class="sig-tab" data-mode="type">Type</button>
|
||||
|
|
@ -95,6 +110,7 @@ body{font-family:'Inter',system-ui,sans-serif;color:#1f2937;background:#f1f5f9;l
|
|||
<input type="text" id="typed-sig" placeholder="Your full name" autocomplete="name">
|
||||
<div class="typed-preview" id="typed-preview"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Step 3: Confirm -->
|
||||
|
|
@ -190,6 +206,16 @@ body{font-family:'Inter',system-ui,sans-serif;color:#1f2937;background:#f1f5f9;l
|
|||
document.getElementById("perjury-box").classList.remove("hidden");
|
||||
}
|
||||
|
||||
// Ink-reproduction consent gate: for documents whose signature will be
|
||||
// reproduced in ink on the official paper form, require an explicit
|
||||
// per-document authorization BEFORE the signer can draw. Lock the signature
|
||||
// block until the consent box is checked.
|
||||
if (data.ink_reproduction && data.ink_consent_text) {
|
||||
document.getElementById("ink-consent-text").textContent = data.ink_consent_text;
|
||||
document.getElementById("ink-consent-box").classList.remove("hidden");
|
||||
document.getElementById("sig-block").classList.add("locked");
|
||||
}
|
||||
|
||||
// PDF preview
|
||||
if (data.document_url) {
|
||||
document.getElementById("pdf-container").innerHTML =
|
||||
|
|
@ -318,9 +344,31 @@ body{font-family:'Inter',system-ui,sans-serif;color:#1f2937;background:#f1f5f9;l
|
|||
var agreeChk = document.getElementById("agree-chk");
|
||||
agreeChk.addEventListener("change", updateSubmit);
|
||||
|
||||
// ── Ink-reproduction consent: unlock the signature block when authorized ──
|
||||
var inkConsentChk = document.getElementById("ink-consent-chk");
|
||||
inkConsentChk.addEventListener("change", function() {
|
||||
var data = window._esignData || {};
|
||||
var needsInk = !!(data.ink_reproduction && data.ink_consent_text);
|
||||
if (needsInk) {
|
||||
document.getElementById("sig-block").classList.toggle("locked", !this.checked);
|
||||
// If they un-check after drawing, clear the now-unauthorized capture.
|
||||
if (!this.checked) document.getElementById("sig-clear").click();
|
||||
}
|
||||
updateSubmit();
|
||||
});
|
||||
|
||||
function inkConsentOk() {
|
||||
var data = window._esignData || {};
|
||||
var needsInk = !!(data.ink_reproduction && data.ink_consent_text);
|
||||
// Ink consent is only required for a DRAWN signature on an ink-path doc.
|
||||
if (!needsInk || sigMode !== "draw") return true;
|
||||
return inkConsentChk.checked;
|
||||
}
|
||||
|
||||
function updateSubmit() {
|
||||
var hasSignature = sigMode === "draw" ? hasSig : typedInput.value.trim().length >= 2;
|
||||
document.getElementById("submit-btn").disabled = !(hasSignature && agreeChk.checked);
|
||||
document.getElementById("submit-btn").disabled =
|
||||
!(hasSignature && agreeChk.checked && inkConsentOk());
|
||||
}
|
||||
|
||||
document.getElementById("submit-btn").addEventListener("click", async function() {
|
||||
|
|
@ -353,6 +401,7 @@ body{font-family:'Inter',system-ui,sans-serif;color:#1f2937;background:#f1f5f9;l
|
|||
signature: signatureData,
|
||||
agreed_at: new Date().toISOString(),
|
||||
user_agent: navigator.userAgent,
|
||||
ink_consent: inkConsentOk() && sigMode === "draw" && inkConsentChk.checked,
|
||||
}),
|
||||
});
|
||||
var result = await resp.json();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue