@semics-tech/emdash-esign 1.0.0-rc.4 → 1.0.0-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +1 -1
- package/dist/manifest.json +1 -1
- package/dist/plugin.mjs +17 -17
- package/package.json +1 -1
- package/src/astro/lib/csp.ts +30 -15
package/dist/index.mjs
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
/** @type {import("emdash").PluginDescriptor} */
|
|
8
8
|
const descriptor = Object.freeze({
|
|
9
9
|
"id": "semics-esign",
|
|
10
|
-
"version": "1.0.0-rc.
|
|
10
|
+
"version": "1.0.0-rc.5",
|
|
11
11
|
"format": "standard",
|
|
12
12
|
"entrypoint": "@semics-tech/emdash-esign/sandbox",
|
|
13
13
|
"capabilities": [
|
package/dist/manifest.json
CHANGED
package/dist/plugin.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
function e(e){for(let t of Object.keys(e))e[t]===void 0&&delete e[t];return e}function t(t,n={}){return e({type:`header`,text:t,block_id:n.blockId})}function n(t,n={}){return e({type:`context`,text:t,block_id:n.blockId})}function r(t,n={}){return e({type:`fields`,fields:t,block_id:n.blockId})}function i(e,t,n){return n===void 0?{key:e,label:t}:{key:e,label:t,format:n}}function a(t){return e({type:`table`,columns:t.columns,rows:t.rows,page_action_id:t.pageActionId,next_cursor:t.nextCursor,empty_text:t.emptyText,block_id:t.blockId})}function o(t){return e({type:`code`,code:t.code,language:t.language,block_id:t.blockId})}const s={error:`error`,warning:`alert`,info:`default`};function c(t){if(t.title===void 0&&t.description===void 0)throw Error(`banner needs a title or a description`);return e({type:`banner`,title:t.title,description:t.description,variant:t.variant,block_id:t.blockId})}function l(e){return c({title:e.title,description:e.message,variant:s[e.severity],blockId:e.blockId})}function u(e){return e.filter(e=>!!e).map(l)}function d(t,n={}){return e({type:`actions`,elements:t,block_id:n.blockId})}function f(t,n,r={}){return e({type:`button`,action_id:t,label:n,style:r.style,value:r.value,confirm:r.confirm})}function p(t,n,r={}){return e({type:`link`,label:t,target:n,appearance:r.appearance})}function m(t,n,r={}){return e({type:`text_input`,action_id:t,label:n,placeholder:r.placeholder,initial_value:r.initialValue,multiline:r.multiline})}function h(t,n,r={}){return e({type:`number_input`,action_id:t,label:n,initial_value:r.initialValue,min:r.min,max:r.max})}function g(t,n,r,i={}){return e({type:`select`,action_id:t,label:n,options:r,initial_value:i.initialValue,optionsRoute:i.optionsRoute})}function _(t,n,r={}){return e({type:`toggle`,action_id:t,label:n,description:r.description,initial_value:r.initialValue})}function v(t,n,r={}){return e({type:`secret_input`,action_id:t,label:n,placeholder:r.placeholder,has_value:r.hasValue})}function y(t){return e({type:`form`,fields:t.fields,submit:{label:t.submit.label,action_id:t.submit.actionId},block_id:t.blockId})}const b=e=>crypto.getRandomValues(new Uint8Array(e));function x(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}function S(e){return Array.from(new Uint8Array(e),e=>e.toString(16).padStart(2,`0`)).join(``)}function C(e){return crypto.subtle.importKey(`raw`,new Uint8Array(e),{name:`HMAC`,hash:`SHA-256`},!1,[`sign`])}function w(e){return{ok:!0,value:e}}function T(e){return{ok:!1,error:e}}function ee(...e){let t={};for(let n of e)for(let[e,[r,i]]of Object.entries(n??{}))t[e]=Object.freeze({status:r,message:i});return Object.freeze(t)}const te=ee({BAD_REQUEST:[400,`The request was not valid.`],NOT_FOUND:[404,`Not found.`],RATE_LIMITED:[429,`Too many requests. Please try again shortly.`],TURNSTILE_FAILED:[403,`The bot check failed. Please try again.`],TOKEN_IN_QUERY:[400,`Tokens must not be sent in the URL.`],INTERNAL:[500,`Something went wrong. Please try again later.`],SOLD_OUT:[409,`This event is sold out.`],HOLD_EXPIRED:[409,`Your hold has expired. Please start again.`],SALES_CLOSED:[409,`Sales for this event are closed.`],BOOKING_TOKEN_INVALID:[404,`Not found.`],BOOKING_TOKEN_EXPIRED:[401,`This booking link has expired.`],CANCEL_NOT_ALLOWED:[409,`This booking can no longer be cancelled online.`]},{ENVELOPE_NOT_FOUND:[404,`Document not found.`],ENVELOPE_CLOSED:[409,`This document can no longer be signed.`],SIGNING_TOKEN_INVALID:[401,`This signing link is not valid.`],SIGNING_TOKEN_EXPIRED:[401,`This signing link has expired.`],SESSION_REQUIRED:[409,`Please reopen the signing page and try again.`],SIGNED_PDF_PENDING:[409,`The signed document is still being prepared. Please try again in a minute.`],SIGNING_OUT_OF_TURN:[409,`Another signer has to sign first. You will get an email when it is your turn.`],OTP_REQUIRED:[403,`Enter the code we emailed you before signing.`]},{TOKEN_TOO_LARGE:[413,`The token is too large.`],TOKEN_MALFORMED:[400,`The token is malformed.`],CLIENT_UNKNOWN:[401,`The client is not recognised.`],CLIENT_REVOKED:[403,`The client has been revoked.`],TOKEN_INVALID:[401,`The token is not valid.`],PAYLOAD_INVALID:[400,`The token payload is not valid.`],TOKEN_LIFETIME_EXCEEDED:[400,`The token lifetime is too long.`],TOKEN_NOT_YET_VALID:[401,`The token is not valid yet.`],TOKEN_EXPIRED:[401,`The token has expired.`],RETURN_URL_NOT_ALLOWED:[400,`The return URL is not allowed.`],TOKEN_REPLAYED:[409,`The token has already been used.`],PAIRING_MALFORMED:[400,`The pairing string is malformed.`],TEMPLATE_NOT_FOUND:[404,`Template not found.`],REF_UNKNOWN:[404,`Reference not found.`]},{PAYMENT_FAILED:[402,`The payment could not be completed.`]},{LICENCE_INVALID:[403,`The licence is not valid.`],LICENCE_EXPIRED:[403,`The licence has expired.`]});function E(e){if(typeof e==`string`)return e;if(typeof e==`object`&&e&&`code`in e)return e.code}function ne(e,t){let n=E(t),r=typeof n==`string`&&Object.hasOwn(e,n)?n:`INTERNAL`,{status:i,message:a}=e[r];return{status:i,body:{ok:!1,error:{code:r,message:a}}}}function D(e){return ne(te,e)}const O=
|
|
2
|
-
`)}async function fe(e,t){return x(new Uint8Array(await crypto.subtle.sign(`HMAC`,e,ie.encode(t))))}async function pe(e){let{secret:t,purpose:n,params:r,now:i,ttlMs:a=9e5}=e,o=await ue(t);if(n.length===0)throw Error(`Link purpose must not be empty.`);if(!Number.isFinite(i))throw Error(`Link now must be a finite epoch time in milliseconds.`);if(!(a>=re&&a<=O))throw Error(`Link ttl must be between ${re} and ${O} ms.`);let s=Object.entries(r);if(s.some(([e])=>ae.has(e)))throw Error(`Link params must not use the reserved names exp or sig.`);let c=String(Math.floor((i+a)/1e3)),l=new URLSearchParams(s);return l.set(`exp`,c),l.set(`sig`,await fe(o,de(n,c,s))),l}async function me(e){let{secret:t,purpose:n,query:r,now:i}=e,a=await ue(t),o=new Set,s=[],c,l;for(let[e,t]of r){if(o.has(e))return T(`TOKEN_INVALID`);o.add(e),e===`exp`?c=t:e===`sig`?l=t:s.push([e,t])}return c===void 0||l===void 0||!oe.test(c)||!ce(await fe(a,de(n,c,s)),l)?T(`TOKEN_INVALID`):i>=Number(c)*1e3?T(`TOKEN_EXPIRED`):w(Object.fromEntries(s))}const he=Object.freeze({intent:`esign-intent/1`,receipt:`esign-receipt/1`,lookup:`esign-lookup/1`,catalog:`esign-catalog/1`}),ge=Object.freeze({intent:8192,receipt:2048,lookup:1024,catalog:1024}),_e=/^[A-Za-z0-9_-]{4,64}$/,ve=/^[A-Za-z0-9_-]*$/,ye=new TextEncoder;function be(e){if(!ve.test(e)||e.length%4==1)return;let t=atob(e.replace(/-/g,`+`).replace(/_/g,`/`)),n=Uint8Array.from(t,e=>e.charCodeAt(0));return x(n)===e?n:void 0}async function xe(e){if(e.length!==32)throw Error(`Client secret must be 32 bytes.`);return C(e)}async function Se(e,t,n){let r=await crypto.subtle.sign(`HMAC`,await xe(e),ye.encode(`${t}.${n}`));return x(new Uint8Array(r))}const Ce=/^[A-Za-z0-9_-]{1,64}$/,we=/^[A-Za-z0-9._:-]{1,128}$/,Te=/^[0-9a-f]{64}$/,Ee=/^[A-Za-z0-9_-]{16,64}$/,De=/^[A-Za-z0-9_]{1,64}$/,Oe=/[\uD800-\uDFFF]/u,ke=/[\u0000-\u001F\u007F]/,Ae=/[\u0000- \u007F]/;function je(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Me(e){let t=0;for(let n of e)t++;return t}function Ne(e,t,n){if(typeof e!=`string`||Oe.test(e))return!1;let r=Me(e);return r>=t&&r<=n}function A(e,t){return typeof e==`string`&&t.test(e)}function Pe(e){return Number.isSafeInteger(e)&&e>=0}function Fe(e){return Ne(e,1,200)&&!ke.test(e)}function Ie(e){if(!Ne(e,1,254)||Ae.test(e))return!1;let t=e.split(`@`);return t.length===2&&t[0]!==``&&t[1]!==``}function Le(e){if(!je(e))return!1;let t=Object.entries(e);return t.length<=32&&t.every(([e,t])=>De.test(e)&&Ne(t,0,500))}function Re(e){return je(e)&&Fe(e.name)}function ze(e){let t=e.as===`guardian`;return Pe(e.iat)&&Pe(e.exp)&&e.exp>e.iat&&A(e.nonce,Ee)&&A(e.tpl,Ce)&&(e.tplVersion===void 0||Number.isSafeInteger(e.tplVersion)&&e.tplVersion>=1)&&A(e.ref,we)&&je(e.signer)&&Fe(e.signer.name)&&Ie(e.signer.email)&&(e.as===void 0||e.as===`self`||t||e.as===`buyer`)&&(t?Re(e.participant):!Object.hasOwn(e,`participant`))&&(e.delivery===void 0||e.delivery===`inline`||e.delivery===`email`)&&Le(e.prefill)&&Ne(e.returnUrl,1,2048)}const Be=new Set([`completed`,`declined`,`voided`,`expired`]);function Ve(e){let t=e.status===`completed`;return A(e.envelopeId,Ce)&&A(e.ref,we)&&Be.has(e.status)&&A(e.docSha256,Te)&&(t?e.pdfSha256===null||A(e.pdfSha256,Te):e.pdfSha256===null)&&(t?A(e.finalHash,Te):e.finalHash===null)&&Pe(e.at)}const He={intent:ze,receipt:Ve,lookup:e=>Pe(e.ts)&&A(e.ref,we),catalog:e=>Pe(e.ts)};function Ue(e,t){return!je(t)||t.v!==1||t.typ!==e||!A(t.cid,_e)||!He[e](t)?T(`PAYLOAD_INVALID`):e===`intent`&&t.exp-t.iat>1800?T(`TOKEN_LIFETIME_EXCEEDED`):w(t)}const We=new Set([`localhost`,`127.0.0.1`,`[::1]`]);function Ge(e){try{return new URL(e)}catch{return}}function Ke(e){return e.username!==``||e.password!==``}function qe(e){let t=Ge(e);if(!(t===void 0||Ke(t)||t.search!==``||e.includes(`#`)))return t.protocol===`https:`||t.protocol===`http:`&&We.has(t.hostname)?t:void 0}function Je(e,t){return t.endsWith(`/`)?e.startsWith(t):e===t||e.startsWith(`${t}/`)}function Ye(e,t){let n=Ge(e);return n===void 0||n.protocol!==`https:`&&n.protocol!==`http:`||Ke(n)||e.includes(`#`)?!1:t.some(e=>{let t=qe(e);return t!==void 0&&t.origin===n.origin&&Je(n.pathname,t.pathname)})}async function Xe(e,t){let{token:n}=t;if(typeof n!=`string`)return T(`TOKEN_MALFORMED`);if(n.length>ge[e])return T(`TOKEN_TOO_LARGE`);let r=n.split(`.`);if(r.length!==2)return T(`TOKEN_MALFORMED`);let[i,a]=r,o=be(i);if(o===void 0||o.length===0||a.length!==43||be(a)===void 0)return T(`TOKEN_MALFORMED`);let s=Ze(o);if(s===void 0||!A(s.cid,_e))return T(`TOKEN_MALFORMED`);let c=await t.getClient(s.cid);return c===void 0?T(`CLIENT_UNKNOWN`):c.revoked?T(`CLIENT_REVOKED`):ce(await Se(c.secret,he[e],i),a)?w({payload:s,client:c}):T(`TOKEN_INVALID`)}function Ze(e){if(!(e[0]===239&&e[1]===187&&e[2]===191))try{let t=JSON.parse(new TextDecoder(`utf-8`,{fatal:!0}).decode(e));return je(t)?t:void 0}catch{return}}function Qe(e,t){return e===`intent`?t.iat:e===`receipt`?t.at:t.ts}function $e(e,t){if(e===`intent`)return t.exp+60;if(e!==`receipt`)return t.ts+300+60}async function et(e,t){let n=await Xe(e,t);if(!n.ok)return n;let r=Ue(e,n.value.payload);if(!r.ok)return r;let i=Math.floor(t.now/1e3);if(Qe(e,r.value)>i+60)return T(`TOKEN_NOT_YET_VALID`);let a=$e(e,r.value);return a!==void 0&&i>a?T(`TOKEN_EXPIRED`):w({payload:r.value,client:n.value.client})}async function tt(e){let t=await et(`intent`,e);if(!t.ok)return t;let{payload:n,client:r}=t.value,i=r.returnUrlAllowlist?.length?r.returnUrlAllowlist:e.siteOrigin===void 0?[]:[`${e.siteOrigin}/`];return Ye(n.returnUrl,i)?await e.consumeNonce(n.cid,n.nonce,n.exp+60)?w(n):T(`TOKEN_REPLAYED`):T(`RETURN_URL_NOT_ALLOWED`)}async function nt(e,t){let n=await et(e,t);return n.ok?w(n.value.payload):n}function rt(e){return nt(`lookup`,e)}function it(e){return nt(`catalog`,e)}async function at(e,t,n){let r=Ue(e,t);if(!r.ok)throw Error(`Cannot sign ${e} token: ${r.error}.`);let i=x(ye.encode(JSON.stringify(t))),a=`${i}.${await Se(n,he[e],i)}`;if(a.length>ge[e])throw Error(`Cannot sign ${e} token: TOKEN_TOO_LARGE.`);return a}const j=(e=Date.now())=>new Date(e).toISOString();function ot(e){let t=e.kind;return{to:e.to,subject:e.subject,...typeof t==`string`?{kind:t}:{}}}async function st(e,t,n,r){let i=r();return await e.put(i,{message:t,status:`pending`,attempts:0,nextAttemptAt:n,createdAt:n}),i}function ct(e){return Math.min(6e4*2**(e-1),36e5)}async function lt(e){let t={sent:0,failed:0,gaveUp:0,remainingHint:!1};if(!e.email)return t;let n=Math.max(1,e.maxPerTick??6),{items:r}=await e.storage.query({status:`pending`,nextAttemptAtLte:e.now,limit:n+1});if(r.length===0)return t;let i=[],a=0,o=0,s=0;for(let{id:t,data:c}of r.slice(0,n)){let n=c.attempts+1;try{await e.email.send(c.message),a++;let r=ot(c.message);i.push({id:t,data:{...c,message:r,status:`sent`,attempts:n,sentAt:e.now}})}catch(r){let a=(r instanceof Error?r.message:String(r)).replace(/\S*:\/\/\S*|[\w-]{20,}/g,`…`).slice(0,300);n>=5?(s++,i.push({id:t,data:{...c,message:ot(c.message),status:`failed`,attempts:n,lastError:a}})):(o++,i.push({id:t,data:{...c,attempts:n,lastError:a,nextAttemptAt:e.now+ct(n)}}))}}return await e.storage.putMany(i),{sent:a,failed:o,gaveUp:s,remainingHint:r.length>n}}async function ut(e){let[t,n]=await Promise.all([e.storage.query({status:`pending`,limit:100}),e.storage.query({status:`failed`,limit:100})]);return{state:e.email?`ok`:`no_transport`,pending:t.items.length,failed:n.items.length}}const dt=new TextEncoder;function ft(e){if(!_e.test(e))throw Error(`Client id must match the esign-intent/1 clientId grammar.`)}function pt(e,t){if(ft(e),t.length!==32)throw Error(`Client secret must be 32 bytes.`);return`esign1.${e}.${x(t)}`}async function mt(e,t){if(e.length<32)throw Error(`Master key must be at least 32 bytes.`);ft(t);let n=await C(e);return new Uint8Array(await crypto.subtle.sign(`HMAC`,n,dt.encode(`esign-client/1.`+t)))}function ht(e=b){let t=e(16);if(t.length!==16)throw Error(`Random source must return 16 bytes.`);let n=`cl_`;for(let e of t)n+=`abcdefghijklmnopqrstuvwxyz234567`[e&31];return n}const gt=[{font:`regular`,resource:`F1`,baseFont:`Helvetica`},{font:`bold`,resource:`F2`,baseFont:`Helvetica-Bold`},{font:`italic`,resource:`F3`,baseFont:`Helvetica-Oblique`}];function _t(e){let t=new Uint16Array(256);for(let n=0;n<224;n++)t[32+n]=Number.parseInt(e.slice(2*n,2*n+2),36);return t}const vt=_t(`7q7q9vfgfgopij5b9999atg87q997q7qfgfgfgfgfgfgfgfgfgfg7q7qg8g8g8fgs7ijijk2k2ijgzlmk27qdwijfgn5k2lmijlmk2ijgzk2ijq8ijijgz7q7q7qd1fg99fgfgdwfgfg7qfgfg6666dw66n5fgfgfgfg99dw7qfgdwk2dwdwdw9a789ag800fg0066fg99rsfgfg99rsij99rs00gz0000666699999qfgrs99rsdw99q800dwij7q99fgfgfgfg78fg99khaafgg899kh99b4g8999999fgex7q9999a5fgn6n6n6gzijijijijijijrsk2ijijijij7q7q7q7qk2k2lmlmlmlmlmg8lmk2k2k2k2ijijgzfgfgfgfgfgfgopdwfgfgfgfg7q7q7q7qfgfgfgfgfgfgfgg8gzfgfgfgfgdwfgdw`),yt={regular:vt,bold:_t(`7q99d6fgfgopk26m9999atg87q997q7qfgfgfgfgfgfgfgfgfgfg9999g8g8g8gzr3k2k2k2k2ijgzlmk27qfgk2gzn5k2lmijlmk2ijgzk2ijq8ijijgz997q99g8fg99fggzfggzfg99gzgz7q7qfg7qopgzgzgzgzatfg99gzfglmfgfgdwat7satg800fg007qfgdwrsfgfg99rsij99rs00gz00007q7qdwdw9qfgrs99rsfg99q800dwij7q99fgfgfgfg7sfg99khaafgg899kh99b4g8999999gzfg7q9999a5fgn6n6n6gzk2k2k2k2k2k2rsk2ijijijij7q7q7q7qk2k2lmlmlmlmlmg8lmk2k2k2k2ijijgzfgfgfgfgfgfgopfgfgfgfgfg7q7q7q7qgzgzgzgzgzgzgzg8gzgzgzgzgzfggzfg`),italic:vt},bt=new Map([8364,0,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,0,381,0,0,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,0,382,376].flatMap((e,t)=>e?[[e,128+t]]:[])),xt=/^[\x20-\x7e\xa0-\xff]*$/;function St(e){return e>=32&&e<=126||e>=160&&e<=255?e:e===9||e===10||e===13?32:bt.get(e)??63}function Ct(e){if(xt.test(e))return e;let t=``;for(let n of e)t+=String.fromCharCode(St(n.codePointAt(0)));return t}function wt(e){return yt[e]}function Tt(e,t){let n=yt[t],r=0;for(let t=0;t<e.length;t++)r+=n[e.charCodeAt(t)];return r}const Et=1e7;function M(e){if(!Number.isFinite(e))return`0`;let t=Math.round(Math.min(Et,Math.max(-Et,e))*100)/100;return t===0?`0`:String(t)}function Dt(e){return`(${e.replace(/[\\()]/g,`\\$&`)})`}function Ot(e){if(/^[\x20-\x7e]*$/.test(e))return Dt(e);let t=`FEFF`;for(let n=0;n<e.length;n++)t+=e.charCodeAt(n).toString(16).toUpperCase().padStart(4,`0`);return`<${t}>`}function kt(e){let t=e.getTime();if(!Number.isFinite(t))return;let n=new Date(t).toISOString();return`D:${n.slice(0,4)}${n.slice(5,7)}${n.slice(8,10)}${n.slice(11,13)}${n.slice(14,16)}${n.slice(17,19)}Z`}function At(e){return`<< /Length ${e.length} >>\nstream\n${e}\nendstream`}function jt(e,t,n){let r=[`%PDF-1.7
|
|
1
|
+
function e(e){for(let t of Object.keys(e))e[t]===void 0&&delete e[t];return e}function t(t,n={}){return e({type:`header`,text:t,block_id:n.blockId})}function n(t,n={}){return e({type:`context`,text:t,block_id:n.blockId})}function r(t,n={}){return e({type:`fields`,fields:t,block_id:n.blockId})}function i(e,t,n){return n===void 0?{key:e,label:t}:{key:e,label:t,format:n}}function a(t){return e({type:`table`,columns:t.columns,rows:t.rows,page_action_id:t.pageActionId,next_cursor:t.nextCursor,empty_text:t.emptyText,block_id:t.blockId})}function o(t){return e({type:`code`,code:t.code,language:t.language,block_id:t.blockId})}const s={error:`error`,warning:`alert`,info:`default`};function c(t){if(t.title===void 0&&t.description===void 0)throw Error(`banner needs a title or a description`);return e({type:`banner`,title:t.title,description:t.description,variant:t.variant,block_id:t.blockId})}function l(e){return c({title:e.title,description:e.message,variant:s[e.severity],blockId:e.blockId})}function u(e){return e.filter(e=>!!e).map(l)}function d(t,n={}){return e({type:`actions`,elements:t,block_id:n.blockId})}function f(t,n,r={}){return e({type:`button`,action_id:t,label:n,style:r.style,value:r.value,confirm:r.confirm})}function p(t,n,r={}){return e({type:`link`,label:t,target:n,appearance:r.appearance})}function m(t,n,r={}){return e({type:`text_input`,action_id:t,label:n,placeholder:r.placeholder,initial_value:r.initialValue,multiline:r.multiline})}function h(t,n,r={}){return e({type:`number_input`,action_id:t,label:n,initial_value:r.initialValue,min:r.min,max:r.max})}function g(t,n,r,i={}){return e({type:`select`,action_id:t,label:n,options:r,initial_value:i.initialValue,optionsRoute:i.optionsRoute})}function _(t,n,r={}){return e({type:`toggle`,action_id:t,label:n,description:r.description,initial_value:r.initialValue})}function v(t,n,r={}){return e({type:`secret_input`,action_id:t,label:n,placeholder:r.placeholder,has_value:r.hasValue})}function y(t){return e({type:`form`,fields:t.fields,submit:{label:t.submit.label,action_id:t.submit.actionId},block_id:t.blockId})}const b=e=>crypto.getRandomValues(new Uint8Array(e));function x(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``)}function S(e){return Array.from(new Uint8Array(e),e=>e.toString(16).padStart(2,`0`)).join(``)}function C(e){return crypto.subtle.importKey(`raw`,new Uint8Array(e),{name:`HMAC`,hash:`SHA-256`},!1,[`sign`])}function w(e){return{ok:!0,value:e}}function T(e){return{ok:!1,error:e}}function ee(...e){let t={};for(let n of e)for(let[e,[r,i]]of Object.entries(n??{}))t[e]=Object.freeze({status:r,message:i});return Object.freeze(t)}const te=ee({BAD_REQUEST:[400,`The request was not valid.`],NOT_FOUND:[404,`Not found.`],RATE_LIMITED:[429,`Too many requests. Please try again shortly.`],TURNSTILE_FAILED:[403,`The bot check failed. Please try again.`],TOKEN_IN_QUERY:[400,`Tokens must not be sent in the URL.`],INTERNAL:[500,`Something went wrong. Please try again later.`],SOLD_OUT:[409,`This event is sold out.`],HOLD_EXPIRED:[409,`Your hold has expired. Please start again.`],SALES_CLOSED:[409,`Sales for this event are closed.`],BOOKING_TOKEN_INVALID:[404,`Not found.`],BOOKING_TOKEN_EXPIRED:[401,`This booking link has expired.`],CANCEL_NOT_ALLOWED:[409,`This booking can no longer be cancelled online.`]},{ENVELOPE_NOT_FOUND:[404,`Document not found.`],ENVELOPE_CLOSED:[409,`This document can no longer be signed.`],SIGNING_TOKEN_INVALID:[401,`This signing link is not valid.`],SIGNING_TOKEN_EXPIRED:[401,`This signing link has expired.`],SESSION_REQUIRED:[409,`Please reopen the signing page and try again.`],SIGNED_PDF_PENDING:[409,`The signed document is still being prepared. Please try again in a minute.`],SIGNING_OUT_OF_TURN:[409,`Another signer has to sign first. You will get an email when it is your turn.`],OTP_REQUIRED:[403,`Enter the code we emailed you before signing.`]},{TOKEN_TOO_LARGE:[413,`The token is too large.`],TOKEN_MALFORMED:[400,`The token is malformed.`],CLIENT_UNKNOWN:[401,`The client is not recognised.`],CLIENT_REVOKED:[403,`The client has been revoked.`],TOKEN_INVALID:[401,`The token is not valid.`],PAYLOAD_INVALID:[400,`The token payload is not valid.`],TOKEN_LIFETIME_EXCEEDED:[400,`The token lifetime is too long.`],TOKEN_NOT_YET_VALID:[401,`The token is not valid yet.`],TOKEN_EXPIRED:[401,`The token has expired.`],RETURN_URL_NOT_ALLOWED:[400,`The return URL is not allowed.`],TOKEN_REPLAYED:[409,`The token has already been used.`],PAIRING_MALFORMED:[400,`The pairing string is malformed.`],TEMPLATE_NOT_FOUND:[404,`Template not found.`],REF_UNKNOWN:[404,`Reference not found.`]},{PAYMENT_FAILED:[402,`The payment could not be completed.`]},{LICENCE_INVALID:[403,`The licence is not valid.`],LICENCE_EXPIRED:[403,`The licence has expired.`]});function E(e){if(typeof e==`string`)return e;if(typeof e==`object`&&e&&`code`in e)return e.code}function ne(e,t){let n=E(t),r=typeof n==`string`&&Object.hasOwn(e,n)?n:`INTERNAL`,{status:i,message:a}=e[r];return{status:i,body:{ok:!1,error:{code:r,message:a}}}}function D(e){return ne(te,e)}const O=new TextEncoder,re=new Set([`exp`,`sig`]),ie=/^\d{1,15}$/;function ae(e=b){let t=e(32);if(t.length!==32)throw Error(`Random source: need 32 bytes.`);return x(t)}async function oe(e){return S(new Uint8Array(await crypto.subtle.digest(`SHA-256`,O.encode(e))))}function se(e,t){let n=O.encode(e),r=O.encode(t),i=Math.max(n.length,r.length),a=n.length^r.length;for(let e=0;e<i;e++)a|=(n[e]??0)^(r[e]??0);return a===0}async function ce(e,t){return se(await oe(e),t??`0`.repeat(64))}async function le(e){if(e.length<32)throw Error(`Link secret under 32 bytes.`);return C(e)}function ue(e,t,n){let r=n.map(([e,t])=>`${encodeURIComponent(e)}=${encodeURIComponent(t)}`).sort();return[`semics-link/1`,encodeURIComponent(e),t,r.join(`&`)].join(`
|
|
2
|
+
`)}async function de(e,t){return x(new Uint8Array(await crypto.subtle.sign(`HMAC`,e,O.encode(t))))}async function fe(e){let{secret:t,purpose:n,params:r,now:i,ttlMs:a=9e5}=e,o=await le(t);if(n.length===0)throw Error(`Link purpose is empty.`);if(!Number.isFinite(i))throw Error(`Link now is not a time.`);if(!(a>=1e3&&a<=36e5))throw Error(`Link ttl out of range.`);let s=Object.entries(r);if(s.some(([e])=>re.has(e)))throw Error(`Link params: exp, sig are reserved.`);let c=String(Math.floor((i+a)/1e3)),l=new URLSearchParams(s);return l.set(`exp`,c),l.set(`sig`,await de(o,ue(n,c,s))),l}async function pe(e){let{secret:t,purpose:n,query:r,now:i}=e,a=await le(t),o=new Set,s=[],c,l;for(let[e,t]of r){if(o.has(e))return T(`TOKEN_INVALID`);o.add(e),e===`exp`?c=t:e===`sig`?l=t:s.push([e,t])}return c===void 0||l===void 0||!ie.test(c)||!se(await de(a,ue(n,c,s)),l)?T(`TOKEN_INVALID`):i>=Number(c)*1e3?T(`TOKEN_EXPIRED`):w(Object.fromEntries(s))}const me=Object.freeze({intent:`esign-intent/1`,receipt:`esign-receipt/1`,lookup:`esign-lookup/1`,catalog:`esign-catalog/1`}),he=Object.freeze({intent:8192,receipt:2048,lookup:1024,catalog:1024}),ge=/^[A-Za-z0-9_-]{4,64}$/,_e=/^[A-Za-z0-9_-]*$/,ve=new TextEncoder;function ye(e){if(!_e.test(e)||e.length%4==1)return;let t=atob(e.replace(/-/g,`+`).replace(/_/g,`/`)),n=Uint8Array.from(t,e=>e.charCodeAt(0));return x(n)===e?n:void 0}async function be(e){if(e.length!==32)throw Error(`Client secret must be 32 bytes.`);return C(e)}async function xe(e,t,n){let r=await crypto.subtle.sign(`HMAC`,await be(e),ve.encode(`${t}.${n}`));return x(new Uint8Array(r))}const Se=/^[A-Za-z0-9_-]{1,64}$/,Ce=/^[A-Za-z0-9._:-]{1,128}$/,we=/^[0-9a-f]{64}$/,Te=/^[A-Za-z0-9_-]{16,64}$/,Ee=/^[A-Za-z0-9_]{1,64}$/,De=/[\uD800-\uDFFF]/u,Oe=/[\u0000-\u001F\u007F]/,ke=/[\u0000- \u007F]/;function Ae(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function je(e){let t=0;for(let n of e)t++;return t}function Me(e,t,n){if(typeof e!=`string`||De.test(e))return!1;let r=je(e);return r>=t&&r<=n}function k(e,t){return typeof e==`string`&&t.test(e)}function Ne(e){return Number.isSafeInteger(e)&&e>=0}function Pe(e){return Me(e,1,200)&&!Oe.test(e)}function Fe(e){if(!Me(e,1,254)||ke.test(e))return!1;let t=e.split(`@`);return t.length===2&&t[0]!==``&&t[1]!==``}function Ie(e){if(!Ae(e))return!1;let t=Object.entries(e);return t.length<=32&&t.every(([e,t])=>Ee.test(e)&&Me(t,0,500))}function Le(e){return Ae(e)&&Pe(e.name)}function Re(e){let t=e.as===`guardian`;return Ne(e.iat)&&Ne(e.exp)&&e.exp>e.iat&&k(e.nonce,Te)&&k(e.tpl,Se)&&(e.tplVersion===void 0||Number.isSafeInteger(e.tplVersion)&&e.tplVersion>=1)&&k(e.ref,Ce)&&Ae(e.signer)&&Pe(e.signer.name)&&Fe(e.signer.email)&&(e.as===void 0||e.as===`self`||t||e.as===`buyer`)&&(t?Le(e.participant):!Object.hasOwn(e,`participant`))&&(e.delivery===void 0||e.delivery===`inline`||e.delivery===`email`)&&Ie(e.prefill)&&Me(e.returnUrl,1,2048)}const ze=new Set([`completed`,`declined`,`voided`,`expired`]);function Be(e){let t=e.status===`completed`;return k(e.envelopeId,Se)&&k(e.ref,Ce)&&ze.has(e.status)&&k(e.docSha256,we)&&(t?e.pdfSha256===null||k(e.pdfSha256,we):e.pdfSha256===null)&&(t?k(e.finalHash,we):e.finalHash===null)&&Ne(e.at)}const Ve={intent:Re,receipt:Be,lookup:e=>Ne(e.ts)&&k(e.ref,Ce),catalog:e=>Ne(e.ts)};function He(e,t){return!Ae(t)||t.v!==1||t.typ!==e||!k(t.cid,ge)||!Ve[e](t)?T(`PAYLOAD_INVALID`):e===`intent`&&t.exp-t.iat>1800?T(`TOKEN_LIFETIME_EXCEEDED`):w(t)}const Ue=new Set([`localhost`,`127.0.0.1`,`[::1]`]);function We(e){try{return new URL(e)}catch{return}}function Ge(e){return e.username!==``||e.password!==``}function Ke(e){let t=We(e);if(!(t===void 0||Ge(t)||t.search!==``||e.includes(`#`)))return t.protocol===`https:`||t.protocol===`http:`&&Ue.has(t.hostname)?t:void 0}function qe(e,t){return t.endsWith(`/`)?e.startsWith(t):e===t||e.startsWith(`${t}/`)}function Je(e,t){let n=We(e);return n===void 0||n.protocol!==`https:`&&n.protocol!==`http:`||Ge(n)||e.includes(`#`)?!1:t.some(e=>{let t=Ke(e);return t!==void 0&&t.origin===n.origin&&qe(n.pathname,t.pathname)})}async function Ye(e,t){let{token:n}=t;if(typeof n!=`string`)return T(`TOKEN_MALFORMED`);if(n.length>he[e])return T(`TOKEN_TOO_LARGE`);let r=n.split(`.`);if(r.length!==2)return T(`TOKEN_MALFORMED`);let[i,a]=r,o=ye(i);if(o===void 0||o.length===0||a.length!==43||ye(a)===void 0)return T(`TOKEN_MALFORMED`);let s=Xe(o);if(s===void 0||!k(s.cid,ge))return T(`TOKEN_MALFORMED`);let c=await t.getClient(s.cid);return c===void 0?T(`CLIENT_UNKNOWN`):c.revoked?T(`CLIENT_REVOKED`):se(await xe(c.secret,me[e],i),a)?w({payload:s,client:c}):T(`TOKEN_INVALID`)}function Xe(e){if(!(e[0]===239&&e[1]===187&&e[2]===191))try{let t=JSON.parse(new TextDecoder(`utf-8`,{fatal:!0}).decode(e));return Ae(t)?t:void 0}catch{return}}function Ze(e,t){return e===`intent`?t.iat:e===`receipt`?t.at:t.ts}function Qe(e,t){if(e===`intent`)return t.exp+60;if(e!==`receipt`)return t.ts+300+60}async function $e(e,t){let n=await Ye(e,t);if(!n.ok)return n;let r=He(e,n.value.payload);if(!r.ok)return r;let i=Math.floor(t.now/1e3);if(Ze(e,r.value)>i+60)return T(`TOKEN_NOT_YET_VALID`);let a=Qe(e,r.value);return a!==void 0&&i>a?T(`TOKEN_EXPIRED`):w({payload:r.value,client:n.value.client})}async function et(e){let t=await $e(`intent`,e);if(!t.ok)return t;let{payload:n,client:r}=t.value,i=r.returnUrlAllowlist?.length?r.returnUrlAllowlist:e.siteOrigin===void 0?[]:[`${e.siteOrigin}/`];return Je(n.returnUrl,i)?await e.consumeNonce(n.cid,n.nonce,n.exp+60)?w(n):T(`TOKEN_REPLAYED`):T(`RETURN_URL_NOT_ALLOWED`)}async function tt(e,t){let n=await $e(e,t);return n.ok?w(n.value.payload):n}function nt(e){return tt(`lookup`,e)}function rt(e){return tt(`catalog`,e)}async function it(e,t,n){let r=He(e,t);if(!r.ok)throw Error(`Cannot sign ${e} token: ${r.error}.`);let i=x(ve.encode(JSON.stringify(t))),a=`${i}.${await xe(n,me[e],i)}`;if(a.length>he[e])throw Error(`Cannot sign ${e} token: TOKEN_TOO_LARGE.`);return a}const A=(e=Date.now())=>new Date(e).toISOString();function at(e){let t=e.kind;return{to:e.to,subject:e.subject,...typeof t==`string`?{kind:t}:{}}}async function ot(e,t,n,r){let i=r();return await e.put(i,{message:t,status:`pending`,attempts:0,nextAttemptAt:n,createdAt:n}),i}function st(e){return Math.min(6e4*2**(e-1),36e5)}async function ct(e){let t={sent:0,failed:0,gaveUp:0,remainingHint:!1};if(!e.email)return t;let n=Math.max(1,e.maxPerTick??6),{items:r}=await e.storage.query({status:`pending`,nextAttemptAtLte:e.now,limit:n+1});if(r.length===0)return t;let i=[],a=0,o=0,s=0;for(let{id:t,data:c}of r.slice(0,n)){let n=c.attempts+1;try{await e.email.send(c.message),a++;let r=at(c.message);i.push({id:t,data:{...c,message:r,status:`sent`,attempts:n,sentAt:e.now}})}catch(r){let a=(r instanceof Error?r.message:String(r)).replace(/\S*:\/\/\S*|[\w-]{20,}/g,`…`).slice(0,300);n>=5?(s++,i.push({id:t,data:{...c,message:at(c.message),status:`failed`,attempts:n,lastError:a}})):(o++,i.push({id:t,data:{...c,attempts:n,lastError:a,nextAttemptAt:e.now+st(n)}}))}}return await e.storage.putMany(i),{sent:a,failed:o,gaveUp:s,remainingHint:r.length>n}}async function lt(e){let[t,n]=await Promise.all([e.storage.query({status:`pending`,limit:100}),e.storage.query({status:`failed`,limit:100})]);return{state:e.email?`ok`:`no_transport`,pending:t.items.length,failed:n.items.length}}const ut=new TextEncoder;function dt(e){if(!ge.test(e))throw Error(`Client id must match the esign-intent/1 clientId grammar.`)}function ft(e,t){if(dt(e),t.length!==32)throw Error(`Client secret must be 32 bytes.`);return`esign1.${e}.${x(t)}`}async function pt(e,t){if(e.length<32)throw Error(`Master key must be at least 32 bytes.`);dt(t);let n=await C(e);return new Uint8Array(await crypto.subtle.sign(`HMAC`,n,ut.encode(`esign-client/1.`+t)))}function mt(e=b){let t=e(16);if(t.length!==16)throw Error(`Random source must return 16 bytes.`);let n=`cl_`;for(let e of t)n+=`abcdefghijklmnopqrstuvwxyz234567`[e&31];return n}const ht=[{font:`regular`,resource:`F1`,baseFont:`Helvetica`},{font:`bold`,resource:`F2`,baseFont:`Helvetica-Bold`},{font:`italic`,resource:`F3`,baseFont:`Helvetica-Oblique`}];function gt(e){let t=new Uint16Array(256);for(let n=0;n<224;n++)t[32+n]=Number.parseInt(e.slice(2*n,2*n+2),36);return t}const _t=gt(`7q7q9vfgfgopij5b9999atg87q997q7qfgfgfgfgfgfgfgfgfgfg7q7qg8g8g8fgs7ijijk2k2ijgzlmk27qdwijfgn5k2lmijlmk2ijgzk2ijq8ijijgz7q7q7qd1fg99fgfgdwfgfg7qfgfg6666dw66n5fgfgfgfg99dw7qfgdwk2dwdwdw9a789ag800fg0066fg99rsfgfg99rsij99rs00gz0000666699999qfgrs99rsdw99q800dwij7q99fgfgfgfg78fg99khaafgg899kh99b4g8999999fgex7q9999a5fgn6n6n6gzijijijijijijrsk2ijijijij7q7q7q7qk2k2lmlmlmlmlmg8lmk2k2k2k2ijijgzfgfgfgfgfgfgopdwfgfgfgfg7q7q7q7qfgfgfgfgfgfgfgg8gzfgfgfgfgdwfgdw`),vt={regular:_t,bold:gt(`7q99d6fgfgopk26m9999atg87q997q7qfgfgfgfgfgfgfgfgfgfg9999g8g8g8gzr3k2k2k2k2ijgzlmk27qfgk2gzn5k2lmijlmk2ijgzk2ijq8ijijgz997q99g8fg99fggzfggzfg99gzgz7q7qfg7qopgzgzgzgzatfg99gzfglmfgfgdwat7satg800fg007qfgdwrsfgfg99rsij99rs00gz00007q7qdwdw9qfgrs99rsfg99q800dwij7q99fgfgfgfg7sfg99khaafgg899kh99b4g8999999gzfg7q9999a5fgn6n6n6gzk2k2k2k2k2k2rsk2ijijijij7q7q7q7qk2k2lmlmlmlmlmg8lmk2k2k2k2ijijgzfgfgfgfgfgfgopfgfgfgfgfg7q7q7q7qgzgzgzgzgzgzgzg8gzgzgzgzgzfggzfg`),italic:_t},yt=new Map([8364,0,8218,402,8222,8230,8224,8225,710,8240,352,8249,338,0,381,0,0,8216,8217,8220,8221,8226,8211,8212,732,8482,353,8250,339,0,382,376].flatMap((e,t)=>e?[[e,128+t]]:[])),bt=/^[\x20-\x7e\xa0-\xff]*$/;function xt(e){return e>=32&&e<=126||e>=160&&e<=255?e:e===9||e===10||e===13?32:yt.get(e)??63}function St(e){if(bt.test(e))return e;let t=``;for(let n of e)t+=String.fromCharCode(xt(n.codePointAt(0)));return t}function Ct(e){return vt[e]}function wt(e,t){let n=vt[t],r=0;for(let t=0;t<e.length;t++)r+=n[e.charCodeAt(t)];return r}const Tt=1e7;function j(e){if(!Number.isFinite(e))return`0`;let t=Math.round(Math.min(Tt,Math.max(-Tt,e))*100)/100;return t===0?`0`:String(t)}function Et(e){return`(${e.replace(/[\\()]/g,`\\$&`)})`}function Dt(e){if(/^[\x20-\x7e]*$/.test(e))return Et(e);let t=`FEFF`;for(let n=0;n<e.length;n++)t+=e.charCodeAt(n).toString(16).toUpperCase().padStart(4,`0`);return`<${t}>`}function Ot(e){let t=e.getTime();if(!Number.isFinite(t))return;let n=new Date(t).toISOString();return`D:${n.slice(0,4)}${n.slice(5,7)}${n.slice(8,10)}${n.slice(11,13)}${n.slice(14,16)}${n.slice(17,19)}Z`}function kt(e){return`<< /Length ${e.length} >>\nstream\n${e}\nendstream`}function At(e,t,n){let r=[`%PDF-1.7
|
|
3
3
|
%âãÏÓ
|
|
4
|
-
`],i=r[0].length,a=`xref\n0 ${e.length+1}\n0000000000 65535 f \n`;e.forEach((e,t)=>{let n=`${t+1} 0 obj\n${e}\nendobj\n`;a+=`${String(i).padStart(10,`0`)} 00000 n \n`,r.push(n),i+=n.length});let o=n===void 0?``:` /Info ${n} 0 R`;r.push(`${a}trailer\n<< /Size ${e.length+1} /Root ${t} 0 R${o} >>\nstartxref\n${i}\n%%EOF\n`);let s=r.join(``),c=new Uint8Array(s.length);for(let e=0;e<s.length;e++)c[e]=s.charCodeAt(e);return c}function
|
|
5
|
-
`)}const
|
|
6
|
-
`))}function
|
|
4
|
+
`],i=r[0].length,a=`xref\n0 ${e.length+1}\n0000000000 65535 f \n`;e.forEach((e,t)=>{let n=`${t+1} 0 obj\n${e}\nendobj\n`;a+=`${String(i).padStart(10,`0`)} 00000 n \n`,r.push(n),i+=n.length});let o=n===void 0?``:` /Info ${n} 0 R`;r.push(`${a}trailer\n<< /Size ${e.length+1} /Root ${t} 0 R${o} >>\nstartxref\n${i}\n%%EOF\n`);let s=r.join(``),c=new Uint8Array(s.length);for(let e=0;e<s.length;e++)c[e]=s.charCodeAt(e);return c}function jt(e){let t,n;return Array.isArray(e)?[t,n]=e:typeof e==`object`&&e&&({x:t,y:n}=e),typeof t==`number`&&typeof n==`number`&&Number.isFinite(t)&&Number.isFinite(n)?[t,n]:void 0}function Mt(e){let t=e?.strokes;if(!Array.isArray(t))return[];let n=[],r=2e4;for(let e of t){if(!Array.isArray(e)||r<=0)continue;let t=[];for(let n of e){let e=jt(n);e&&r>0&&(t.push(e),r--)}t.length>0&&n.push(t)}return n}function Nt(e,t){let n=Mt(e);if(n.length===0)return``;let r=e,i=typeof r.w==`number`&&Number.isFinite(r.w)&&r.w>0?r.w:0,a=typeof r.h==`number`&&Number.isFinite(r.h)&&r.h>0?r.h:0;if(i===0||a===0){for(let e of n)for(let[t,n]of e)i=Math.max(i,t),a=Math.max(a,n);i=Math.max(i,1),a=Math.max(a,1)}let o=Math.min(t.width/i,t.height/a),s=(t.height-a*o)/2,c=e=>j(t.x+Math.min(i,Math.max(0,e))*o),l=e=>j(t.top-s-Math.min(a,Math.max(0,e))*o),u=[`q 0.05 0.1 0.45 RG 1.2 w 1 J 1 j`];for(let e of n){let[t]=e;u.push(`${c(t[0])} ${l(t[1])} m`),e.length===1&&u.push(`${c(t[0])} ${l(t[1])} l`);for(let t=1;t<e.length;t++){let[n,r]=e[t];u.push(`${c(n)} ${l(r)} l`)}u.push(`S`)}return u.push(`Q`),u.join(`
|
|
5
|
+
`)}const Pt=St(` `);function M(e,t,n,r){let i=n*1e3+1e-6,a=Ct(r),o=wt(Pt,r),s=[],c=[];for(let n of e.split(/\r\n|\r|\n/)){let e=/[\ud800-\udfff]/.test(n)?Array.from(n):void 0,r=(t,r)=>e?e.slice(t,r).join(``):n.slice(t,r),l=St(n),u=0,d=0,f=()=>{let e=c.length/2,n=c[0]??0,i=c[c.length-1]??0,a=e>0&&i-n===d+e-1,o,f;if(a)o=r(n,i),f=l.slice(n,i);else{let e=[],t=[];for(let n=0;n<c.length;n+=2)e.push(r(c[n],c[n+1])),t.push(l.slice(c[n],c[n+1]));o=e.join(` `),f=t.join(Pt)}s.push({text:o,bytes:f,width:u*t/1e3}),c.length=0,u=0,d=0},p=s.length;for(let e=0;e<l.length;){if(l.charCodeAt(e)===32){e++;continue}let n=e,r=l.indexOf(` `,n),s=r===-1?l.length:r;e=s;let p=0;for(let e=n;e<s;e++)p+=a[l.charCodeAt(e)];if(c.length>0&&(u+o+p)*t<=i){c.push(n,s),u+=o+p,d+=s-n;continue}if(c.length>0&&f(),p*t<=i){c.push(n,s),u=p,d=s-n;continue}for(;n<s;){let e=n,r=0;for(;e<s;){let o=a[l.charCodeAt(e)];if(e>n&&(r+o)*t>i)break;r+=o,e++}c.length=0,c.push(n,e),u=r,d=e-n,e<s&&f(),n=e}}(c.length>0||s.length===p)&&f()}return s}const Ft={width:595.28,height:841.89},It=1.3,Lt={1:18,2:13,3:11},Rt=Object.fromEntries(ht.map(e=>[e.font,e.resource])),N=(e,t)=>typeof e==`number`&&Number.isFinite(e)&&e>0?e:t,zt=(e,t)=>typeof e==`number`&&Number.isFinite(e)&&e>=0?e:t,P=e=>typeof e==`string`?e:e==null?``:String(e),Bt=e=>e===`bold`||e===`italic`?e:`regular`;function Vt(e){let t=Math.round(N(e?.width,Ft.width)*100)/100,n=Math.round(N(e?.height,Ft.height)*100)/100,r=e?.margin,i=e=>zt(typeof r==`number`?r:typeof r==`object`&&r?r[e]:void 0,56),a={top:i(`top`),right:i(`right`),bottom:i(`bottom`),left:i(`left`)};if(t-a.left-a.right<72||n-a.top-a.bottom<72){let e=Math.max(0,Math.min((t-72)/2,(n-72)/2,56));a={top:e,right:e,bottom:e,left:e}}return{width:t,height:n,margin:a}}var Ht=class{pages=[];ops=[];y;left;right;bottom;constructor(e){this.g=e,this.left=e.margin.left,this.right=e.width-e.margin.right,this.bottom=e.height-e.margin.bottom,this.y=e.margin.top,this.pages.push(this.ops)}get contentWidth(){return this.right-this.left}get atTop(){return this.y<=this.g.margin.top}newPage(){this.ops=[],this.pages.push(this.ops),this.y=this.g.margin.top}ensure(e){this.y+e>this.bottom+1e-6&&!this.atTop&&this.newPage()}pdfY(e){return j(this.g.height-e)}text(e,t,n,r,i){i.length!==0&&this.ops.push(`BT /${Rt[r]} ${j(n)} Tf ${j(e)} ${this.pdfY(t+n)} Td ${Et(i)} Tj ET`)}alignX(e,t,n=this.left,r=this.contentWidth){return t===`center`?n+(r-e.width)/2:t===`right`?n+r-e.width:n}paragraph(e,t,n,r,i){let a=t*It;for(let i of M(e,t,this.contentWidth,n))this.ensure(a),this.text(this.alignX(i,r),this.y,t,n,i.bytes),this.y+=a;this.y+=i}heading(e,t){let n=Lt[t],r=M(e,n,this.contentWidth,`bold`),i=this.atTop?0:n*.6;this.ensure(i+r.length*n*It+n*.4+20*It),this.atTop||(this.y+=i),this.paragraph(e,n,`bold`,`left`,n*.4)}spacer(e){this.y+=e,this.y>this.bottom&&this.newPage()}rule(){this.ensure(12);let e=this.pdfY(this.y+6);this.ops.push(`0.75 w 0.6 G ${j(this.left)} ${e} m ${j(this.right)} ${e} l S 0 G`),this.y+=12}pageBreak(){this.atTop||this.newPage()}table(e,t,n){if(e.length===0)return;let r=e.map(e=>N(e.width,1)),i=r.reduce((e,t)=>e+t,0),a=[],o=r.map(e=>this.contentWidth*e/i);o.reduce((e,t)=>(a.push(e),e+t),this.left);let s=n*It,c=(e,t)=>o.map((r,i)=>M(P(e[i]),n,r-8,t)),l=c(e.map(e=>e.header),`bold`),u=e=>Math.max(1,...e.map(e=>e.length)),d=u(l)*s+8,f=(e,t,r,i,c)=>{let l=r*s+8,u=this.pdfY(this.y+l);c&&this.ops.push(`0.92 g ${j(this.left)} ${u} ${j(this.contentWidth)} ${j(l)} re f 0 g`),this.ops.push(`0.5 w 0.7 G`);for(let e=0;e<o.length;e++)this.ops.push(`${j(a[e])} ${u} ${j(o[e])} ${j(l)} re S`);this.ops.push(`0 G`),e.forEach((e,o)=>{for(let c=0;c<r;c++){let r=e[t+c];r&&this.text(a[o]+4,this.y+4+c*s,n,i,r.bytes)}}),this.y+=l},p=()=>f(l,0,u(l),`bold`,!0);this.ensure(d+s+8),p();let m=!0;for(let e of t){let t=c(Array.isArray(e)?e:[],`regular`),n=u(t),r=0;for(;r<n;){let e=Math.floor((this.bottom-this.y-8+1e-6)/s),i=n-r;if(e>=i){f(t,r,i,`regular`,!1),m=!1;break}if(m){let i=Math.max(1,e);if(f(t,r,i,`regular`,!1),r+=i,r>=n)break}this.newPage(),p(),m=!0}}this.y+=10*.5}signature(e){let t=Math.min(N(e.width,220),this.contentWidth),n=N(e.height,70),r=M(P(e.label),9,this.contentWidth,`regular`).filter(e=>e.bytes),i=(Array.isArray(e.caption)?e.caption:[]).flatMap(e=>M(P(e),9,this.contentWidth,`regular`)).filter(e=>e.bytes),a=9*It;this.ensure(r.length*a+n+4+i.length*a);for(let e of r)this.text(this.left,this.y,9,`regular`,e.bytes),this.y+=a;let o=this.y,s=M(P(e.typedName),20,t,`italic`)[0];s?.bytes&&this.text(this.left+4,o+n-28,20,`italic`,s.bytes);let c=Nt(e.strokes,{x:this.left,top:this.g.height-o,width:t,height:n});c&&this.ops.push(c),this.y=o+n+2;let l=this.pdfY(this.y);this.ops.push(`0.5 w 0.4 G ${j(this.left)} ${l} m ${j(this.left+t)} ${l} l S 0 G`),this.y+=2;for(let e of i)this.text(this.left,this.y,9,`regular`,e.bytes),this.y+=a;this.y+=12}block(e){switch(e.type){case`heading`:this.heading(P(e.text),e.level===2||e.level===3?e.level:1);break;case`paragraph`:{let t=N(e.size,10),n=e.align===`center`||e.align===`right`?e.align:`left`;this.paragraph(P(e.text),t,Bt(e.font),n,t*.5);break}case`spacer`:this.spacer(zt(e.height,0));break;case`rule`:this.rule();break;case`pageBreak`:this.pageBreak();break;case`table`:this.table(Array.isArray(e.columns)?e.columns:[],Array.isArray(e.rows)?e.rows:[],N(e.size,9));break;case`signature`:this.signature(e);break}}footer(e){if(!e)return;let t=P(e.text),n=this.pages.length;this.pages.forEach((r,i)=>{let a=[t,e.pageNumbers?`Page ${i+1} of ${n}`:``].filter(Boolean);if(a.length===0)return;let[o]=M(a.join(` · `),8,this.contentWidth,`regular`),s=this.alignX(o,`center`),c=this.g.margin.bottom/2;r.push(`BT /F1 8 Tf ${j(s)} ${j(c)} Td ${Et(o.bytes)} Tj ET`)})}};function Ut(e,t,n){let r=new Ht(e);for(let e of Array.isArray(t)?t:[])e&&typeof e==`object`&&r.block(e);return r.footer(n),r.pages.map(e=>e.join(`
|
|
6
|
+
`))}function Wt(e){let t=[],n=(e,n)=>{typeof n==`string`&&n!==``&&t.push(`/${e} ${Dt(n)}`)};if(n(`Title`,e?.title),n(`Author`,e?.author),n(`Subject`,e?.subject),n(`Keywords`,e?.keywords),n(`Creator`,e?.creator),n(`Producer`,`semics pdf`),e?.creationDate instanceof Date){let n=Ot(e.creationDate);n&&t.push(`/CreationDate (${n})`)}return`<< ${t.join(` `)} >>`}function Gt(e){let t=Vt(e.page),n=Ut(t,e.blocks,e.footer),r=[`<< /Type /Catalog /Pages 2 0 R >>`,``,Wt(e.info)],i=ht.map(e=>(r.push(`<< /Type /Font /Subtype /Type1 /BaseFont /${e.baseFont} /Encoding /WinAnsiEncoding >>`),`/${e.resource} ${r.length} 0 R`)).join(` `),a=`[0 0 ${j(t.width)} ${j(t.height)}]`,o=[];for(let e of n){r.push(kt(e));let t=r.length;r.push(`<< /Type /Page /Parent 2 0 R /MediaBox ${a} /Resources << /Font << ${i} >> >> /Contents ${t} 0 R >>`),o.push(`${r.length} 0 R`)}return r[1]=`<< /Type /Pages /Kids [${o.join(` `)}] /Count ${o.length} >>`,At(r,1,3)}async function Kt(e,t){let n=await crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(`${t}:${e}`));return S(new Uint8Array(n).slice(0,16))}async function qt(e,t,n,r){let i=Math.floor(n/(r.windowSeconds*1e3)),a=`rl:${r.scope}:${await Kt(t,r.salt)}:${i}`,o=Number.parseInt(await e.get(a)??`0`,10),s=Number.isFinite(o)&&o>0?o:0;return s>=r.limit?T(`RATE_LIMITED`):(await e.set(a,`${s+1}:${(i+1)*r.windowSeconds}`,{ttlSeconds:r.windowSeconds*2}),w({remaining:r.limit-s-1}))}async function Jt(e,t,n){let r=(await e.list(`rl:`)).filter(({value:e})=>!(Number(String(e).split(`:`)[1])*1e3>t)).map(({key:e})=>e);for(let t of r.slice(0,n))await e.delete(t);return{calls:1+Math.min(n,r.length),more:r.length>n}}const Yt=`cron:scheduled:v11`,Xt=`ensure-schedules`;async function Zt(e,t){try{if(await e.kv.get(Yt))return;await e.cron?.schedule(Xt,{schedule:new Date(t).toISOString()})}catch{}}async function Qt(e,t){let n=e.cron;if(!n)return!1;for(let e of t)await n.schedule(e.name,{schedule:e.schedule});return!0}async function $t(e,t,n){await Qt(e,t)&&await e.kv.set(Yt,{at:new Date(n).toISOString()})}async function en(e,t,n,r){return e.name===Xt?(await $t(t,n,r),!0):!1}function tn(e){return typeof e==`object`&&!!e&&e.type===`page_load`}function nn(e,t=()=>!0,n=Date.now){let r=e.handler,i=async(e,i)=>(t(e?.input)&&await Zt(i,n()),r(e,i));return{...e,handler:i}}var rn=class extends Error{code=`TEMPLATE_MISSING_FIELD`;constructor(e){super(`Template field "${e}" has no value`),this.field=e,this.name=`TemplateError`}};const an=/\{\{\s*([A-Za-z_][A-Za-z0-9_.]*)\s*\}\}/g,on={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`};function sn(e){return e.replace(/\s*[\r\n]+\s*/g,` `).replace(/[\\&<>"'#[\]()*_`~|{}+!-]/g,e=>on[e]??`\\${e}`)}function cn(e){return[...new Set([...e.matchAll(an)].map(e=>e[1]))]}function ln(e,t){return e.replace(an,(e,n)=>{let r=Object.hasOwn(t,n)?t[n]:void 0;if(r===void 0)throw new rn(n);return sn(String(r))})}function un(e){return`${e.replace(/^/,``).replace(/\r\n?/g,`
|
|
7
7
|
`).normalize(`NFC`).split(`
|
|
8
8
|
`).map(e=>e.replace(/[ \t]+$/,``)).join(`
|
|
9
|
-
`).replace(/\n+$/,``)}\n`}async function F(e){let t=typeof e==`string`?new TextEncoder().encode(e):new Uint8Array(e);return S(await crypto.subtle.digest(`SHA-256`,t))}const
|
|
9
|
+
`).replace(/\n+$/,``)}\n`}async function F(e){let t=typeof e==`string`?new TextEncoder().encode(e):new Uint8Array(e);return S(await crypto.subtle.digest(`SHA-256`,t))}const dn={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`},fn=e=>e.replace(/[&<>"']/g,e=>dn[e]),pn=e=>e.replace(/\s*[\r\n]+\s*/g,` `),mn=/\{\{(\w+)\}\}/g;function hn(e,t,n){return e.replace(mn,(e,r)=>n(t[r]??``))}const gn=`January February March April May June July August September October November December`.split(` `);function _n(e){let t=new Date(e);return`${t.getUTCDate()} ${gn[t.getUTCMonth()]} ${t.getUTCFullYear()}`}function vn(e,t,n){let r=Object.fromEntries(Object.entries(n).map(([e,t])=>[e,pn(t)]));return{to:e,subject:hn(t.subject,r,e=>e),text:hn(t.text,r,e=>e),html:hn(t.html,r,fn)}}function yn(e){let t=e.expiresAt?`This request expires on ${_n(e.expiresAt)}.`:``;return vn(e.to,{subject:`{{sender}} asks you to sign: {{title}}`,text:`Hello {{name}},
|
|
10
10
|
|
|
11
11
|
{{sender}} has asked you to review and sign "{{title}}" electronically.{{expiry}}
|
|
12
12
|
|
|
@@ -17,22 +17,22 @@ This link is personal to you. Please do not forward it.
|
|
|
17
17
|
`,html:`<p>Hello {{name}},</p>
|
|
18
18
|
<p>{{sender}} has asked you to review and sign "{{title}}" electronically.{{expiry}}</p>
|
|
19
19
|
<p><a href="{{link}}">Review and sign the document</a></p>
|
|
20
|
-
<p>This link is personal to you. Please do not forward it.</p>`},{name:e.signerName,title:e.title,sender:e.sender,link:e.link,expiry:t?` ${t}`:``})}function
|
|
20
|
+
<p>This link is personal to you. Please do not forward it.</p>`},{name:e.signerName,title:e.title,sender:e.sender,link:e.link,expiry:t?` ${t}`:``})}function bn(e){return vn(e.to,{subject:`Signed: {{title}}`,text:`Hello {{name}},
|
|
21
21
|
|
|
22
22
|
Thank you. "{{title}}" for {{sender}} is now signed.
|
|
23
23
|
Get your signed copy here (the page issues a fresh download link each time):
|
|
24
24
|
{{link}}
|
|
25
25
|
`,html:`<p>Hello {{name}},</p>
|
|
26
26
|
<p>Thank you. "{{title}}" for {{sender}} is now signed.</p>
|
|
27
|
-
<p><a href="{{link}}">Get your signed copy</a> (the page issues a fresh download link each time).</p>`},{name:e.signerName,title:e.title,sender:e.sender,link:e.link})}const
|
|
27
|
+
<p><a href="{{link}}">Get your signed copy</a> (the page issues a fresh download link each time).</p>`},{name:e.signerName,title:e.title,sender:e.sender,link:e.link})}const xn=`outbox-drain`;function Sn(e){let t=e.storage.outbox;return{put:(e,n)=>t.put(e,n),putMany:e=>t.putMany([...e]),query:({status:e,nextAttemptAtLte:n,limit:r})=>t.query({where:{status:e,...n===void 0?{}:{nextAttemptAt:{lte:n}}},orderBy:{nextAttemptAt:`asc`},limit:r})}}function Cn(e){try{let{origin:t}=new URL(e.site.url);return t===`null`?``:t}catch{return``}}const wn=(e,t)=>typeof t==`string`&&t.trim()!==``?t.trim():e.site.name,Tn=`The site URL is not set, so signing invitations and signed-copy emails are not queued (their links would not work). Set the site URL in EmDash's settings, then use Resend invitation.`;async function En(e,t){let{signerId:n,envelope:r,token:i,now:a}=t,o=Cn(e);if(!o)return null;let s=yn({to:r.signer.email,signerName:r.signer.name,title:r.title,sender:wn(e,t.senderSetting),link:`${o}/sign/${i}`,expiresAt:r.expiresAt});return ot(Sn(e),s,a,()=>`invite-${n}`)}async function Dn(e,t){let n=Cn(e);if(!n)return null;let r={to:t.envelope.signer.email,signerName:t.envelope.signer.name,title:t.envelope.title,sender:wn(e,t.senderSetting),link:`${n}/signed/${t.token}`};return ot(Sn(e),bn(r),t.now,()=>`complete-${t.envelopeId}`)}async function On(e,t,n=Date.now()){if(e.name!==xn)return!1;let r=await ct({storage:Sn(t),email:t.email,now:n});return r.gaveUp>0&&t.log.error(`emails given up after repeated failures`,{count:r.gaveUp}),!0}async function kn(e){return lt({storage:Sn(e),email:e.email,now:Date.now()})}const An=`0`.repeat(64);function jn(e=b){return S(e(32))}function Mn(e,t){return F(e+t)}function Nn(e,t){return`${e}:a${String(t).padStart(6,`0`)}`}const Pn=e=>Object.keys(e).sort().map(t=>[t,e[t]]);function Fn(e){let t=JSON.stringify([1,e.envelopeId,e.seq,e.type,e.at,e.actor,Pn(e.data),Pn(e.commitments)]);return F(e.prevHash+t)}async function In(e,t,n,r){let i=Object.entries(n.personal??{}).filter(e=>typeof e[1]==`string`),a={};for(let[e,t]of i)a[e]=await Mn(r,t);let o={envelopeId:e,seq:t?t.seq+1:0,type:n.type,at:n.at,actor:n.actor,data:{...n.data},commitments:a,prevHash:t?t.hash:An};return{...o,personal:i.length>0?Object.fromEntries(i):null,hash:await Fn(o)}}function Ln(e,t,n){return Rn(e,null,t,n)}async function Rn(e,t,n,r){let i=[],a=t;for(let t of n){let n=await In(e,a,t,r);i.push({id:Nn(e,n.seq),data:n}),a=n}return i}async function zn(e,t,n,r){let i=r.attempts??2;for(let a=0;a<i;a++){let{items:i}=await e.query({where:{envelopeId:t},orderBy:{seq:`desc`},limit:1}),a=await In(t,i[0]?.data??null,n,r.salt);if((await e.compareAndSet(Nn(t,a.seq),null,a)).applied)return w(a)}return T(`CONFLICT`)}async function Bn(e,t){let{items:n}=await e.query({where:{envelopeId:t},orderBy:{seq:`desc`},limit:1});return n[0]?.data??null}async function Vn(e,t){let[n,...r]=t;return n?(await e.compareAndSet(n.id,null,n.data)).applied?(r.length>0&&await e.putMany(r),!0):!1:!0}async function Hn(e,t){for(let[n,r]of Object.entries(e.personal??{}))if(e.commitments[n]!==await Mn(t,r))return!1;return!0}async function Un(e,t,n={}){let r=An;for(let[i,a]of t.entries()){let t=e=>T({seq:i,reason:e});if(a.envelopeId!==e)return t(`ENVELOPE`);if(a.seq!==i)return t(`SEQ`);if(await Fn(a)!==a.hash)return t(`HASH`);if(a.prevHash!==r)return t(`PREV_HASH`);if(n.salt!==void 0&&!await Hn(a,n.salt))return t(`COMMITMENT`);r=a.hash}return n.head!==void 0&&n.head!==r?T({seq:t.length,reason:`HEAD`}):w({head:r,length:t.length})}function Wn(e){return{...e,personal:null}}function Gn(e,t){return F(`esign-final/1\n${e}\n${t}`)}const Kn=[`draft`,`sent`,`in_progress`,`completed`,`declined`,`voided`,`expired`],qn=[`declined`,`voided`,`expired`],Jn=Object.freeze({draft:[`sent`,`voided`],sent:[`in_progress`,`completed`,...qn],in_progress:[`completed`,...qn],completed:[],declined:[],voided:[],expired:[]});function Yn(e){return typeof e==`string`&&Kn.includes(e)}function Xn(e,t){return Yn(e)&&Yn(t)&&Jn[e].includes(t)}function Zn(e){return Jn[e].length===0}async function I(e,t,n,r,i={}){if(!Xn(n,r))return T(`ILLEGAL_TRANSITION`);let a=await e.updateIf(t,{where:{status:n},set:{...i,status:r}});return a.applied?w(a.data):T(`CONFLICT`)}const L=(e,t)=>`${e}:v${t}`;function Qn(e){if(typeof e!=`object`||!e||Array.isArray(e))return T([{path:``,code:`INVALID_INPUT`}]);let{name:t,body:n,description:r,integrations:i}=e,a=[],o=typeof t==`string`?t.trim():``;return(o.length===0||o.length>200)&&a.push({path:`name`,code:`INVALID_NAME`}),(typeof n!=`string`||n.trim().length===0||n.length>1e5)&&a.push({path:`body`,code:`INVALID_BODY`}),r!==void 0&&(typeof r!=`string`||r.length>1e3)&&a.push({path:`description`,code:`INVALID_DESCRIPTION`}),i!==void 0&&typeof i!=`boolean`&&a.push({path:`integrations`,code:`INVALID_INTEGRATIONS`}),a.length>0?T(a):w({name:o,body:n,...typeof r==`string`&&r!==``?{description:r}:{},...typeof i==`boolean`?{integrations:i}:{}})}function $n(e,t){return{...e,status:`version`,templateId:t}}function er(e,t){let n=Qn(e);if(!n.ok)return n;let r={name:n.value.name,...n.value.description===void 0?{}:{description:n.value.description},kind:`text`,status:`active`,public:!1,integrations:n.value.integrations??!1,version:1,body:n.value.body,fields:cn(n.value.body),createdAt:t.now,updatedAt:t.now};return w({head:r,versions:[{id:L(t.id,1),data:$n(r,t.id)}]})}function tr(e,t,n){if(e.status===`archived`)return T([{path:``,code:`TEMPLATE_ARCHIVED`}]);let r=Qn(t);if(!r.ok)return r;let{description:i,...a}=e,o={...a,...r.value.description===void 0?{}:{description:r.value.description},name:r.value.name,body:r.value.body,fields:cn(r.value.body),integrations:r.value.integrations??e.integrations===!0,version:e.version+1,updatedAt:n.now};return w({head:o,version:{id:L(n.id,o.version),data:$n(o,n.id)}})}function nr(e,t){return e.status===`archived`?e:{...e,status:`archived`,updatedAt:t}}function rr(e){return e?.status===`active`&&e.integrations===!0}function ir(e){return e.status===`active`?w(e):T(`TEMPLATE_NOT_FOUND`)}const ar=/[\u0000-\u001F\u007F]/,or=/^[^\s@]+@[^\s@]+\.[^\s@]+$/,sr=/^[A-Za-z0-9_]{1,64}$/,cr=(e,t)=>`${e}:s${t}`,lr=e=>typeof e==`object`&&!!e&&!Array.isArray(e),ur=e=>typeof e==`string`&&e.length>0&&e.length<=200&&!e.includes(`:`);function dr(e){let t=typeof e==`string`?e.trim():``;return t.length>0&&t.length<=200&&!ar.test(t)?t:null}function fr(e){let t=typeof e==`string`?e.trim().toLowerCase():``;return t.length<=254&&or.test(t)?t:null}function pr(e){if(e===void 0)return{};if(!lr(e))return null;let t=Object.entries(e);if(t.length>32)return null;let n={};for(let[e,r]of t){if(!sr.test(e)||typeof r!=`string`||[...r].length>500)return null;n[e]=r}return n}function mr(e){if(e===void 0)return[];if(!Array.isArray(e)||e.length>16)return null;let t=[];for(let n of e){if(!lr(n)||typeof n.key!=`string`||!sr.test(n.key)||t.some(e=>e.key===n.key))return null;let e=typeof n.label==`string`?n.label.trim():``;if(e===``||[...e].length>100||ar.test(e)||n.required!==void 0&&typeof n.required!=`boolean`)return null;t.push({key:n.key,label:e,...n.required?{required:!0}:{}})}return t}function hr(e){if(!lr(e))return T([{path:``,code:`INVALID_INPUT`}]);let{templateId:t,templateVersion:n,title:r,signer:i,fields:a}=e,o=[];ur(t)||o.push({path:`templateId`,code:`INVALID_TEMPLATE_ID`}),n!==void 0&&!(Number.isSafeInteger(n)&&n>=1)&&o.push({path:`templateVersion`,code:`INVALID_VERSION`});let s=typeof r==`string`?r.trim():void 0;r!==void 0&&!(s&&s.length<=200&&!ar.test(s))&&o.push({path:`title`,code:`INVALID_TITLE`});let c=lr(i)?i:{},l=dr(c.name),u=fr(c.email);l===null&&o.push({path:`signer.name`,code:`INVALID_SIGNER_NAME`}),u===null&&o.push({path:`signer.email`,code:`INVALID_SIGNER_EMAIL`});let d=pr(a);d===null&&o.push({path:`fields`,code:`INVALID_FIELDS`});let f=mr(e.signerFields);return f===null&&o.push({path:`signerFields`,code:`INVALID_FIELDS`}),o.length>0?T(o):w({templateId:t,...n===void 0?{}:{templateVersion:n},...s===void 0?{}:{title:s},signer:{name:l,email:u,as:`self`},fieldValues:d,...f&&f.length>0?{signerFields:f}:{}})}function gr(e,t,n){let r=e?ir(e):T(`TEMPLATE_NOT_FOUND`);return!r.ok||n===void 0?r:t?.status===`version`&&t.version===n?w(t):T(`TEMPLATE_NOT_FOUND`)}function _r(e){let{signer:t}=e;return{...e.fieldValues,"signer.name":t.name,"signer.email":t.email,...t.participant?{"participant.name":t.participant.name}:{}}}function vr(e,t){let n=_r(e);return cn(t).filter(e=>!Object.hasOwn(n,e)).map(e=>({path:`fields.${e}`,code:`MISSING_FIELD`}))}function yr(e,t,n){let{title:r,...i}=e,a={title:r??t.name,templateVersion:t.version,status:`draft`,routing:`parallel`,...i,signerEmail:i.signer.email.toLowerCase(),signerIds:[],docSha256:null,snapshot:null,expiresAt:null,sentAt:null,completedAt:null,finalHash:null,piiSalt:n.piiSalt,createdAt:n.now,updatedAt:n.now},o=vr(a,t.body);return o.length>0?T(o):w(a)}function br(e,t,n){return yr({templateId:e.templateId,signer:e.signer,fieldValues:e.fieldValues,delivery:`email`,...e.title===void 0?{}:{title:e.title},...e.signerFields?{signerFields:e.signerFields}:{}},t,n)}function xr(e,t,n){let r=Sr(e),i={name:e.signer.name.trim(),email:e.signer.email.trim().toLowerCase(),as:e.as??`self`,...e.participant?{participant:{name:e.participant.name.trim()}}:{}};return yr({templateId:e.tpl,signer:i,fieldValues:{...e.prefill},delivery:e.delivery??`inline`,clientId:e.cid,externalRef:e.ref,returnUrl:e.returnUrl,...r===void 0?{}:{signBy:r}},t,n)}function Sr(e){let{signBy:t,iat:n}=e;return Number.isSafeInteger(t)&&t>n?t:void 0}function Cr(e,t,n){let r=Date.parse(e)+t*864e5;return A(n===void 0?r:Math.min(r,(n+60)*1e3))}function wr(e){let t=0;for(let n=e.indexOf(`
|
|
28
28
|
`);n!==-1;n=e.indexOf(`
|
|
29
|
-
`,n+1))t++;return t}async function
|
|
30
|
-
`,"`",`*`,`_`,`[`,`!`,`<`]),
|
|
31
|
-
`){o(),i.push({type:`break`}),s++;continue}let l=n<6?this.markup(s,t,n):void 0;l?.inline?(o(),i.push(l.inline)):a+=l?l.text:e,s=l?l.end:s+1}return o(),i}markup(e,t,n){let r=this.src[e];if(r==="`")return this.codeSpan(e,t);if(r===`*`||r===`_`)return this.emphasis(e,t,n);if(r===`[`)return this.link(e,t,n,!1);if(r===`!`&&this.src[e+1]===`[`)return this.link(e+1,t,n,!0);if(r===`<`)return this.autolink(e,t)}next(e,t,n,r){let i=this.memo.get(e);if(i&&t>=i.from&&(i.at===-1||t<=i.at))return i.at;let a=n(t);for(;a!==-1&&!r(a);)a=n(a+1);return this.memo.set(e,{from:t,at:a}),a}escaped(e){let t=0;for(let n=e-1;n>=0&&this.src[n]===`\\`;n--)t++;return t%2==1}codeSpan(e,t){let{src:n}=this,r=1;for(;n[e+r]==="`";)r++;let i="`".repeat(r),a=this.next(`code${r}`,e+r,e=>n.indexOf(i,e),e=>n[e-1]!=="`"&&n[e+r]!=="`");return a===-1||a+r>t?{text:i,end:e+r}:{inline:{type:`code`,text:
|
|
32
|
-
`))});continue}if(
|
|
33
|
-
`)))});continue}let l=[i.trim()];for(r++;r<e.length&&!
|
|
34
|
-
`))})}return n}function
|
|
29
|
+
`,n+1))t++;return t}async function Tr(e,t){let n;try{n=ln(t,_r(e))}catch(e){if(e instanceof rn)return T([{path:`fields.${e.field}`,code:`MISSING_FIELD`}]);throw e}let r=un(n);return r.length>131072||wr(r)>1500?T([{path:`body`,code:`DOCUMENT_TOO_LARGE`}]):w({text:r,docSha256:await F(r)})}const Er=e=>e>=55296&&e<=56319;function Dr(e,t,n){let r=[];for(let e=0;e<t.length;){let n=Math.min(e+65536,t.length);n<t.length&&Er(t.charCodeAt(n-1))&&n--,r.push(t.slice(e,n)),e=n}let i=`${e}:${n.slice(0,16)}`;return r.map((t,a)=>({id:`${i}:${a}`,data:{envelopeId:e,contentType:`text/markdown`,index:a,count:r.length,data:t,sha256:n}}))}function Or(e){let t=e[0];if(!t||e.length!==t.count)return null;let n=[...e].sort((e,t)=>e.index-t.index);return n.every((e,n)=>e.index===n&&e.count===t.count&&e.sha256===t.sha256)?n.map(e=>e.data).join(``):null}async function kr(e,t,n,r){if(!Xn(t.status,`sent`))return T(`ILLEGAL_TRANSITION`);if(n.version!==t.templateVersion)return T(`TEMPLATE_MISMATCH`);let i=await Tr(t,n.body);if(!i.ok)return i;let{text:a,docSha256:o}=i.value,s=Dr(e,a,o),c=cr(e,1),{signer:l}=t;return w({envelope:{...t,status:`sent`,docSha256:o,snapshot:{ids:s.map(e=>e.id),length:a.length},signerIds:[c],sentAt:r.now,expiresAt:Cr(r.now,r.expiryDays,t.signBy),updatedAt:r.now},chunks:s,signer:{id:c,data:{envelopeId:e,order:1,role:`signer`,name:l.name,email:l.email,as:l.as,...l.participant?{participant:l.participant}:{},status:`pending`,tokenHash:r.tokenHash,createdAt:r.now}}})}const Ar=[`declined`,`voided`,`expired`];function jr(e){return e.find(e=>!Ar.includes(e.data.status))}async function Mr(e,t,n){return`env_${(await F(`${e}\n${t}`)).slice(0,32)}_${n}`}function Nr(e,t,n){let{signer:r,clientId:i,externalRef:a}=e;return{type:`envelope.created`,at:e.createdAt,actor:t,data:{source:t===`admin`?`admin`:`intent`,templateId:e.templateId,templateVersion:e.templateVersion,title:e.title,delivery:e.delivery,as:r.as,...i===void 0?{}:{clientId:i},...a===void 0?{}:{externalRef:a},...n?{userId:n}:{}},personal:{name:r.name,email:r.email,...r.participant?{participant:r.participant.name}:{}}}}function Pr(e,t,n){return{type:`envelope.sent`,at:e.updatedAt,actor:t,data:{docSha256:e.docSha256,expiresAt:e.expiresAt,signerIds:e.signerIds.join(`,`),...n?{userId:n}:{}},personal:{email:e.signer.email}}}function Fr(e={}){let t=[];return new Headers(e.headers).forEach((e,n)=>t.push([n,e])),{__emdashPluginResponse:!0,status:e.status??200,headers:t,body:e.body??null}}const Ir={amp:`&`,lt:`<`,gt:`>`,quot:`"`,"#39":`'`},Lr=/^&(amp|lt|gt|quot|#39);/,Rr=/[!-/:-@[-`{-~]/,zr=/[\p{L}\p{N}]/u,Br=/[\s"'<>`\\\u0000-\u001F\u007F]/,Vr=/^(https?:\/\/|mailto:)/i,Hr=new Set([`\\`,`&`,`
|
|
30
|
+
`,"`",`*`,`_`,`[`,`!`,`<`]),Ur=/[\\&\n`*_[!<]/g;function Wr(e){if(!(e.length===0||Br.test(e)||!Vr.test(e)))try{return new URL(e).href}catch{return}}function Gr(e){return e.replace(/\\([!-/:-@[-`{-~])|&(amp|lt|gt|quot|#39);/g,(e,t,n)=>t===void 0?Ir[n]:t)}function Kr(e){let t=new Map,n={"]":[],")":[]},r={"[":`]`,"(":`)`},i=/[\\[\]()]/g;for(let a=i.exec(e);a;a=i.exec(e)){let e=a.index,o=a[0];if(o===`\\`)i.lastIndex=e+2;else if(o in r)n[r[o]]?.push(e);else{let r=n[o]?.pop();r!==void 0&&t.set(r,e)}}return t}var qr=class{partner;memo=new Map;constructor(e){this.src=e,this.partner=Kr(e)}parse(e,t,n){let{src:r}=this,i=[],a=``,o=()=>{a&&i.push({type:`text`,text:a}),a=``},s=e;for(;s<t;){let e=r[s];if(!Hr.has(e)){Ur.lastIndex=s;let e=Ur.exec(r),n=e&&e.index<t?e.index:t;a+=r.slice(s,n),s=n;continue}if(e===`\\`&&s+1<t&&Rr.test(r[s+1])){a+=r[s+1],s+=2;continue}let c=e===`&`?Lr.exec(r.slice(s,Math.min(t,s+6))):null;if(c){a+=Ir[c[1]],s+=c[0].length;continue}if(e===`
|
|
31
|
+
`){o(),i.push({type:`break`}),s++;continue}let l=n<6?this.markup(s,t,n):void 0;l?.inline?(o(),i.push(l.inline)):a+=l?l.text:e,s=l?l.end:s+1}return o(),i}markup(e,t,n){let r=this.src[e];if(r==="`")return this.codeSpan(e,t);if(r===`*`||r===`_`)return this.emphasis(e,t,n);if(r===`[`)return this.link(e,t,n,!1);if(r===`!`&&this.src[e+1]===`[`)return this.link(e+1,t,n,!0);if(r===`<`)return this.autolink(e,t)}next(e,t,n,r){let i=this.memo.get(e);if(i&&t>=i.from&&(i.at===-1||t<=i.at))return i.at;let a=n(t);for(;a!==-1&&!r(a);)a=n(a+1);return this.memo.set(e,{from:t,at:a}),a}escaped(e){let t=0;for(let n=e-1;n>=0&&this.src[n]===`\\`;n--)t++;return t%2==1}codeSpan(e,t){let{src:n}=this,r=1;for(;n[e+r]==="`";)r++;let i="`".repeat(r),a=this.next(`code${r}`,e+r,e=>n.indexOf(i,e),e=>n[e-1]!=="`"&&n[e+r]!=="`");return a===-1||a+r>t?{text:i,end:e+r}:{inline:{type:`code`,text:Gr(n.slice(e+r,a))},end:a+r}}emphasis(e,t,n){let{src:r}=this,i=r[e],a=r[e+1]===i?i+i:i,o=e+a.length,s=e=>e>=0&&e<r.length&&zr.test(r[e]),c=e=>i===`_`&&s(e),l={text:a,end:o};if(c(e-1)||o>=t||/\s/.test(r[o]))return l;let u=this.next(a,o+1,e=>r.indexOf(a,e),e=>!this.escaped(e)&&!/\s/.test(r[e-1])&&!c(e+a.length));if(u===-1||u+a.length>t)return l;let d=this.parse(o,u,n+1);return{inline:{type:a.length===2?`strong`:`em`,children:d},end:u+a.length}}link(e,t,n,r){let{src:i}=this,a={text:r?`![`:`[`,end:e+1},o=this.partner.get(e);if(o===void 0||o>=t||i[o+1]!==`(`)return a;let s=this.partner.get(o+1);if(s===void 0||s>=t)return a;let c=s+1;if(r)return{text:Gr(i.slice(e+1,o)),end:c};let l=Wr(Gr(i.slice(o+2,s)));return l?{inline:{type:`link`,href:l,children:this.parse(e+1,o,n+1)},end:c}:{text:Gr(i.slice(e,c)),end:c}}autolink(e,t){let n=/^<([A-Za-z][A-Za-z0-9+.-]*:[^\s<>]*)>/.exec(this.src.slice(e,Math.min(t,e+2048))),r=n?Wr(n[1]):void 0;if(!(!n||!r))return{inline:{type:`link`,href:r,children:[{type:`text`,text:n[1]}]},end:e+n[0].length}}};function Jr(e){return new qr(e).parse(0,e.length,0)}const Yr=/^ {0,3}(`{3,}|~{3,})/,Xr=/^ {0,3}(#{1,6})(?:[ \t]+(.*?))?(?:[ \t]+#+)?[ \t]*$/,Zr=/^ {0,3}([-*_])(?:[ \t]*\1){2,}[ \t]*$/,Qr=/^ {0,3}> ?(.*)$/,$r=/^ {0,3}[-*+][ \t]+(.*)$/,ei=/^ {0,3}(\d{1,9})[.)][ \t]+(.*)$/,ti=e=>e.trim()===``,ni=e=>Yr.test(e)||Xr.test(e)||Zr.test(e)||Qr.test(e)||$r.test(e)||ei.test(e);function ri(e,t){let n=[],r=0;for(;r<e.length;){let i=e[r];if(ti(i)){r++;continue}let a=Yr.exec(i);if(a){let t=a[1],i=RegExp(`^ {0,3}${t[0]}{${t.length},}[ \\t]*$`),o=[];for(r++;r<e.length&&!i.test(e[r]);)o.push(e[r]),r++;r++,n.push({type:`code`,text:Gr(o.join(`
|
|
32
|
+
`))});continue}if(Zr.test(i)){n.push({type:`rule`}),r++;continue}let o=Xr.exec(i);if(o){let e=Math.min(6,o[1].length+1);n.push({type:`heading`,level:e,children:Jr(o[2]??``)}),r++;continue}if(Qr.test(i)&&t<4){let i=[];for(;r<e.length&&Qr.test(e[r]);)i.push(Qr.exec(e[r])[1]),r++;n.push({type:`quote`,children:ri(i,t+1)});continue}let s=$r.test(i),c=ei.exec(i);if(s||c){let t=s?$r:ei,i=[];for(;r<e.length;){let n=e[r],a=t.exec(n);if(a)i.push([s?a[1]:a[2]]);else if(!ti(n)&&/^ {2,}\S/.test(n)&&!ni(n.trimStart()))i.at(-1).push(n.trim());else break;r++}n.push({type:`list`,ordered:!s,...c&&c[1]!==`1`?{start:Number(c[1])}:{},items:i.map(e=>Jr(e.join(`
|
|
33
|
+
`)))});continue}let l=[i.trim()];for(r++;r<e.length&&!ti(e[r])&&!ni(e[r]);)l.push(e[r].trim()),r++;n.push({type:`paragraph`,children:Jr(l.join(`
|
|
34
|
+
`))})}return n}function ii(e){return ri(e.replace(/\r\n?/g,`
|
|
35
35
|
`).split(`
|
|
36
|
-
`),0)}const
|
|
37
|
-
`;case`link`:{let t=ui(e.children);return t===e.href?t:`${t} (${e.href})`}default:return ui(e.children)}}).join(``)}function di(e){let t=[],n=(e,r)=>{for(let i of e)switch(i.type){case`heading`:t.push({type:`heading`,text:ui(i.children),level:Math.min(i.level,3)});break;case`paragraph`:t.push({type:`paragraph`,text:ui(i.children),...r?{font:`italic`}:{}});break;case`list`:i.items.forEach((e,n)=>{let a=i.ordered?`${(i.start??1)+n}.`:`•`;t.push({type:`paragraph`,text:`${a} ${ui(e)}`,...r?{font:`italic`}:{}})});break;case`quote`:n(i.children,!0);break;case`code`:t.push({type:`paragraph`,text:i.text,size:9});break;case`rule`:t.push({type:`rule`});break}};return n(oi(e),!1),t}function fi(e){let t=e.signature,n=[e.name,`Signed ${li(e.signedAt)}`];return t?.kind===`drawn`&&t.strokes?{type:`signature`,label:`Signature`,strokes:{v:1,w:1,h:1,strokes:t.strokes},caption:t.typedName?[t.typedName,...n]:n}:{type:`signature`,label:`Signature`,typedName:t?.typedName??e.name,caption:n}}function pi(e,t,n){let r=e.envelope.signerFields??[];if(r.length===0)return[];let i=t.fieldValues??{};return[{type:`spacer`,height:12},{type:`heading`,text:`Details entered by ${n?t.name:`the signer`}`,level:2},{type:`table`,columns:[{header:`Field`},{header:`Value`,width:2}],rows:r.map(e=>[e.label,i[e.key]??``])}]}function mi(e){let{envelope:t,signers:n,events:r,head:i,envelopeId:a}=e,o=n.length>1,s=[[`Envelope`,a],[`Document`,t.title],[`Document SHA-256`,t.docSha256??``],...n.flatMap((e,t)=>[[o?`Signer ${t+1}`:`Signer`,e.name],[`Signing as`,ci[e.as]??e.as],...e.participant?[[`Participant`,e.participant.name]]:[],[`Signature`,e.signature?.kind===`drawn`?`Drawn`:`Typed`],[`Signature SHA-256`,e.signature?.sha256??``],[`Consent version`,e.consentVersion??``],...e.consentSha256?[[`Consent wording SHA-256`,e.consentSha256]]:[],...e.otpVerifiedAt?[[`Identity check`,`Email one-time code verified`]]:[],[`Signed`,li(e.signedAt)]]),[`Completed`,li(t.completedAt)],[`Audit events`,String(r.length)]],c=r.map(e=>[String(e.seq+1),li(e.at),e.type,typeof e.data.signer==`number`?`signer ${e.data.signer}`:e.actor,e.personal?.ip??``,e.hash.slice(0,16)]);return{info:{title:t.title,subject:`Signed document and certificate of completion`,creator:`semics e-sign`,...t.completedAt?{creationDate:new Date(t.completedAt)}:{}},footer:{text:`Envelope ${a}`,pageNumbers:!0},blocks:[{type:`heading`,text:t.title,level:1},...di(e.snapshot),...n.flatMap(t=>[...pi(e,t,o),{type:`spacer`,height:18},fi(t)]),{type:`pageBreak`},{type:`heading`,text:`Certificate of completion`,level:1},{type:`paragraph`,text:`This certificate records how the document above was signed. It was signed with a simple electronic signature: the signer consented to sign electronically, confirmed their intent to sign, and signed the exact text identified by the document SHA-256 below. Every step is recorded in a hash-chained audit trail; the final hash binds the document to the end of that trail. Anyone holding this PDF can check these values on the verify page.`},{type:`spacer`,height:8},{type:`table`,columns:[{header:`Field`},{header:`Value`,width:3}],rows:s},{type:`spacer`,height:8},{type:`heading`,text:`Audit trail`,level:2},{type:`table`,columns:[{header:`#`,width:.4},{header:`Time`,width:1.6},{header:`Event`,width:1.6},{header:`Actor`,width:.8},{header:`IP address`,width:1.2},{header:`Event hash (first 16)`,width:1.6}],rows:c,size:8},{type:`spacer`,height:8},{type:`paragraph`,text:`Audit chain head`,font:`bold`,size:9},{type:`paragraph`,text:i,size:9},{type:`paragraph`,text:`Final hash`,font:`bold`,size:9},{type:`paragraph`,text:t.finalHash??``,size:9}]}}async function hi(e){let t=qt(mi(e));return{bytes:t,sha256:await F(t)}}const R=new TextEncoder().encode(`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`);function gi(e){let t=new Uint8Array(Math.ceil(e.length/3)*4),n=e.length-e.length%3,r=0;for(let i=0;i<n;i+=3){let n=e[i]<<16|e[i+1]<<8|e[i+2];t[r++]=R[n>>18],t[r++]=R[n>>12&63],t[r++]=R[n>>6&63],t[r++]=R[n&63]}if(n<e.length){let i=n+1<e.length,a=e[n]<<16|(i?e[n+1]<<8:0);t[r++]=R[a>>18],t[r++]=R[a>>12&63],t[r++]=i?R[a>>6&63]:61,t[r++]=61}return new TextDecoder().decode(t)}function _i(e){try{let t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return n}catch{return null}}const vi=(e,t,n)=>`${e}:pdf:${t.slice(0,16)}:${n}`;function yi(e,t,n){let r=Math.max(1,Math.ceil(t.length/si));return Array.from({length:r},(i,a)=>({id:vi(e,n,a),data:{envelopeId:e,kind:`signed-pdf`,contentType:`application/pdf`,index:a,count:r,bytes:t.length,sha256:n,data:gi(t.subarray(a*si,(a+1)*si))}}))}function bi(e){let t=e[0];if(!t||e.length!==t.count)return null;let n=[...e].sort((e,t)=>e.index-t.index),r=new Uint8Array(t.bytes),i=0;for(let[e,a]of n.entries()){if(a.index!==e||a.sha256!==t.sha256||a.bytes!==t.bytes)return null;let n=_i(a.data);if(!n||i+n.length>r.length)return null;r.set(n,i),i+=n.length}return i===r.length?r:null}const xi=`signed-pdf-`,Si=e=>`${xi}${e}`;function Ci(e,t,n,r=0){return e?.schedule(Si(t),{schedule:j(n),data:{envelopeId:t,attempt:r}})}async function wi(e,t,n){let{envelopes:r,signers:i,snapshots:a,audit_events:o,artifacts:s}=B(e),c=await r.get(t);if(!c||c.status!==`completed`||c.pdfSha256||c.personalPurgedAt||c.signerIds.length===0||!c.snapshot||!c.docSha256)return`skipped`;let[l,u,d]=await Promise.all([i.getMany(c.signerIds),a.getMany(c.snapshot.ids),o.query({where:{envelopeId:t},orderBy:{seq:`asc`},limit:100})]),f=Ar([...u.values()]),p=d.items.map(e=>e.data),m=await Gn(t,p),h=m.ok&&p.at(-1)?.type===`envelope.completed`&&await qn(c.docSha256,m.value.head)===c.finalHash,g=c.signerIds.map(e=>l.get(e));if(g.some(e=>e?.status!==`signed`)||f===null||!m.ok||!h){let r=n.attempt??0;return r+1>=5?(e.log.error(`signed PDF not generated: the envelope never settled`,{envelopeId:t}),`gave-up`):(await Ci(e.cron,t,n.now+6e4,r+1),`retry`)}let{bytes:_,sha256:v}=await hi({envelopeId:t,envelope:c,signers:g,snapshot:f,events:p,head:m.value.head}),y=yi(t,_,v);return await s.putMany(y),(await r.updateIf(t,{where:{status:`completed`,pdfSha256:null},set:{pdfSha256:v,pdf:{ids:y.map(e=>e.id),bytes:_.length},updatedAt:j(n.now)}})).applied?(await ea(e.cron,t,n.now),`stored`):`skipped`}async function Ti(e,t){if(!e.name.startsWith(xi))return!1;let n=e.data?.envelopeId,r=e.data?.attempt;return typeof n!=`string`||n.length===0||await wi(t,n,{now:Date.now(),attempt:typeof r==`number`&&Number.isSafeInteger(r)?r:0}),!0}const Ei=`esign/download`,Di=`esign:download-link-key`,Oi=/^[A-Za-z0-9_:.-]{1,200}$/,ki=RegExp(`^[0-9a-f]{64}$`);function Ai(e){return typeof e!=`string`||!ki.test(e)?null:Uint8Array.from(e.match(/../g),e=>Number.parseInt(e,16))}async function ji(e){let t=Ai(await e.get(Di));if(t)return t;let n=crypto.getRandomValues(new Uint8Array(32));if((await e.compareAndSet(Di,null,S(n))).applied)return n;let r=Ai(await e.get(Di));if(!r)throw Error(`download link key unavailable`);return r}async function Mi(e,t,n){let r=await pe({secret:await ji(e.kv),purpose:Ei,params:{e:t},now:n,ttlMs:9e5}),i=j(Number(r.get(`exp`))*1e3);return{url:`/_emdash/api/plugins/${e.plugin.id}/public/download?${r}`,expiresAt:i}}function z(e){let{status:t,body:n}=D(e);return Lr({status:t,headers:{"content-type":`application/json; charset=utf-8`,"cache-control":`no-store`},body:{kind:`text`,value:JSON.stringify(n)}})}function Ni(e){try{return e?.url?new URL(e.url).searchParams:null}catch{return null}}async function Pi(e,t){let n=Ni(e.request);if(!n)return z(`TOKEN_INVALID`);if(n.has(`token`))return z(`TOKEN_IN_QUERY`);let r=Date.now(),i=await me({secret:await ji(t.kv),purpose:Ei,query:n,now:r});if(!i.ok)return z(i.error);let a=i.value.e;if(typeof a!=`string`||!Oi.test(a))return z(`TOKEN_INVALID`);let{envelopes:o,artifacts:s}=B(t),c=await o.get(a);if(!c||c.status!==`completed`||c.recordsPurgedAt)return z(`ENVELOPE_NOT_FOUND`);if(!c.pdfSha256||!c.pdf)return await Ci(t.cron,a,r),z(`SIGNED_PDF_PENDING`);let l=bi([...(await s.getMany(c.pdf.ids)).values()]);return!l||await F(l)!==c.pdfSha256?(t.log.error(`signed PDF chunks do not match pdfSha256`,{envelopeId:a}),z(`INTERNAL`)):Lr({status:200,headers:{"content-type":`application/pdf`,"content-disposition":`attachment; filename="signed-${a.replace(/[^A-Za-z0-9_-]/g,`_`)}.pdf"`,"cache-control":`private, no-store`,"x-content-type-options":`nosniff`,"referrer-policy":`no-referrer`},body:{kind:`bytes`,value:l}})}const Fi=(e,t)=>Pi(e,t),Ii=e=>typeof e.user?.id==`string`&&e.user.id.length>0?e.user.id:void 0,B=e=>e.storage,V=e=>typeof e==`object`&&e?e:{},H=e=>({...D(`BAD_REQUEST`).body,...e?{issues:e}:{}}),U=e=>D(e).body;function Li(e){let t=V(e).id;return typeof t==`string`&&t.length>0&&t.length<=200?t:null}function Ri(e){return Number.isSafeInteger(e)&&e>=1&&e<=365?e:30}function zi(e){return e instanceof Error&&e.message.includes(`UNIQUE constraint failed`)}async function Bi(e,t,n){let r=e;for(let e=1;;e++)try{return{token:r,value:await n(await k(r))}}catch(n){if(!zi(n)||e>=3)throw n;r=se(t)}}async function Vi(e,t,n,r){let{token:i}=await Bi(n,r,n=>e.put(t.id,{...t.data,tokenHash:n}));return i}const Hi=(e,{piiSalt:t,...n})=>({id:e,...n}),Ui=(e,{snapshot:t,fieldValues:n,piiSalt:r,...i})=>({id:e,...i});async function Wi(e,t,n,r){if(!(await Vn(B(e).audit_events,t,r,{salt:n.piiSalt})).ok)throw Error(`audit chain contention`)}async function Gi(e,t){let n=_r(e.input);if(!n.ok)return H(n.error);let{templateId:r,templateVersion:i}=n.value,{templates:a,envelopes:o,audit_events:s}=B(t),c=await a.getMany(i===void 0?[r]:[r,L(r,i)]),l=vr(c.get(r),i===void 0?void 0:c.get(L(r,i)),i);if(!l.ok)return U(`TEMPLATE_NOT_FOUND`);let u=Nn(),d=Sr(n.value,l.value,{now:j(),piiSalt:u});if(!d.ok)return H(d.error);let f=crypto.randomUUID();return await o.put(f,d.value),await s.putMany(await zn(f,[Fr(d.value,`admin`,Ii(e))],u)),{ok:!0,envelope:Hi(f,d.value)}}async function Ki(e,t){let n=Li(e.input);if(!n)return H();let{envelopes:r,templates:i,snapshots:a,signers:o}=B(t),s=await r.get(n);if(!s)return U(`ENVELOPE_NOT_FOUND`);if(!Qn(s.status,`sent`))return U(`ENVELOPE_CLOSED`);let{templateId:c,templateVersion:l}=s,[u,d]=await Promise.all([i.getMany([c,L(c,l)]),t.settings.list()]),f=Object.fromEntries(d.map(e=>[e.key,e.value])),p=vr(u.get(c),u.get(L(c,l)),l);if(!p.ok)return U(`TEMPLATE_NOT_FOUND`);let m=se(),h=await jr(n,{...s,...await void 0},p.value,{now:j(),tokenHash:await k(m),expiryDays:Ri(f.expiryDays)});if(!h.ok)return Array.isArray(h.error)?H(h.error):U(`ENVELOPE_CLOSED`);await a.putMany(h.value.chunks);let g=await I(r,n,`draft`,`sent`,h.value.envelope);if(!g.ok)return U(`ENVELOPE_CLOSED`);let _=await Vi(o,h.value.signer,m),v=await On(t,{signerId:h.value.signer.id,envelope:g.value,token:_,senderSetting:f.senderName,now:Date.now()});return await Wi(t,n,g.value,Ir(g.value,`admin`,Ii(e))),{ok:!0,envelope:Hi(n,g.value),...v?{}:{invitation:`SITE_URL_MISSING`}}}async function qi(e,t){let n=Li(e.input);if(!n)return H();let{envelopes:r,snapshots:i,signers:a}=B(t),o=await r.get(n);if(!o)return U(`ENVELOPE_NOT_FOUND`);let[s,c]=await Promise.all([o.snapshot?i.getMany(o.snapshot.ids):Promise.resolve(new Map),o.signerIds.length>0?a.getMany(o.signerIds):Promise.resolve(new Map)]),l=o.pdfSha256?await Mi(t,n,Date.now()):null;return{ok:!0,envelope:Hi(n,o),download:l,snapshot:o.snapshot?Ar([...s.values()]):null,signers:[...c].map(([e,t])=>({id:e,order:t.order,name:t.name,email:t.email,status:t.status}))}}async function Ji(e,t){let n=Li(e.input);if(!n)return H();let{envelopes:r,signers:i,outbox:a,audit_events:o}=B(t),s=await r.get(n);if(!s)return U(`ENVELOPE_NOT_FOUND`);let c=s.signerIds[0];if(s.status!==`sent`||c===void 0)return U(`ENVELOPE_CLOSED`);if(!Tn(t))return{ok:!1,error:{code:`SITE_URL_MISSING`,message:Dn}};let l=Fn(n,0),u=Fn(n,1),[d,f,p]=await Promise.all([t.settings.get(`senderName`),a.get(`invite-${c}`),o.getMany([l,u])]);if(f&&f.status!==`failed`)return{ok:!1,error:{code:`INVITATION_QUEUED`,message:`The invitation is already queued or sent.`}};let m=await Bi(se(),void 0,e=>i.updateIf(c,{where:{status:`pending`},set:{tokenHash:e}}));if(!m.value.applied)return U(`ENVELOPE_CLOSED`);await On(t,{signerId:c,envelope:s,token:m.token,senderSetting:d,now:Date.now()});let h=!1;p.has(u)||(h=await Un(o,await Bn(n,p.get(l)??null,[Ir(s,`admin`,Ii(e))],s.piiSalt)));let{name:g,email:_,status:v}=m.value.data;return{ok:!0,envelope:Hi(n,s),signers:[{id:c,order:m.value.data.order,name:g,email:_,status:v}],repaired:h}}async function Yi(e,t){let n=Li(e.input);if(!n)return H();let r=await B(t).envelopes.get(n);if(!r)return U(`ENVELOPE_NOT_FOUND`);let i=j(),a=await I(B(t).envelopes,n,r.status,`voided`,{closedAt:i,updatedAt:i});return a.ok?(await Wi(t,n,a.value,{type:`envelope.voided`,at:i,actor:`admin`,...Ii(e)?{data:{userId:Ii(e)}}:{}}),{ok:!0,envelope:Hi(n,a.value)}):U(`ENVELOPE_CLOSED`)}async function Xi(e,t){let{status:n,cursor:r}=V(e.input);if(n!==void 0&&!Zn(n)||r!==void 0&&!(typeof r==`string`&&r.length>0&&r.length<=500))return H();let i=await B(t).envelopes.query({...n===void 0?{}:{where:{status:n}},orderBy:{createdAt:`desc`},limit:100,...r===void 0?{}:{cursor:r}});return{ok:!0,envelopes:i.items.map(e=>Ui(e.id,e.data)),...i.hasMore&&i.cursor?{nextCursor:i.cursor}:{}}}const Zi={"envelopes/create":{handler:Gi},"envelopes/send":{handler:Ki},"envelopes/get":{handler:qi},"envelopes/list":{handler:Xi},"envelopes/resend":{handler:Ji},"envelopes/void":{handler:Yi},"outbox/status":{handler:(async(e,t)=>({ok:!0,...await jn(t)}))}},Qi=`completion-email-`,$i=e=>`${Qi}${e}`;function ea(e,t,n){return e?.schedule($i(t),{schedule:j(n),data:{envelopeId:t}})}async function ta(e,t,n){let[r,i,a]=await Promise.all([B(e).envelopes.get(t),e.settings.get(`senderName`),B(e).outbox.get(`complete-${t}`)]);if(!r||r.status!==`completed`||!r.pdfSha256||a)return!1;let o=r.signerIds[0];if(o===void 0||!Tn(e))return!1;let s=await Bi(se(),void 0,t=>B(e).signers.updateIf(o,{where:{status:`signed`},set:{copyTokenHash:t}}));return s.value.applied?(await kn(e,{envelopeId:t,envelope:r,token:s.token,senderSetting:i,now:n}),!0):!1}async function na(e,t){if(!e.name.startsWith(Qi))return!1;let n=e.data?.envelopeId;return typeof n==`string`&&n.length>0&&await ta(t,n,Date.now()),!0}const ra=`expire`,ia=`expire-more`;async function aa(e,t){if(e.name!==ra&&e.name!==ia)return!1;let{envelopes:n}=B(t),r=j(),i=await n.query({where:{status:{in:[`sent`,`in_progress`]},expiresAt:{lt:r}},orderBy:{expiresAt:`asc`},limit:2});for(let{id:e,data:a}of i.items){let i=await I(n,e,a.status,`expired`,{closedAt:r,updatedAt:r});i.ok&&await Wi(t,e,i.value,{type:`envelope.expired`,at:r,actor:`system`})}return i.hasMore&&await t.cron?.schedule(ia,{schedule:j(Date.now()+6e4)}),!0}function W(e){if(typeof e!=`string`)return null;let t=new TextEncoder().encode(e.trim());return t.length>=32?t:null}const oa=`intent-finish-`,sa=e=>`${oa}${e}`;function ca(e,t,n){return e?.schedule(sa(t),{schedule:j(n),data:{envelopeId:t}})}async function la(e,t){let n=await C(e),r=await crypto.subtle.sign(`HMAC`,n,new TextEncoder().encode(`esign-invite/1.${t}`));return x(new Uint8Array(r))}async function ua(e,t,n){let{envelopes:r,templates:i,snapshots:a,signers:o,audit_events:s}=B(e),c=await r.get(t);if(!c||c.status!==`draft`||c.delivery!==`email`||!c.clientId)return`skipped`;let l=L(c.templateId,c.templateVersion),[u,d]=await Promise.all([i.getMany([c.templateId,l]),e.settings.list()]),f=Object.fromEntries(d.map(e=>[e.key,e.value])),p=vr(u.get(c.templateId),u.get(l),c.templateVersion);if(!p.ok)return`skipped`;let m=W(f.integrationMasterKey);if(!m)return`skipped`;let h=await la(m,t),g=await jr(t,c,p.value,{now:j(n),tokenHash:await k(h),expiryDays:Ri(f.expiryDays)});if(!g.ok)return`skipped`;await a.putMany(g.value.chunks);let _=await Vi(o,g.value.signer,h);await On(e,{signerId:g.value.signer.id,envelope:g.value.envelope,token:_,senderSetting:f.senderName,now:n});let v=[Fr(c,`integration`),Ir(g.value.envelope,`integration`)];return await s.putMany(await zn(t,v,c.piiSalt)),(await I(r,t,`draft`,`sent`,g.value.envelope)).ok?`sent`:`skipped`}async function da(e,t){if(!e.name.startsWith(oa))return!1;let n=e.data?.envelopeId;return typeof n==`string`&&n.length>0&&await ua(t,n,Date.now()),!0}const fa=`nonce-sweep`,pa=`nonce-sweep-more`;async function ma(e){let{nonces:t,cron:n,now:r,page:i=100,pages:a=3}=e,o=j(r),s=0,c=!1;for(let e=0;e<a;e++){let e=await t.query({where:{expiresAt:{lt:o}},orderBy:{expiresAt:`asc`},limit:i});if(e.items.length===0||(s+=await t.deleteMany(e.items.map(e=>e.id)),c=e.hasMore===!0,!c))break}return c&&await n?.schedule(pa,{schedule:j(r+6e4)}),{deleted:s,more:c}}async function ha(e,t){if(e.name!==fa&&e.name!==pa)return!1;let n=t.storage.nonces;return await ma({nonces:n,cron:t.cron,now:Date.now()}),!0}const ga=`retention`,_a=`retention-more`,va=`cron:retention`,ya=e=>e.status===`sent`||e.status===`in_progress`,ba=e=>ya(e)?null:Date.parse(e.completedAt??e.closedAt??e.updatedAt),xa=(e,t,n,r)=>{let i=e.find(e=>e.key===t)?.value;return typeof i==`number`&&Number.isFinite(i)?Math.min(r,Math.max(1,Math.round(i))):n};function Sa(e,t){let n=new Date(t);n.setUTCMonth(n.getUTCMonth()-xa(e,`retentionPersonalDataMonths`,12,120));let r=new Date(t);return r.setUTCFullYear(r.getUTCFullYear()-xa(e,`retentionSignedRecordsYears`,7,50)),{p:Math.max(n.getTime(),r.getTime()),r:r.getTime()}}function Ca(e,t){let{name:n,email:r,ip:i,ua:a,signature:o,fieldValues:s,declineReason:c,copyTokenHash:l,participant:u,...d}=t;return{...d,name:``,email:``,tokenHash:`purged:${e}`,...o?{signature:{kind:o.kind,sha256:o.sha256}}:{}}}function wa(e,t){let{piiSalt:n,returnUrl:r,signerEmail:i,...a}=e;return{...a,signer:{name:``,email:``,as:e.signer.as},fieldValues:{},personalPurgedAt:t}}async function Ta(e,t,n){let r=new Set(t.filter(e=>e.data.status===`draft`).map(e=>e.id)),i=await e.audit_events.query({where:{envelopeId:{in:t.map(e=>e.id)}},limit:100,...n?{cursor:n}:{}}),a=i.items.filter(e=>!r.has(e.data.envelopeId)&&e.data.personal!==null),o=i.items.filter(e=>r.has(e.data.envelopeId)).map(e=>e.id);return a.length>0&&await e.audit_events.putMany(a.map(e=>({id:e.id,data:Kn(e.data)}))),o.length>0&&await e.audit_events.deleteMany(o),i.hasMore?i.cursor:void 0}async function Ea(e,t,n){let r=j(n),i=t.filter(e=>e.data.status!==`draft`),a=i.flatMap(e=>e.data.signerIds),o=a.length>0?await e.signers.getMany(a):new Map,s=a.flatMap(e=>{let t=o.get(e);return t?[{id:e,data:Ca(e,t)}]:[]});s.length>0&&await e.signers.putMany(s),i.length>0&&await e.envelopes.putMany(i.map(e=>({id:e.id,data:wa(e.data,r)})));let c=t.filter(e=>e.data.status===`draft`).map(e=>e.id);c.length>0&&await e.envelopes.deleteMany(c)}async function Da(e,t){let n=B(e),r={...await e.kv.get(va)},i=!1;if(!r.phase||r.phase===`rl`)(await Xt(e.kv,t,3)).more?r.phase=`rl`:Object.assign(r,Sa(await e.settings.list(`retention`),t),{phase:`personal`});else if(r.phase===`outbox`){let e=await n.outbox.query({where:{status:{in:[`sent`,`failed`]},nextAttemptAt:{lt:r.p}},limit:100});e.items.length>0&&await n.outbox.deleteMany(e.items.map(e=>e.id)),i=!e.hasMore}else{let e=r.phase===`personal`,i=e?r.p:r.r,a=await n.envelopes.query({where:{createdAt:{gte:(e?r.pf:r.rf)??``,lt:j(i)}},limit:10,...r.cursor?{cursor:r.cursor}:{}}),o=t=>e?t.personalPurgedAt:t.recordsPurgedAt,s=a.items.filter(({data:e})=>!o(e)&&(ba(e)??i)<i),c=s.length===0;if(!r.step&&s.length>0){if(e)r.acursor=await Ta(n,s,r.acursor);else{let e=await n.audit_events.query({where:{envelopeId:{in:s.map(e=>e.id)}},limit:100});if(e.items.length>0&&await n.audit_events.deleteMany(e.items.map(e=>e.id)),e.hasMore)r.acursor=`more`;else{delete r.acursor;let e=s.flatMap(e=>e.data.pdf?.ids??[]),t=s.flatMap(e=>e.data.snapshot?.ids??[]);e.length>0&&await n.artifacts.deleteMany(e),t.length>0&&await n.snapshots.deleteMany(t)}}r.acursor||(r.step=1)}else if(s.length>0){if(e)await Ea(n,s,t);else{let e=s.flatMap(e=>e.data.signerIds);e.length>0&&await n.signers.deleteMany(e);let r=j(t);await n.envelopes.putMany(s.map(({id:e,data:t})=>({id:e,data:{...t,title:``,signerIds:[],snapshot:null,pdf:null,pdfSha256:null,recordsPurgedAt:r}})))}c=!0}if(c){delete r.step;for(let{data:e}of a.items)!o(e)&&!s.some(t=>t.data===e)&&(!r.keep||e.createdAt<r.keep)&&(r.keep=e.createdAt);a.hasMore&&a.cursor?r.cursor=a.cursor:(r[e?`pf`:`rf`]=r.keep??j(i),delete r.cursor,delete r.keep,r.phase=e?`records`:`outbox`)}}return i&&delete r.phase,await e.kv.set(va,r),i||await e.cron?.schedule(_a,{schedule:j(t)}),i}async function Oa(e,t,n=Date.now()){return e.name!==ga&&e.name!==_a?!1:(await Da(t,n),!0)}const ka=e=>ya(e)||e.status===`completed`&&!e.pdfSha256;async function Aa(e,t){let n=B(e),r;if(t.includes(`@`)){let e=t.toLowerCase(),[i,a]=await Promise.all([n.signers.query({where:{email:e},limit:10}),n.envelopes.query({where:{signerEmail:e},limit:10})]),o=new Map(a.items.map(e=>[e.id,e.data])),s=[...new Set(i.items.map(e=>e.data.envelopeId))].filter(e=>!o.has(e));if(s.length>0)for(let[e,t]of await n.envelopes.getMany(s))o.set(e,t);r=[...o].slice(0,10).map(([e,t])=>({id:e,data:t}))}else{let e=await n.envelopes.get(t);r=e?[{id:t,data:e}]:[]}return{due:r.filter(e=>!ka(e.data)&&!e.data.personalPurgedAt),open:r.filter(e=>ka(e.data)).length}}async function ja(e,t,n){let r=B(e),i=await Ta(r,t.due);if(i&&=await Ta(r,t.due,i),i)throw Error(`audit trail too long for one request`);await Ea(r,t.due,n),await r.outbox.deleteMany(t.due.flatMap(e=>[`complete-${e.id}`,...e.data.signerIds.map(e=>`invite-${e}`)]))}const Ma=new Set([`localhost`,`127.0.0.1`,`[::1]`]);function Na(e=b){return x(e(32))}const Pa=e=>W(e)===null;function Fa(e){let t=[];for(let n of e.split(/\r?\n/)){let e=n.trim();if(e===``)continue;let r;try{r=new URL(e)}catch{return{ok:!1,entry:e}}if(!(r.protocol===`https:`||r.protocol===`http:`&&Ma.has(r.hostname))||r.username||r.password||e.includes(`#`)||e.includes(`?`))return{ok:!1,entry:e};t.push(r.href)}return t.length>10?{ok:!1,entry:`too many entries`}:{ok:!0,entries:t}}async function Ia(e,t,n){let r=W(t.masterKey);if(!r)return{ok:!1,code:`MASTER_KEY_MISSING`};let i=t.name.trim();if(i===``||i.length>100)return{ok:!1,code:`NAME_REQUIRED`};let a=ht(n.random),o={name:i,clientId:a,createdAt:n.now,lastUsedAt:null,revokedAt:null,returnUrlAllowlist:t.returnUrlAllowlist};return await e.put(a,o),{ok:!0,client:o,pairing:pt(a,await mt(r,a))}}async function La(e,t,n){return(await e.updateIf(t,{where:{revokedAt:null},set:{revokedAt:n}})).applied}async function Ra(e){return(await e.query({orderBy:{createdAt:`desc`},limit:100})).items.map(e=>e.data)}function za(e){let t=(e??``).split(`,`).filter(e=>e.trim()!==``).length;return t===0?{state:`missing`,canSaveSecrets:!1,keyCount:0,banner:{tone:`error`,message:`EMDASH_ENCRYPTION_KEY is not set, so secret settings (the integration master key and the Turnstile secret) cannot be saved. Set it in the site environment and restart.`}}:{state:`ready`,canSaveSecrets:!0,keyCount:t,banner:null}}function Ba(e){let t=`PLUGIN_SETTING_ENCRYPTION_KEY_MISSING`,n=e=>e.includes(t)||e.includes(`PluginSettingEncryptionError`);return typeof e==`string`?n(e):e instanceof Error?n(e.message)||e.name===`PluginSettingEncryptionError`:typeof e==`object`&&e?e.code===t:!1}const Va=e=>e.storage.templates,G=e=>({...D(`BAD_REQUEST`).body,...e?{issues:e}:{}}),Ha=()=>D(`TEMPLATE_NOT_FOUND`).body;function Ua(e){let t=V(e).id;return typeof t==`string`&&t.length>0&&t.length<=200&&!t.includes(`:`)?t:null}const Wa=(e,t)=>({id:e,...t}),Ga=(e,{body:t,...n})=>({id:e,...n});async function Ka(e,t){let n=await Va(e).get(t);return n&&n.status!==`version`?n:null}const qa={"templates/create":{handler:(async(e,t)=>{let n=crypto.randomUUID(),r=nr(e.input,{id:n,now:j()});if(!r.ok)return G(r.error);let{head:i,versions:a}=r.value;return await Va(t).putMany([{id:n,data:i},...a]),{ok:!0,template:Wa(n,i)}})},"templates/update":{handler:(async(e,t)=>{let n=Ua(e.input);if(!n)return G();let r=await Ka(t,n);if(!r)return Ha();let i=rr(r,e.input,{id:n,now:j()});return i.ok?(await Va(t).putMany([{id:n,data:i.value.head},i.value.version]),{ok:!0,template:Wa(n,i.value.head)}):G(i.error)})},"templates/get":{handler:(async(e,t)=>{let n=Ua(e.input);if(!n)return G();let r=V(e.input).version;if(r!==void 0&&!(Number.isSafeInteger(r)&&r>=1))return G();let i=r,a=await Va(t).getMany(i===void 0?[n]:[n,L(n,i)]),o=a.get(n);if(!o||o.status===`version`)return Ha();let s=i===void 0?o:a.get(L(n,i));if(!s)return Ha();let c=Array.from({length:o.version},(e,t)=>t+1);return{ok:!0,template:Wa(n,{...s,status:o.status}),versions:c}})},"templates/list":{handler:(async(e,t)=>{let n=V(e.input).status??`active`;if(n!==`active`&&n!==`archived`)return G();let{items:r}=await Va(t).query({where:{status:n},limit:200});return{ok:!0,templates:r.map(e=>Ga(e.id,e.data)).sort((e,t)=>e.name<t.name?-1:e.name>t.name?1:0)}})},"templates/archive":{handler:(async(e,t)=>{let n=Ua(e.input);if(!n)return G();let r=await Ka(t,n);if(!r)return Ha();if(r.status===`archived`)return{ok:!0,template:Wa(n,r)};let i=ir(r,j());return await Va(t).putMany([{id:n,data:i}]),{ok:!0,template:Wa(n,i)}})}},Ja=(e,t)=>({severity:`error`,title:e,...t?{message:t}:{}}),Ya=e=>B(e.ctx).clients;async function Xa(e){return(await e.ctx.settings.list()).find(e=>e.key===`integrationMasterKey`)?.value}const Za=e=>typeof e==`string`&&e.trim()!==``;function Qa(e,r,o=[]){let s=W(e)!==null,c=typeof e==`object`&&!!e,l=za(null).banner;return q([t(`Integrations`),...u([c&&l&&{severity:`error`,title:`Encryption key missing`,message:l.message},!s&&!c&&{severity:`warning`,title:Za(e)?`Integration master key is too short`:`Integration master key not set`,message:`Clients are paired with secrets derived from the master key. Generate one here, or save one of at least 32 characters in Settings.`}]),...o,...s||c||Za(e)?[]:[d([f(`integrations.generate-key`,`Generate master key`,{style:`primary`})])],t(`Clients`),a({columns:[i(`name`,`Name`),i(`clientId`,`Client id`),i(`created`,`Created`,`relative_time`),i(`status`,`Status`,`badge`),i(`revoke`,``,`element`)],rows:r.map(e=>({name:e.name,clientId:e.clientId,created:e.createdAt,status:e.revokedAt?`Revoked`:`Active`,...e.revokedAt?{}:{revoke:f(`client.revoke`,`Revoke`,{style:`danger`,value:e.clientId,confirm:{title:`Revoke this client?`,text:`Its intents and receipts are refused from now on. This cannot be undone; create a new client to pair again.`,confirm:`Revoke client`,deny:`Keep`,style:`danger`}})}})),pageActionId:`clients.page`,emptyText:`No clients yet.`}),n(`Events on this site: with the Events suite installed, an administrator pairs it in one click at /_events/pair (the client appears here as "Events on this site"; no string to copy).`),t(`Add a client`),n(`The pairing string is shown once, right after you create the client, and cannot be shown again. Paste it into the other plugin's settings. Return URLs: one per line, https (http only for localhost); leave blank to allow this site only.`),y({fields:[m(`name`,`Name`,{initialValue:``}),m(`returnUrlAllowlist`,`Allowed return URLs`,{multiline:!0,initialValue:``})],submit:{label:`Create client`,actionId:`client.create`}})])}async function K(e,t,n=[]){return Qa(t,await Ra(Ya(e)),n)}async function $a(e){let[t,n]=await Promise.all([Xa(e),Ra(Ya(e))]);return Qa(t,n)}async function eo(e){let t=await Xa(e);if(Za(t))return K(e,t,u([Ja(`Key already set`,`Changing it would re-pair every client.`)]));let n=Na();try{await e.ctx.settings.set(`integrationMasterKey`,n)}catch(n){if(!Ba(n))throw n;return K(e,t,u([Ja(`Encryption key missing`,za(null).banner?.message)]))}return K(e,n,u([{severity:`info`,title:`Master key generated`}]))}async function to(e,t){let n=await Xa(e),r=(e,t)=>typeof e==`string`?e.slice(0,t):``,i=Fa(r(t.returnUrlAllowlist,2e3));if(!i.ok)return K(e,n,u([Ja(`Not created`,`Return URL not allowed: ${i.entry.slice(0,200)}`)]));let a=await Ia(Ya(e),{name:r(t.name,200),returnUrlAllowlist:i.entries,masterKey:n},{now:j(e.now)});return a.ok?K(e,n,[...u([{severity:`warning`,title:`Copy the pairing string now`,message:`It is shown only this once and cannot be recovered. Treat it like a password.`}]),o({code:a.pairing})]):K(e,n,u([Ja(`Not created`,a.code===`MASTER_KEY_MISSING`?`Set the integration master key first (at least 32 characters), or generate one.`:`Give the client a name of up to 100 characters.`)]))}async function no(e,t){let n=await La(Ya(e),t,j(e.now));return K(e,await Xa(e),u([n?{severity:`info`,title:`Client revoked`}:Ja(`Not revoked`,`Unknown or already revoked.`)]))}const q=e=>({blocks:e}),J=(e,t=200)=>typeof e==`string`?e.trim().slice(0,t):``,Y=(e,t,n)=>t.handler({input:n,user:e.user??null},e.ctx),ro=e=>Zi[e],io=e=>qa[e],ao={INVALID_NAME:`Give the template a name of up to 200 characters.`,INVALID_BODY:`The template text is required (up to 100,000 characters).`,INVALID_DESCRIPTION:`The description is too long (up to 1,000 characters).`,TEMPLATE_ARCHIVED:`This template is archived.`,INVALID_INTEGRATIONS:`Choose whether integrations may use the template.`,INVALID_TITLE:`The title is too long or has control characters.`,INVALID_SIGNER_NAME:`Enter the signer's name.`,INVALID_SIGNER_EMAIL:`Enter a valid email address for the signer.`,INVALID_FIELDS:`A field value is too long or not text.`,MISSING_FIELD:`A template field has no value.`,DOCUMENT_TOO_LARGE:`The document is too long to sign (up to 131,072 characters and 1,500 lines).`};function X(e,t=`The change was refused.`){let n=Array.isArray(e.issues)?e.issues:[];return n.length>0?n.map(e=>ao[e.code??``]??`${e.path??`input`} (${e.code??`invalid`})`).join(` `):e.error?.message??t}const oo=(e,t,n)=>({severity:e,title:t,...n?{message:n}:{}}),Z=(e,t)=>oo(`error`,e,t),so=(e,t)=>oo(`warning`,e,t),co=(e,t)=>f(e,t,{style:`secondary`}),Q=(e,t)=>oo(`info`,e,t),lo=()=>co(`envelopes.back`,`Back to envelopes`),uo=()=>co(`templates.back`,`Back to templates`),fo=e=>f(`envelope.open`,`Open envelope`,{value:e}),po={"envelope.created":`Envelope created`,"envelope.sent":`Envelope sent`,"signer.viewed":`Signer opened the document`,"signer.consented":`Signer gave consent`,"signer.signed":`Signer signed`,"signer.declined":`Signer declined`,"envelope.completed":`Envelope completed`,"envelope.declined":`Envelope declined`,"envelope.voided":`Envelope voided`,"envelope.expired":`Envelope expired`},mo=e=>!Tn(e.ctx)&&so(`Set the site URL`,Dn);async function ho(e){let t=await jn(e.ctx);return[mo(e),t.state===`no_transport`&&so(`No email transport`,`No email provider is configured, so signing invitations stay queued and are not delivered. Install an email provider plugin.`),t.failed>0&&so(`${t.failed} email${t.failed===1?``:`s`} could not be delivered`,`Open the envelope and use Resend invitation if a signer never received theirs.`)]}async function go(e,r,o=[],s){let c=Zn(r)?r:``,[l,d]=await Promise.all([Y(e,ro(`envelopes/list`),{...c?{status:c}:{},...s?{cursor:s}:{}}),ho(e)]),p=typeof l.nextCursor==`string`?l.nextCursor:void 0,h=(l.envelopes??[]).map(e=>{let t=e.signer;return{title:e.title,signer:t?`${t.name??``} <${t.email??``}>`:``,status:e.status,created:e.createdAt,open:f(`envelope.open`,`Open`,{value:e.id})}});return q([t(`Envelopes`),...u(d),...o,y({fields:[g(`status`,`Status`,[{label:`Any status`,value:``},...Jn.map(e=>({label:e.replaceAll(`_`,` `),value:e}))],{initialValue:c})],submit:{label:`Filter`,actionId:`envelopes.filter`}}),n(`Newest first, 100 a page. Create an envelope from a template on the Templates page.`),a({columns:[i(`title`,`Title`),i(`signer`,`Signer`),i(`status`,`Status`,`badge`),i(`created`,`Created`,`relative_time`),i(`open`,``,`element`)],rows:h,pageActionId:`envelopes.page:${c}`,...p?{nextCursor:p}:{},emptyText:`No envelopes match.`}),t(_o),y({fields:[m(`subject`,`Signer email or envelope id`)],submit:{label:`Find`,actionId:`retention.preview`}})])}const _o=`Delete personal data`;async function vo(e,n,r){let i=await Aa(e.ctx,n),a=i.due.length;return r&&a>0&&await ja(e.ctx,i,e.now),q([t(_o),...u([{severity:r?`info`:`warning`,title:r&&a>0?`Personal data deleted`:a+i.open>0?`${a} envelope(s) to delete, ${i.open} kept for now`:`No envelopes found`,message:`Signed records stay for their own period; open envelopes and pending PDFs are skipped.`}]),d([...!r&&a>0?[f(`retention.erase`,_o,{style:`danger`,value:n,confirm:{title:`${_o}?`,text:`This cannot be undone.`,confirm:`Delete`,deny:`Keep`,style:`danger`}})]:[],lo()])])}async function yo(e,t){if(!t)return`missing`;let n=await B(e.ctx).outbox.get(`invite-${t}`);return n?n.status===`failed`?`failed`:`queued`:`missing`}async function bo(e,o,s={}){let{envelopes:c,signers:l,audit_events:m}=B(e.ctx),h=s.envelope??await c.get(o);if(!h)return q([t(`Envelope`),...u([Z(`Envelope not found`,`It may have been removed.`)]),d([lo()])]);let g=h.status===`sent`||h.status===`in_progress`,[_,v,y]=await Promise.all([m.query({where:{envelopeId:o},orderBy:{seq:`asc`},limit:200}),s.signers?Promise.resolve(s.signers):h.signerIds.length>0?l.getMany(h.signerIds).then(e=>[...e].map(([e,t])=>({id:e,name:t.name,email:t.email,status:t.status}))):Promise.resolve([]),s.invite??(h.status===`sent`?yo(e,h.signerIds[0]):Promise.resolve(`n/a`))]),b=v[0],x=h.status===`sent`&&(y===`missing`||y===`failed`),S=null;if(h.status===`completed`&&!h.recordsPurgedAt)if(h.pdfSha256){let t=await Mi(e.ctx,o,e.now);S=d([p(`Download signed PDF`,{kind:`external`,url:`${e.origin}${t.url}`},{appearance:`primary`})])}else S=n(`The signed PDF is still being prepared. Reload in a minute.`);let C=[h.status===`draft`&&f(`envelope.send`,`Send for signature`,{style:`primary`,value:o}),x&&f(`envelope.resend`,`Resend invitation`,{style:`primary`,value:o}),(h.status===`draft`||g)&&f(`envelope.void`,`Void`,{style:`danger`,value:o,confirm:{title:`Void this envelope?`,text:`The signer will no longer be able to sign it. This cannot be undone.`,confirm:`Void envelope`,deny:`Keep`,style:`danger`}}),lo()].filter(e=>e!==!1);return q([t(h.title),...u([x&&{severity:`warning`,title:`The invitation was not delivered`,message:y===`failed`?`The email gave up after repeated failures. Resend invitation queues a fresh email with a new signing link.`:`The invitation was never queued. Resend invitation queues it with a new signing link.`},x&&mo(e)]),...s.extra??[],...h.personalPurgedAt?[n(`Personal data deleted ${h.personalPurgedAt}${h.recordsPurgedAt?`; signed records deleted`:``} (retention).`)]:[],r([{label:`Status`,value:h.status.replaceAll(`_`,` `)},{label:`Template`,value:`${h.templateId} v${h.templateVersion}`},{label:`Signer`,value:b?`${b.name} <${b.email}>`:h.signer.email},{label:`Signer status`,value:b?.status??`not sent yet`},{label:`Delivery`,value:h.delivery},{label:`Created`,value:h.createdAt},{label:`Sent`,value:h.sentAt??`Not sent`},{label:`Expires`,value:h.expiresAt??`Not set`},{label:`Completed`,value:h.completedAt??`Not completed`},{label:`Document SHA-256`,value:h.docSha256??`Set when sent`},{label:`Final hash`,value:h.finalHash??`Set when completed`}]),...S?[S]:[],d(C),t(`Audit timeline`),a({columns:[i(`seq`,`#`,`number`),i(`event`,`Event`),i(`at`,`When`,`text`),i(`actor`,`By`)],rows:_.items.map(({data:e})=>({seq:e.seq,event:po[e.type]??e.type,at:e.at,actor:e.actor})),pageActionId:`audit.page:${o}`,emptyText:`No events yet.`})])}async function xo(e,n){let r;try{r=await Y(e,ro(`envelopes/send`),{id:n})}catch{return q([t(`Envelope`),...u([Z(`The envelope was sent but the invitation could not be queued`,`Open the envelope and use Resend invitation.`)]),d([fo(n)])])}if(r.ok!==!0)return q([t(`Envelope`),...u([Z(`Not sent`,X(r))]),d([fo(n),lo()])]);let i=r.invitation===`SITE_URL_MISSING`;return q([t(`Envelope`),...u([i?{severity:`warning`,title:`Envelope sent, but no invitation was queued`,message:Dn}:Q(`Envelope sent`,`The signer's invitation is queued.`)]),d([fo(n),lo()])])}async function So(e,t){let n=await Y(e,ro(`envelopes/void`),{id:t});if(n.ok!==!0){let r=n.error?.code===`ENVELOPE_CLOSED`;return bo(e,t,{extra:u([Z(r?`This envelope cannot be voided`:`Not voided`,r?`It is already completed, declined, voided or expired.`:X(n))])})}return bo(e,t,{envelope:n.envelope,invite:`n/a`,extra:u([Q(`Voided`,`The signer can no longer sign this envelope.`)])})}async function Co(e,t){let n=await Y(e,ro(`envelopes/resend`),{id:t});return n.ok===!0?bo(e,t,{envelope:n.envelope,invite:`queued`,signers:n.signers,extra:u([Q(`Invitation queued`,`A new email with a new signing link is on its way.`)])}):bo(e,t,{extra:u([n.error?.code===`INVITATION_QUEUED`?Q(`Already queued`,`The invitation is queued or was sent.`):Z(`Not resent`,X(n,`Only an envelope that is sent and unsigned can be resent.`))])})}const wo=/^(signer|participant)\./;async function To(e,r,i=[]){let a=await Y(e,io(`templates/get`),{id:r}),o=a.template;return a.ok!==!0||!o?q([t(`New envelope`),...u([Z(`Template not found`)]),...i]):q([t(`New envelope: ${o.name}`),...i,n(`Creates a draft you can check before sending it for signature. Signer fields: one per line as key: Label, ending in * when required.`),y({fields:[m(`title`,`Title`,{initialValue:o.name}),m(`signerName`,`Signer name`),m(`signerEmail`,`Signer email`),...o.fields.filter(e=>!wo.test(e)).map(e=>m(`field:${e}`,e)),m(`signerFields`,`Fields the signer fills in (optional)`,{multiline:!0,placeholder:`phone: Phone number *`})],submit:{label:`Create draft`,actionId:`envelope.create`},blockId:`envelope-new:${r}`}),d([uo()])])}function Eo(e){return typeof e==`string`?e.slice(0,4e3).split(`
|
|
38
|
-
`).map(e=>e.trim()).filter(e=>e!==``).map(e=>{let t=e.indexOf(`:`),n=(t===-1?e:e.slice(0,t)).trim(),r=t===-1?``:e.slice(t+1).trim(),i=r.endsWith(`*`);return i&&(r=r.slice(0,-1).trim()),{key:n,label:r,...i?{required:!0}:{}}}):[]}async function Do(e,t,n){let r=t?.startsWith(`envelope-new:`)?t.slice(13):``;if(!r)return q(u([Z(`Choose a template first`)]));let i={};for(let[e,t]of Object.entries(n))e.startsWith(`field:`)&&(i[e.slice(6)]=typeof t==`string`?t:``);let a=J(n.title),o=Eo(n.signerFields),s=await Y(e,ro(`envelopes/create`),{templateId:r,...a?{title:a}:{},signer:{name:J(n.signerName),email:J(n.signerEmail)},fields:i,...o.length>0?{signerFields:o}:{}});if(s.ok!==!0)return To(e,r,u([Z(`Not saved`,X(s))]));let c=s.envelope.id;return bo(e,c,{extra:u([Q(`Draft created`,`Check the details, then send it.`)])})}async function Oo(e,r=[]){let o=((await Y(e,io(`templates/list`),{})).templates??[]).map(e=>({name:e.name,id:e.id,version:e.version,fields:(e.fields??[]).join(`, `),integrations:e.integrations===!0?`Yes`:`No`,updated:e.updatedAt,edit:f(`template.edit`,`Edit`,{value:e.id}),use:f(`envelope.new`,`New envelope`,{style:`primary`,value:e.id})}));return q([t(`Templates`),...r,a({columns:[i(`name`,`Name`),i(`id`,`ID`),i(`version`,`Version`,`number`),i(`fields`,`Fields`),i(`integrations`,`Integrations`),i(`updated`,`Updated`,`relative_time`),i(`edit`,``,`element`),i(`use`,``,`element`)],rows:o,pageActionId:`templates.page`,emptyText:`No templates yet. Add one below.`}),t(`New template`),n(`Write the document in Markdown. Use {{field}} for values filled in per envelope, and {{signer.name}} for the signer.`),y({fields:[m(`name`,`Name`),m(`description`,`Description (optional)`),m(`body`,`Template text`,{multiline:!0}),ko(!1)],submit:{label:`Create template`,actionId:`template.create`}})])}function ko(e){return _(`integrations`,`Available to integrations`,{description:`Paired sites (such as Events) may send this template for signing.`,initialValue:e})}function Ao(e){let t=Object.fromEntries(un(e).map(e=>[e,`«${e}»`]));try{return dn(e,t)}catch{return e}}function jo(e,r,i=[]){let a=String(r.body??``),s=un(a);return q([t(`Edit template: ${String(r.name??``)}`),...i,n(`Version ${String(r.version??1)}. Saving writes a new version; sent envelopes keep the text they were sent with.`),n(`Template id:`),o({code:e}),y({fields:[m(`name`,`Name`,{initialValue:String(r.name??``)}),m(`description`,`Description (optional)`,{initialValue:String(r.description??``)}),m(`body`,`Template text`,{initialValue:a,multiline:!0}),ko(r.integrations===!0)],submit:{label:`Save new version`,actionId:`template.save`},blockId:`template:${e}`}),t(`Preview`),n(s.length>0?`Fields: ${s.join(`, `)}. Placeholders show as «name».`:`This template has no fields.`),o({code:Ao(a)}),d([f(`envelope.new`,`New envelope from this template`,{style:`primary`,value:e}),f(`template.archive`,`Archive`,{style:`danger`,value:e,confirm:{title:`Archive this template?`,text:`It can no longer be used for new envelopes. Sent envelopes are not affected.`,confirm:`Archive`,deny:`Keep`,style:`danger`}}),uo()])])}async function Mo(e,t,n=[]){let r=await Y(e,io(`templates/get`),{id:t});return r.ok!==!0||!r.template?Oo(e,u([Z(`Template not found`)])):jo(t,r.template,n)}async function No(e,t){let n=await Y(e,io(`templates/create`),{name:J(t.name),body:typeof t.body==`string`?t.body:``,...J(t.description,1e3)?{description:J(t.description,1e3)}:{},integrations:t.integrations===!0});return n.ok===!0?Oo(e,u([Q(`Template created`)])):Oo(e,u([Z(`Not saved`,X(n))]))}async function Po(e,t,n){let r=t?.startsWith(`template:`)?t.slice(9):``;if(!r)return q(u([Z(`Choose a template first`)]));let i={name:J(n.name),body:typeof n.body==`string`?n.body:``,description:J(n.description,1e3),integrations:n.integrations===!0},a=await Y(e,io(`templates/update`),{id:r,...i});return a.ok===!0?jo(r,a.template,u([Q(`Saved`)])):jo(r,{...i,version:`?`},u([Z(`Not saved`,X(a))]))}async function Fo(e,t){let n=await Y(e,io(`templates/archive`),{id:t});return Oo(e,u([n.ok===!0?Q(`Template archived`):Z(`Not archived`,X(n))]))}const Io=[{key:`senderName`,label:`Sender name`,kind:`text`},{key:`expiryDays`,label:`Envelope expiry (days)`,kind:`number`,min:1,max:365},{key:`consentVersion`,label:`Consent version`,kind:`text`},{key:`consentWording`,label:`Consent wording`,kind:`long`},{key:`retentionPersonalDataMonths`,label:`Keep personal data (months)`,kind:`number`,min:1,max:120},{key:`retentionSignedRecordsYears`,label:`Keep signed records (years)`,kind:`number`,min:1,max:50},{key:`turnstileSiteKey`,label:`Turnstile site key`,kind:`text`}],Lo=[{key:`turnstileSecretKey`,label:`Turnstile secret key`},{key:`integrationMasterKey`,label:`Integration master key`}],Ro=e=>typeof e==`string`&&e!==``?`readable`:typeof e==`object`&&e?`unreadable`:`unset`;function zo(e,r,i=[]){let a=Lo.some(e=>r[e.key]===`unreadable`),o=za(null).banner;return q([t(`Settings`),...u([a&&o&&{severity:`error`,title:`Encryption key missing`,message:o.message},r.integrationMasterKey===`unset`&&so(`Integration master key not set`,`Other plugins cannot create envelopes through the integration protocol until it is saved.`)]),...i,y({fields:[...Io.map(t=>t.kind===`number`?h(t.key,t.label,{min:t.min,max:t.max,...typeof e[t.key]==`number`?{initialValue:e[t.key]}:{}}):m(t.key,t.label,{multiline:t.kind===`long`,initialValue:typeof e[t.key]==`string`?e[t.key]:``})),...Lo.map(e=>v(e.key,`${e.label} (leave blank to keep)`,{hasValue:r[e.key]===`readable`}))],submit:{label:`Save settings`,actionId:`settings.save`}}),n(`Reminder and one-time-code settings (Pro) are in the plugin's own settings panel.`)])}async function Bo(e){let t=await e.ctx.settings.list(),n=Object.fromEntries(t.map(e=>[e.key,e.value]));return{values:n,secrets:Object.fromEntries(Lo.map(e=>[e.key,Ro(n[e.key])]))}}async function Vo(e){let{values:t,secrets:n}=await Bo(e);return zo(t,n)}async function Ho(e,t){let{values:n,secrets:r}=await Bo(e),i=[],a=[];for(let e of Io){let r=t[e.key];if(r==null||r===``)continue;let o;if(e.kind===`number`){if(o=Number(r),!Number.isInteger(o)||o<(e.min??0)||o>(e.max??2**53-1)){a.push(`${e.label} must be a whole number from ${e.min} to ${e.max}.`);continue}}else o=J(r,e.kind===`long`?2e3:200);o!==n[e.key]&&i.push([e.key,o])}let o=Lo.filter(e=>J(t[e.key],500)!==``);if(o.some(e=>e.key===`integrationMasterKey`&&Pa(J(t[e.key],500)))&&a.push(`The integration master key must be at least 32 characters, or use Generate on the Integrations page.`),a.length>0)return zo(n,r,u([Z(`Not saved`,a.join(` `))]));if(i.length+o.length>6)return zo(n,r,u([Z(`Too many changes at once`,`Save at most 6 settings at a time.`)]));if(i.length+o.length===0)return zo(n,r,u([Q(`Nothing to save`)]));let s={...n},c={...r};try{for(let n of o)await e.ctx.settings.set(n.key,J(t[n.key],500)),c[n.key]=`readable`;for(let[t,n]of i)await e.ctx.settings.set(t,n),s[t]=n}catch(e){if(!Ba(e))throw e;let t=za(null).banner;return zo(n,r,u([{severity:`error`,title:`Encryption key missing`,message:t?.message}]))}return zo(s,c,u([Q(`Saved`)]))}const Uo=e=>J(e,200);async function Wo(e,t){if(t.type===`page_load`)switch(t.page){case`/envelopes`:return go(e,``);case`/templates`:return Oo(e);case`/settings`:return Vo(e);case`/integrations`:return $a(e);default:return q(u([Z(`Page not found`)]))}if(t.type===`form_submit`){let n=t.values;switch(t.action_id){case`envelopes.filter`:return go(e,J(n.status));case`envelope.create`:return Do(e,t.block_id,n);case`template.create`:return No(e,n);case`template.save`:return Po(e,t.block_id,n);case`settings.save`:return Ho(e,n);case`client.create`:return to(e,n);case`retention.preview`:return vo(e,J(n.subject),!1)}}else{let n=Uo(t.value);if(t.action_id.startsWith(`envelopes.page:`))return go(e,t.action_id.slice(15),[],J(t.value,500)||void 0);if(t.action_id.startsWith(`audit.page:`))return bo(e,Uo(t.action_id.slice(11)));switch(t.action_id){case`envelopes.back`:case`envelopes.page`:return go(e,``);case`envelope.open`:return bo(e,n);case`envelope.send`:return xo(e,n);case`envelope.void`:return So(e,n);case`envelope.resend`:return Co(e,n);case`retention.erase`:return vo(e,n,!0);case`envelope.new`:return To(e,n);case`integrations.generate-key`:return eo(e);case`client.revoke`:return no(e,n);case`clients.page`:return $a(e);case`templates.back`:case`templates.page`:return Oo(e);case`template.edit`:return Mo(e,n);case`template.archive`:return Fo(e,n)}}return q(u([Z(`Unknown action`)]))}const Go={admin:{handler:(async(e,t)=>{let n=`http://localhost`;try{n=new URL(e.request?.url??``).origin}catch{}return Wo({ctx:t,origin:n,now:Date.now(),user:e.user??null},e.input)})}},Ko=[`completed`,`declined`,`voided`,`expired`],qo=e=>{if(!e)return;let t=Date.parse(e);return Number.isNaN(t)?void 0:Math.floor(t/1e3)};function Jo(e,t){let{status:n,clientId:r,externalRef:i}=t;if(!Ko.includes(n)||!r||!i||t.docSha256===null)return;let a=n===`completed`,o=a?qo(t.completedAt):qo(t.closedAt)??qo(t.updatedAt);if(o===void 0)return;let s={v:1,typ:`receipt`,cid:r,envelopeId:e,ref:i,status:n,docSha256:t.docSha256,pdfSha256:a?t.pdfSha256??null:null,finalHash:a?t.finalHash:null,at:o};return Ue(`receipt`,s).ok?s:void 0}async function Yo(e,t,n){let r=Jo(e,t);return r?at(`receipt`,r,n):void 0}function Xo(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):void 0}function Zo(e){let t={};return{settings:()=>t,async getClient(n){let[r,i]=await Promise.all([e.settings.list(),B(e).clients.get(n)]);t=Object.fromEntries(r.map(e=>[e.key,e.value]));let a=W(t.integrationMasterKey);if(!(!a||!i))return{secret:await mt(a,n),revoked:i.revokedAt!==void 0&&i.revokedAt!==null,returnUrlAllowlist:Xo(i.returnUrlAllowlist)}}}}async function Qo(e,t,n){let r=W(n);if(!(!r||!t.clientId))return Yo(e,t,await mt(r,t.clientId))}async function $o(e,t,n=Date.now()){let r=await it({token:V(e).request,now:n,getClient:Zo(t).getClient});if(!r.ok)return U(r.error);let i=[],a;for(let e=0;e<3;e++){let e=await B(t).templates.query({where:{status:`active`},limit:200,...a===void 0?{}:{cursor:a}});if(i.push(...e.items),!e.hasMore||!e.cursor)break;a=e.cursor}return{ok:!0,templates:i.filter(e=>ar(e.data)).map(e=>({id:e.id,name:e.data.name,version:e.data.version})).sort((e,t)=>e.name<t.name?-1:e.name>t.name?1:e.id<t.id?-1:1)}}const es=(e,t)=>$o(e.input,t),ts=/^[0-9a-f]{64}$/,ns=/[\u0000-\u001F\u007F]/,rs=e=>Array.isArray(e)&&e.length===2&&e.every(e=>typeof e==`number`&&Number.isFinite(e)&&e>=0&&e<=1);function is(e){let t=e=>T({path:`signature.strokes`,code:e});return!Array.isArray(e)||e.length===0||e.length>64?t(`INVALID_SIGNATURE`):JSON.stringify(e).length>32768?t(`STROKES_TOO_LARGE`):e.every(e=>Array.isArray(e)&&e.length>0&&e.every(rs))?w(e):t(`INVALID_SIGNATURE`)}function as(e){let t=T({path:`signature`,code:`INVALID_SIGNATURE`});if(!dr(e)||e.kind!==`typed`&&e.kind!==`drawn`)return t;let n=e.typedName===void 0?void 0:pr(e.typedName);if(n===null)return t;if(e.kind===`typed`)return n===void 0?t:w({kind:`typed`,typedName:n});let r=is(e.strokes);return r.ok?w({kind:`drawn`,...n===void 0?{}:{typedName:n},strokes:r.value}):r}function os(e){if(!dr(e))return T([{path:``,code:`INVALID_INPUT`}]);let t=[];e.consent!==!0&&t.push({path:`consent`,code:`CONSENT_REQUIRED`}),e.intent!==!0&&t.push({path:`intent`,code:`INTENT_REQUIRED`});let n=typeof e.docSha256==`string`&&ts.test(e.docSha256)?e.docSha256:null;n===null&&t.push({path:`docSha256`,code:`INVALID_DOC_HASH`});let r=typeof e.consentSha256==`string`&&ts.test(e.consentSha256)?e.consentSha256:null;r===null&&t.push({path:`consentSha256`,code:`INVALID_CONSENT_HASH`});let i=as(e.signature);i.ok||t.push(i.error);let a=hr(e.fieldValues);return a===null&&t.push({path:`fieldValues`,code:`INVALID_FIELDS`}),t.length>0||n===null||r===null||!i.ok||a===null?T(t):w({docSha256:n,consentSha256:r,signature:i.value,fieldValues:a})}function ss(e){if(e===void 0)return;let t=typeof e==`string`?e.trim():``;return t.length===0||[...t].length>500||ns.test(t)?null:t}async function cs(e,t,n){let r=Object.keys(n.fieldValues).sort().map(e=>[e,n.fieldValues[e]]),i=await F(n.salt+JSON.stringify([e,t.kind,t.typedName??null,t.strokes??null,r]));return{...t,sha256:i}}const ls=e=>({...e.ip===void 0?{}:{ip:e.ip},...e.ua===void 0?{}:{ua:e.ua}}),us=e=>e===void 0?{}:{signer:e};function ds(e,t,n,r){return{type:`signer.viewed`,at:e,actor:`signer`,data:{docSha256:t,...us(r)},personal:ls(n)}}function fs(e){let{at:t,docSha256:n,signature:r}=e;return[{type:`signer.consented`,at:t,actor:`signer`,data:{docSha256:n,consentVersion:e.consentVersion,consentSha256:e.consentSha256,intent:!0},personal:ls(e.who)},{type:`signer.signed`,at:t,actor:`signer`,data:{docSha256:n,kind:r.kind,signatureSha256:r.sha256},personal:{name:r.typedName??e.signerName,...ls(e.who)}},{type:`envelope.completed`,at:t,actor:`system`,data:{docSha256:n}}]}function ps(e){let{at:t,docSha256:n,hasReason:r}=e;return[{type:`signer.declined`,at:t,actor:`signer`,data:{docSha256:n,hasReason:r,...us(e.order)},personal:ls(e.who)},{type:`envelope.declined`,at:t,actor:`system`,data:{docSha256:n}}]}const ms=[`sent`,`in_progress`];function hs(e){let t=V(e).token;return typeof t==`string`&&t.length>0&&t.length<=200?t:null}const gs=e=>({...e.requestMeta?.ip?{ip:e.requestMeta.ip}:{},...e.requestMeta?.userAgent?{ua:e.requestMeta.userAgent}:{}});function _s(e){try{return e!==void 0&&new URL(e.url).searchParams.has(`token`)}catch{return!1}}function vs(e,t){let n=new Map,r,i={get:t=>{let r=n.get(t);return r||(r=e.kv.get(t),n.set(t,r)),r},set:async(e,t)=>{r={key:e,value:t}}},a=Date.now(),o=()=>Yt(i,t.requestMeta?.ip??`unknown`,a,{scope:`ceremony`,limit:20,windowSeconds:600,salt:`esign-ceremony/1`});return{async blocked(){return!(await o()).ok},async fail(){let t=await o();return t.ok&&r&&await e.kv.set(r.key,r.value),U(t.ok?`SIGNING_TOKEN_INVALID`:`RATE_LIMITED`)}}}async function ys(e,t){let{items:n}=await B(e).signers.query({where:{tokenHash:await k(t)},limit:1}),r=n[0];return r&&await le(t,r.data.tokenHash)?r:null}async function bs(e,t){let{items:n}=await B(e).signers.query({where:{copyTokenHash:await k(t)},limit:1}),r=n[0];return r?.data.copyTokenHash&&await le(t,r.data.copyTokenHash)?r:null}const xs=e=>!!(e.returnUrl&&e.clientId),Ss=(e,t)=>xs(t)?e.settings.get(`integrationMasterKey`):Promise.resolve(void 0);async function Cs(e,t,n){if(!t.returnUrl)return{};let r=await Qo(e,t,n);return{returnUrl:t.returnUrl,...r?{receipt:r}:{}}}const ws=(e,t)=>e.find(e=>e.key===t)?.value;async function Ts(e,t){let n=await(t?e.settings.list():e.settings.list(`consent`)),r=(e,t)=>{let r=ws(n,e);return typeof r==`string`&&r.length>0?r:t},i=r(`consentWording`,`I agree to use electronic records and an electronic signature for this document.`);return{version:r(`consentVersion`,`1`),wording:i,sha256:await F(i),masterKey:ws(n,`integrationMasterKey`)}}const Es=(e,t)=>e.expiresAt!==null&&e.expiresAt<=t;async function Ds(e,t,n,r){let i=await I(B(e).envelopes,t,n.status,`expired`,{closedAt:r,updatedAt:r});return i.ok&&await Wi(e,t,i.value,{type:`envelope.expired`,at:r,actor:`system`}),U(`SIGNING_TOKEN_EXPIRED`)}const Os=(e,t)=>e.signerIds.length>1?t.order:void 0;async function ks(e,t,n,r,i){let a=B(e).audit_events,o=i;for(let e=0;e<2;e++){if(o??=await Bn(t,await Hn(a,t),r,n),await Un(a,o))return o;o=void 0}throw Error(`audit chain contention`)}async function As(e,t){if(_s(e.request))return U(`TOKEN_IN_QUERY`);let n=vs(t,e),r=hs(e.input);if(r===null)return n.fail();if(await n.blocked())return U(`RATE_LIMITED`);let i=V(e.input).open===!0,{envelopes:a,snapshots:o}=B(t),s=await ys(t,r),c=s?null:await bs(t,r),l=s??c;if(!l)return n.fail();let u=await a.get(l.data.envelopeId);if(!u)return U(`ENVELOPE_NOT_FOUND`);if(c&&u.status!==`completed`)return n.fail();if(!ms.includes(u.status)||l.data.status!==`pending`){let e={ok:!0,state:`closed`,status:u.status,title:u.title,...c?{}:await Cs(l.data.envelopeId,u,await Ss(t,u))};return u.status!==`completed`||l.data.status!==`signed`?e:u.pdfSha256?{...e,pdf:`ready`,download:await Mi(t,l.data.envelopeId,Date.now())}:{...e,pdf:`pending`}}let d=j();if(Es(u,d))return Ds(t,l.data.envelopeId,u,d);let f=u.document,[p,m]=await Promise.all([u.snapshot?o.getMany(u.snapshot.ids):Promise.resolve(new Map),Ts(t,!1)]),h=f&&!u.snapshot?``:Ar([...p.values()]);if(h===null)return U(`INTERNAL`);let g=u.status,_=Os(u,l.data);if(i){let n=!1;if(u.status===`sent`&&(n=(await I(a,l.data.envelopeId,`sent`,`in_progress`,{updatedAt:d})).ok,n&&(g=`in_progress`)),_!==void 0&&(n=(await B(t).signers.updateIf(l.id,{where:{viewedAt:null},set:{viewedAt:d}})).applied),n){let n=ds(d,u.docSha256??``,gs(e),_);if(!(await Vn(B(t).audit_events,l.data.envelopeId,n,{salt:u.piiSalt})).ok)throw Error(`audit chain contention`)}}let{participant:v}=l.data;return{ok:!0,state:`ready`,envelope:{id:l.data.envelopeId,title:u.title,status:g,docSha256:u.docSha256,expiresAt:u.expiresAt},signer:{name:l.data.name,as:l.data.as,...v?{participant:v.name}:{}},snapshot:h,...f?{document:{kind:f.kind,name:f.name,bytes:f.bytes,pages:f.pages}}:{},...u.otp?{otp:l.data.otpVerifiedAt?`verified`:`required`}:{},...u.signerFields?.length?{fields:u.signerFields}:{},consent:{version:m.version,wording:m.wording,sha256:m.sha256}}}async function js(e,t,n){if(_s(e.request))return U(`TOKEN_IN_QUERY`);let r=vs(t,e),i=hs(e.input);if(i===null)return r.fail();let a=os(e.input);if(!a.ok)return H(a.error);let{envelopes:o,signers:s,audit_events:c}=B(t),l=await ys(t,i);if(!l||l.data.status!==`pending`)return r.fail();let u=l.data.envelopeId,d=await o.get(u);if(!d)return U(`ENVELOPE_NOT_FOUND`);if(d.status===`sent`)return U(`SESSION_REQUIRED`);if(d.status!==`in_progress`||d.document&&!n)return U(`ENVELOPE_CLOSED`);let f=j();if(Es(d,f))return Ds(t,u,d,f);if(d.otp&&!l.data.otpVerifiedAt)return U(`OTP_REQUIRED`);if(d.docSha256===null||a.value.docSha256!==d.docSha256)return H([{path:`docSha256`,code:`DOC_CHANGED`}]);let p=await Ts(t,xs(d));if(a.value.consentSha256!==p.sha256)return H([{path:`consentSha256`,code:`CONSENT_CHANGED`}]);let m=d.signerFields??[],h=a.value.fieldValues,g=[...Object.keys(h).filter(e=>!m.some(t=>t.key===e)).map(e=>({path:`fieldValues.${e}`,code:`INVALID_FIELDS`})),...m.filter(e=>e.required&&(h[e.key]??``).trim()===``).map(e=>({path:`fieldValues.${e.key}`,code:`INVALID_FIELDS`}))];if(g.length>0)return H(g);let _=await cs(d.docSha256,a.value.signature,{fieldValues:h,salt:d.piiSalt}),v=gs(e),y={status:`signed`,signature:_,consentAt:f,consentVersion:p.version,consentSha256:p.sha256,signedAt:f,fieldValues:h,...v};if(d.signerIds.length>1)return n?n(t,{envelopeId:u,envelope:d,signer:l,set:y,now:f}):U(`ENVELOPE_CLOSED`);let b=fs({at:f,docSha256:d.docSha256,consentVersion:p.version,consentSha256:p.sha256,signature:_,signerName:l.data.name,who:v}),x=await Bn(u,await Hn(c,u),b,d.piiSalt),S=await qn(d.docSha256,x.at(-1)?.data.hash??``),C=await I(o,u,d.status,`completed`,{completedAt:f,finalHash:S,updatedAt:f});if(!C.ok)return U(`ENVELOPE_CLOSED`);if(await s.updateIf(l.id,{where:{status:`pending`},set:y}),!await Un(c,x))throw Error(`audit chain contention`);return await Ci(t.cron,u,Date.parse(f)),{ok:!0,status:`completed`,completedAt:f,...await Cs(u,C.value,p.masterKey)}}async function Ms(e,t){if(_s(e.request))return U(`TOKEN_IN_QUERY`);let n=vs(t,e),r=hs(e.input);if(r===null)return n.fail();let i=ss(V(e.input).reason);if(i===null)return H([{path:`reason`,code:`INVALID_INPUT`}]);let{envelopes:a,signers:o}=B(t),s=await ys(t,r);if(!s||s.data.status!==`pending`)return n.fail();let c=s.data.envelopeId,l=await a.get(c);if(!l)return U(`ENVELOPE_NOT_FOUND`);if(!Qn(l.status,`declined`))return U(`ENVELOPE_CLOSED`);let u=j();if(Es(l,u))return Ds(t,c,l,u);let d=await I(a,c,l.status,`declined`,{closedAt:u,updatedAt:u});if(!d.ok)return U(`ENVELOPE_CLOSED`);let f=gs(e);return await o.updateIf(s.id,{where:{status:`pending`},set:{status:`declined`,declinedAt:u,...i===void 0?{}:{declineReason:i},...f}}),await ks(t,c,l.piiSalt,ps({at:u,docSha256:l.docSha256,hasReason:i!==void 0,who:f,order:Os(l,s.data)})),{ok:!0,status:`declined`,...await Cs(c,d.value,await Ss(t,d.value))}}const Ns=e=>(t,n)=>e(t,n),Ps=(e=>({"public/session":Ns(As),"public/submit":Ns((t,n)=>js(t,n,e)),"public/decline":Ns(Ms)}))(),Fs=[`sent`,`in_progress`];function Is(e){try{return new URL(e.site.url).origin}catch{return}}async function Ls(e,t,n={}){let r=(n.now??Date.now)(),i=j(r),{envelopes:a,signers:o,snapshots:s,templates:c,nonces:l}=B(t),u=Zo(t),d=await tt({token:V(e).intent,now:r,getClient:u.getClient,consumeNonce:async(e,t,n)=>{let r=`${e}.${t}`;try{let t={nonce:r,cid:e,expiresAt:j(n*1e3)};return(await l.compareAndSet(r,null,t)).applied}catch(e){if(zi(e))return!1;throw e}},siteOrigin:Is(t)});if(!d.ok)return U(d.error);let f=d.value,p=u.settings();if(f.replace===!0)return Vs(t,f,i);let m=f.tplVersion===void 0?void 0:L(f.tpl,f.tplVersion),h=await c.getMany(m===void 0?[f.tpl]:[f.tpl,m]),g=h.get(f.tpl);if(!ar(g))return U(`TEMPLATE_NOT_FOUND`);let _=vr(g,m===void 0?void 0:h.get(m),f.tplVersion);if(!_.ok)return U(`TEMPLATE_NOT_FOUND`);let v=Nn(n.random),y=Cr(f,_.value,{now:i,piiSalt:v});if(!y.ok)return H(y.error);let b={delivery:y.value.delivery,signer:y.value.signer},x=f.resend===!0?(e,n,i)=>On(t,{signerId:e,envelope:n,token:i,senderSetting:p.senderName,now:r}):void 0,S=Ri(p.expiryDays),C=wr(f),w=async(e,t,r)=>Bs(o,e,await zs(a,e,t,C,S,i),b,n.random,r),T=se(n.random),ee=await k(T),te=async e=>{let t=await Pr(f.cid,f.ref,e);return{id:t,sent:await jr(t,y.value,_.value,{now:i,tokenHash:ee,expiryDays:S})}},E=await te(1);if(!E.sent.ok)return Array.isArray(E.sent.error)?H(E.sent.error):U(`INTERNAL`);let ne=await a.compareAndSet(E.id,null,E.sent.value.envelope);if(!ne.applied){let e=await a.query({where:{clientId:f.cid,externalRef:f.ref},limit:100}),n=Nr(e.items);if(n)return n.data.status===`draft`&&await ca(t.cron,n.id,r),w(n.id,n.data,x);let i=Math.max(e.items.length,1)+1;if(y.value.delivery===`email`){let e=await Pr(f.cid,f.ref,i);if(!(await a.compareAndSet(e,null,y.value)).applied){let t=await a.get(e);return t?w(e,t):U(`INTERNAL`)}return await ca(t.cron,e,r),$(e,y.value,void 0)}if(E=await te(i),!E.sent.ok)return Array.isArray(E.sent.error)?H(E.sent.error):U(`INTERNAL`);if(ne=await a.compareAndSet(E.id,null,E.sent.value.envelope),!ne.applied){let e=await a.get(E.id);return e?w(E.id,e):U(`INTERNAL`)}}let{id:D,sent:O}=E;if(!O.ok)return U(`INTERNAL`);await s.putMany(O.value.chunks);let re=await Vi(o,O.value.signer,T,n.random);O.value.envelope.delivery===`email`&&await On(t,{signerId:O.value.signer.id,envelope:O.value.envelope,token:re,senderSetting:p.senderName,now:r});let ie=[Fr(y.value,`integration`),Ir(O.value.envelope,`integration`)];return await B(t).audit_events.putMany(await zn(D,ie,v)),$(D,O.value.envelope,re)}function $(e,t,n,r=t.delivery===`inline`){return{ok:!0,envelopeId:e,status:t.status,...n!==void 0&&r?{signingToken:n}:{}}}function Rs(e,t){let n=e.signer;return n.email===t.email&&n.as===t.as&&(n.participant?.name??null)===(t.participant?.name??null)}async function zs(e,t,n,r,i,a){if(r===void 0)return n;let o={applied:!1};if(n.status===`draft`)n.signBy!==void 0&&n.signBy<r&&(o=await e.updateIf(t,{where:{status:`draft`,signBy:{lt:r}},set:{signBy:r,updatedAt:a}}));else if(Fs.includes(n.status)&&n.sentAt&&n.expiresAt){let s=Tr(n.sentAt,i,r);s>n.expiresAt&&(o=await e.updateIf(t,{where:{status:{in:Fs},expiresAt:{lt:s}},set:{expiresAt:s,signBy:r,updatedAt:a}}))}return o.applied?o.data:n}async function Bs(e,t,n,r,i,a){let o=n.signerIds[0],s=(n.status===`sent`||n.status===`in_progress`)&&Rs(n,r.signer),c=r.delivery===`inline`&&s,l=a!==void 0&&r.delivery===`email`&&n.delivery===`email`&&s;if(!c&&!l||o===void 0)return $(t,n,void 0);let u=await Bi(se(i),i,t=>e.updateIf(o,{where:{status:`pending`},set:{tokenHash:t}}));if(!u.value.applied)return $(t,n,void 0);if(c||!a)return $(t,n,u.token,!0);let d=await a(o,n,u.token);return{...$(t,n,void 0),...d?{resent:!0}:{}}}async function Vs(e,t,n){let{envelopes:r}=B(e),i=Nr((await r.query({where:{clientId:t.cid,externalRef:t.ref},limit:100})).items);if(!i)return{ok:!0,status:`none`};let a=i.data.signer;if(a.name===t.signer.name.trim()&&a.email===t.signer.email.trim().toLowerCase()&&a.as===(t.as??`self`)&&(a.participant?.name??null)===(t.participant?.name.trim()??null)||i.data.status===`completed`)return $(i.id,i.data,void 0);let o=await I(r,i.id,i.data.status,`voided`,{closedAt:n,updatedAt:n});return o.ok?(await Wi(e,i.id,o.value,{type:`envelope.voided`,at:n,actor:`integration`}),$(i.id,o.value,void 0)):U(`ENVELOPE_CLOSED`)}const Hs=(e,t)=>Ls(e.input,t),Us=`integrations:site-client`,Ws=[`origin`,`sec-fetch-mode`,`sec-fetch-site`,`sec-fetch-dest`],Gs={ADMIN_REQUIRED:`Only an administrator can pair plugins.`,SERVER_ONLY:`Pairing runs on the server only.`,BAD_REQUEST:`The request was not valid.`,MASTER_KEY_INVALID:`The integration master key is unreadable or shorter than 32 characters.`,ENCRYPTION_KEY_MISSING:`EMDASH_ENCRYPTION_KEY is not set, so the master key cannot be saved.`},Ks=e=>({ok:!1,error:{code:e,message:Gs[e]}});function qs(e,t){if(e)return typeof e.get==`function`?e.get(t)??void 0:e[t]}const Js=e=>e!=null&&e!==``,Ys={"integrations/pair":{handler:(async(e,t)=>{let n=e.user?.role;if(typeof n!=`number`||n<50)return Ks(`ADMIN_REQUIRED`);if(Ws.some(t=>qs(e.request?.headers,t)!==void 0))return Ks(`SERVER_ONLY`);let r=V(e.input),i=r.action;if(i!==`status`&&i!==`pair`&&i!==`unpair`)return Ks(`BAD_REQUEST`);let a=r.clientId;if(a!==void 0&&(typeof a!=`string`||!_e.test(a)))return Ks(`BAD_REQUEST`);let o=B(t).clients,[s,c]=await Promise.all([t.settings.list(),t.kv.get(Us)]),l=typeof c==`string`?c:null,u=typeof a==`string`?a:l,[d,f]=await Promise.all([u?o.get(u):null,l&&l!==u&&i!==`status`?o.get(l):null]),p=d!==null&&!d.revokedAt,m=f!==null&&!f.revokedAt,h=j();if(i===`status`)return d&&u?{ok:!0,client:p?`active`:`revoked`,clientId:u}:{ok:!0,client:`none`};if(i===`unpair`)return m&&l&&await La(o,l,h),{ok:!0,revoked:p&&u?await La(o,u,h):!1};let g=s.find(e=>e.key===`integrationMasterKey`)?.value;if(!Js(g)){g=Na();try{await t.settings.set(`integrationMasterKey`,g)}catch(e){if(Ba(e))return Ks(`ENCRYPTION_KEY_MISSING`);throw e}}let _=W(g);if(!_)return Ks(`MASTER_KEY_INVALID`);let v=p&&u?u:m?l:null;if(v)return v!==l&&(await t.kv.set(Us,v),m&&l&&await La(o,l,h)),{ok:!0,created:!1,clientId:v,pairing:pt(v,await mt(_,v))};let y=await Ia(o,{name:`Events on this site`,returnUrlAllowlist:[],masterKey:g},{now:h});return y.ok?(await t.kv.set(Us,y.client.clientId),{ok:!0,created:!0,clientId:y.client.clientId,pairing:y.pairing}):Ks(`MASTER_KEY_INVALID`)})}},Xs=64*1024,Zs=[{name:`public/envelopes/from-intent`,methods:[`POST`],body:`json`,maxBytes:16*1024},{name:`public/session`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/otp/send`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/otp/verify`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/submit`,methods:[`POST`],body:`json`,maxBytes:256*1024},{name:`public/decline`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/download`,methods:[`GET`],body:`none`,response:`raw`},{name:`public/verify`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/receipts/lookup`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/templates/catalog`,methods:[`POST`],body:`json`,maxBytes:Xs},{name:`public/self-serve/start`,methods:[`POST`],body:`json`,maxBytes:Xs}];async function Qs(){return D({code:`NOT_FOUND`}).body}function $s(e={}){let t={};for(let n of Zs)t[n.name]={public:!0,methods:[...n.methods],request:n.maxBytes===void 0?{body:n.body}:{body:n.body,maxBytes:n.maxBytes},...n.response?{response:n.response}:{},handler:e[n.name]??Qs};return t}const ec=e=>Number(/_(\d+)$/.exec(e)?.[1]??0);function tc(e){let t;for(let n of e)(!t||ec(n.id)>ec(t.id)||ec(n.id)===ec(t.id)&&n.data.createdAt>t.data.createdAt)&&(t=n);return t}async function nc(e,t,n=Date.now()){let r=Zo(t),i=await rt({token:V(e).request,now:n,getClient:r.getClient});if(!i.ok)return U(i.error);let{cid:a,ref:o}=i.value,s=tc((await B(t).envelopes.query({where:{clientId:a,externalRef:o},limit:100})).items.filter(e=>e.data.clientId===a&&e.data.externalRef===o));if(!s)return{ok:!0,state:`none`,receipt:null};if(!$n(s.data.status))return{ok:!0,state:`pending`,receipt:null};let c=await Qo(s.id,s.data,r.settings().integrationMasterKey);return c?{ok:!0,state:`terminal`,receipt:c}:U(`INTERNAL`)}const rc=(e,t)=>nc(e.input,t),ic=/^[0-9a-f]{64}$/,ac=async(e,t)=>{let n=V(e.input).sha256,r=typeof n==`string`?n.toLowerCase():``;if(!ic.test(r))return H([{path:`sha256`,code:`invalid`}]);if(!(await Yt({get:e=>t.kv.get(e),set:(e,n)=>t.kv.set(e,n)},e.requestMeta?.ip??`unknown`,Date.now(),{scope:`esign-verify`,limit:20,windowSeconds:600,salt:`esign-verify/1`})).ok)return U(`RATE_LIMITED`);let{envelopes:i,audit_events:a}=B(t),o=(await i.query({where:{pdfSha256:r},limit:1})).items[0];if(!o||o.data.status!==`completed`)return{ok:!0,matched:!1};let s=o.data,{items:c}=await a.query({where:{envelopeId:o.id},orderBy:{seq:`asc`},limit:101}),l=null;if(c.length<=100){let e=c.map(e=>e.data),t=await Gn(o.id,e);l=t.ok&&s.docSha256!==null&&e.at(-1)?.type===`envelope.completed`&&await qn(s.docSha256,t.value.head)===s.finalHash}return{ok:!0,matched:!0,status:s.status,completedAt:s.completedAt,finalHash:s.finalHash,chainVerified:l}},oc=[{name:Cn,schedule:`* * * * *`},{name:fa,schedule:`0 * * * *`},{name:ga,schedule:`23 3 * * *`},{name:ra,schedule:`17 * * * *`}],sc=$s({"public/envelopes/from-intent":Hs,"public/download":Fi,"public/verify":ac,"public/receipts/lookup":rc,"public/templates/catalog":es,...Ps}),cc={hooks:{"plugin:activate":async(e,t)=>{await en(t,oc)},cron:async(e,t)=>{await nn(e,t,oc,Date.now())||await An(e,t)||await na(e,t)||await da(e,t)||await ha(e,t)||await Oa(e,t)||await aa(e,t)||await Ti(e,t)}},routes:{...sc,...Go,...qa,...Zi,...Ys,admin:an(Go.admin,rn),"templates/create":an(qa[`templates/create`]),"public/verify":an(sc[`public/verify`])}};export{cc as default};
|
|
36
|
+
`),0)}const ai=262144/4*3,oi={self:`Self`,guardian:`Parent or guardian`,buyer:`Buyer`},si=e=>e?`${e.slice(0,10)} ${e.slice(11,19)} UTC`:``;function ci(e){return e.map(e=>{switch(e.type){case`text`:case`code`:return e.text;case`break`:return`
|
|
37
|
+
`;case`link`:{let t=ci(e.children);return t===e.href?t:`${t} (${e.href})`}default:return ci(e.children)}}).join(``)}function li(e){let t=[],n=(e,r)=>{for(let i of e)switch(i.type){case`heading`:t.push({type:`heading`,text:ci(i.children),level:Math.min(i.level,3)});break;case`paragraph`:t.push({type:`paragraph`,text:ci(i.children),...r?{font:`italic`}:{}});break;case`list`:i.items.forEach((e,n)=>{let a=i.ordered?`${(i.start??1)+n}.`:`•`;t.push({type:`paragraph`,text:`${a} ${ci(e)}`,...r?{font:`italic`}:{}})});break;case`quote`:n(i.children,!0);break;case`code`:t.push({type:`paragraph`,text:i.text,size:9});break;case`rule`:t.push({type:`rule`});break}};return n(ii(e),!1),t}function ui(e){let t=e.signature,n=[e.name,`Signed ${si(e.signedAt)}`];return t?.kind===`drawn`&&t.strokes?{type:`signature`,label:`Signature`,strokes:{v:1,w:1,h:1,strokes:t.strokes},caption:t.typedName?[t.typedName,...n]:n}:{type:`signature`,label:`Signature`,typedName:t?.typedName??e.name,caption:n}}function di(e,t,n){let r=e.envelope.signerFields??[];if(r.length===0)return[];let i=t.fieldValues??{};return[{type:`spacer`,height:12},{type:`heading`,text:`Details entered by ${n?t.name:`the signer`}`,level:2},{type:`table`,columns:[{header:`Field`},{header:`Value`,width:2}],rows:r.map(e=>[e.label,i[e.key]??``])}]}function fi(e){let{envelope:t,signers:n,events:r,head:i,envelopeId:a}=e,o=n.length>1,s=[[`Envelope`,a],[`Document`,t.title],[`Document SHA-256`,t.docSha256??``],...n.flatMap((e,t)=>[[o?`Signer ${t+1}`:`Signer`,e.name],[`Signing as`,oi[e.as]??e.as],...e.participant?[[`Participant`,e.participant.name]]:[],[`Signature`,e.signature?.kind===`drawn`?`Drawn`:`Typed`],[`Signature SHA-256`,e.signature?.sha256??``],[`Consent version`,e.consentVersion??``],...e.consentSha256?[[`Consent wording SHA-256`,e.consentSha256]]:[],...e.otpVerifiedAt?[[`Identity check`,`Email one-time code verified`]]:[],[`Signed`,si(e.signedAt)]]),[`Completed`,si(t.completedAt)],[`Audit events`,String(r.length)]],c=r.map(e=>[String(e.seq+1),si(e.at),e.type,typeof e.data.signer==`number`?`signer ${e.data.signer}`:e.actor,e.personal?.ip??``,e.hash.slice(0,16)]);return{info:{title:t.title,subject:`Signed document and certificate of completion`,creator:`semics e-sign`,...t.completedAt?{creationDate:new Date(t.completedAt)}:{}},footer:{text:`Envelope ${a}`,pageNumbers:!0},blocks:[{type:`heading`,text:t.title,level:1},...li(e.snapshot),...n.flatMap(t=>[...di(e,t,o),{type:`spacer`,height:18},ui(t)]),{type:`pageBreak`},{type:`heading`,text:`Certificate of completion`,level:1},{type:`paragraph`,text:`This certificate records how the document above was signed. It was signed with a simple electronic signature: the signer consented to sign electronically, confirmed their intent to sign, and signed the exact text identified by the document SHA-256 below. Every step is recorded in a hash-chained audit trail; the final hash binds the document to the end of that trail. Anyone holding this PDF can check these values on the verify page.`},{type:`spacer`,height:8},{type:`table`,columns:[{header:`Field`},{header:`Value`,width:3}],rows:s},{type:`spacer`,height:8},{type:`heading`,text:`Audit trail`,level:2},{type:`table`,columns:[{header:`#`,width:.4},{header:`Time`,width:1.6},{header:`Event`,width:1.6},{header:`Actor`,width:.8},{header:`IP address`,width:1.2},{header:`Event hash (first 16)`,width:1.6}],rows:c,size:8},{type:`spacer`,height:8},{type:`paragraph`,text:`Audit chain head`,font:`bold`,size:9},{type:`paragraph`,text:i,size:9},{type:`paragraph`,text:`Final hash`,font:`bold`,size:9},{type:`paragraph`,text:t.finalHash??``,size:9}]}}async function pi(e){let t=Gt(fi(e));return{bytes:t,sha256:await F(t)}}const R=new TextEncoder().encode(`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`);function mi(e){let t=new Uint8Array(Math.ceil(e.length/3)*4),n=e.length-e.length%3,r=0;for(let i=0;i<n;i+=3){let n=e[i]<<16|e[i+1]<<8|e[i+2];t[r++]=R[n>>18],t[r++]=R[n>>12&63],t[r++]=R[n>>6&63],t[r++]=R[n&63]}if(n<e.length){let i=n+1<e.length,a=e[n]<<16|(i?e[n+1]<<8:0);t[r++]=R[a>>18],t[r++]=R[a>>12&63],t[r++]=i?R[a>>6&63]:61,t[r++]=61}return new TextDecoder().decode(t)}function hi(e){try{let t=atob(e),n=new Uint8Array(t.length);for(let e=0;e<t.length;e++)n[e]=t.charCodeAt(e);return n}catch{return null}}const gi=(e,t,n)=>`${e}:pdf:${t.slice(0,16)}:${n}`;function _i(e,t,n){let r=Math.max(1,Math.ceil(t.length/ai));return Array.from({length:r},(i,a)=>({id:gi(e,n,a),data:{envelopeId:e,kind:`signed-pdf`,contentType:`application/pdf`,index:a,count:r,bytes:t.length,sha256:n,data:mi(t.subarray(a*ai,(a+1)*ai))}}))}function vi(e){let t=e[0];if(!t||e.length!==t.count)return null;let n=[...e].sort((e,t)=>e.index-t.index),r=new Uint8Array(t.bytes),i=0;for(let[e,a]of n.entries()){if(a.index!==e||a.sha256!==t.sha256||a.bytes!==t.bytes)return null;let n=hi(a.data);if(!n||i+n.length>r.length)return null;r.set(n,i),i+=n.length}return i===r.length?r:null}const yi=`signed-pdf-`,bi=e=>`${yi}${e}`;function xi(e,t,n,r=0){return e?.schedule(bi(t),{schedule:A(n),data:{envelopeId:t,attempt:r}})}async function Si(e,t,n){let{envelopes:r,signers:i,snapshots:a,audit_events:o,artifacts:s}=B(e),c=await r.get(t);if(!c||c.status!==`completed`||c.pdfSha256||c.personalPurgedAt||c.signerIds.length===0||!c.snapshot||!c.docSha256)return`skipped`;let[l,u,d]=await Promise.all([i.getMany(c.signerIds),a.getMany(c.snapshot.ids),o.query({where:{envelopeId:t},orderBy:{seq:`asc`},limit:100})]),f=Or([...u.values()]),p=d.items.map(e=>e.data),m=await Un(t,p),h=m.ok&&p.at(-1)?.type===`envelope.completed`&&await Gn(c.docSha256,m.value.head)===c.finalHash,g=c.signerIds.map(e=>l.get(e));if(g.some(e=>e?.status!==`signed`)||f===null||!m.ok||!h){let r=n.attempt??0;return r+1>=5?(e.log.error(`signed PDF not generated: the envelope never settled`,{envelopeId:t}),`gave-up`):(await xi(e.cron,t,n.now+6e4,r+1),`retry`)}let{bytes:_,sha256:v}=await pi({envelopeId:t,envelope:c,signers:g,snapshot:f,events:p,head:m.value.head}),y=_i(t,_,v);return await s.putMany(y),(await r.updateIf(t,{where:{status:`completed`,pdfSha256:null},set:{pdfSha256:v,pdf:{ids:y.map(e=>e.id),bytes:_.length},updatedAt:A(n.now)}})).applied?(await Qi(e.cron,t,n.now),`stored`):`skipped`}async function Ci(e,t){if(!e.name.startsWith(yi))return!1;let n=e.data?.envelopeId,r=e.data?.attempt;return typeof n!=`string`||n.length===0||await Si(t,n,{now:Date.now(),attempt:typeof r==`number`&&Number.isSafeInteger(r)?r:0}),!0}const wi=`esign/download`,Ti=`esign:download-link-key`,Ei=/^[A-Za-z0-9_:.-]{1,200}$/,Di=RegExp(`^[0-9a-f]{64}$`);function Oi(e){return typeof e!=`string`||!Di.test(e)?null:Uint8Array.from(e.match(/../g),e=>Number.parseInt(e,16))}async function ki(e){let t=Oi(await e.get(Ti));if(t)return t;let n=crypto.getRandomValues(new Uint8Array(32));if((await e.compareAndSet(Ti,null,S(n))).applied)return n;let r=Oi(await e.get(Ti));if(!r)throw Error(`download link key unavailable`);return r}async function Ai(e,t,n){let r=await fe({secret:await ki(e.kv),purpose:wi,params:{e:t},now:n,ttlMs:9e5}),i=A(Number(r.get(`exp`))*1e3);return{url:`/_emdash/api/plugins/${e.plugin.id}/public/download?${r}`,expiresAt:i}}function z(e){let{status:t,body:n}=D(e);return Fr({status:t,headers:{"content-type":`application/json; charset=utf-8`,"cache-control":`no-store`},body:{kind:`text`,value:JSON.stringify(n)}})}function ji(e){try{return e?.url?new URL(e.url).searchParams:null}catch{return null}}async function Mi(e,t){let n=ji(e.request);if(!n)return z(`TOKEN_INVALID`);if(n.has(`token`))return z(`TOKEN_IN_QUERY`);let r=Date.now(),i=await pe({secret:await ki(t.kv),purpose:wi,query:n,now:r});if(!i.ok)return z(i.error);let a=i.value.e;if(typeof a!=`string`||!Ei.test(a))return z(`TOKEN_INVALID`);let{envelopes:o,artifacts:s}=B(t),c=await o.get(a);if(!c||c.status!==`completed`||c.recordsPurgedAt)return z(`ENVELOPE_NOT_FOUND`);if(!c.pdfSha256||!c.pdf)return await xi(t.cron,a,r),z(`SIGNED_PDF_PENDING`);let l=vi([...(await s.getMany(c.pdf.ids)).values()]);return!l||await F(l)!==c.pdfSha256?(t.log.error(`signed PDF chunks do not match pdfSha256`,{envelopeId:a}),z(`INTERNAL`)):Fr({status:200,headers:{"content-type":`application/pdf`,"content-disposition":`attachment; filename="signed-${a.replace(/[^A-Za-z0-9_-]/g,`_`)}.pdf"`,"cache-control":`private, no-store`,"x-content-type-options":`nosniff`,"referrer-policy":`no-referrer`},body:{kind:`bytes`,value:l}})}const Ni=(e,t)=>Mi(e,t),Pi=e=>typeof e.user?.id==`string`&&e.user.id.length>0?e.user.id:void 0,B=e=>e.storage,V=e=>typeof e==`object`&&e?e:{},H=e=>({...D(`BAD_REQUEST`).body,...e?{issues:e}:{}}),U=e=>D(e).body;function Fi(e){let t=V(e).id;return typeof t==`string`&&t.length>0&&t.length<=200?t:null}function Ii(e){return Number.isSafeInteger(e)&&e>=1&&e<=365?e:30}function Li(e){return e instanceof Error&&e.message.includes(`UNIQUE constraint failed`)}async function Ri(e,t,n){let r=e;for(let e=1;;e++)try{return{token:r,value:await n(await oe(r))}}catch(n){if(!Li(n)||e>=3)throw n;r=ae(t)}}async function zi(e,t,n,r){let{token:i}=await Ri(n,r,n=>e.put(t.id,{...t.data,tokenHash:n}));return i}const Bi=(e,{piiSalt:t,...n})=>({id:e,...n}),Vi=(e,{snapshot:t,fieldValues:n,piiSalt:r,...i})=>({id:e,...i});async function Hi(e,t,n,r){if(!(await zn(B(e).audit_events,t,r,{salt:n.piiSalt})).ok)throw Error(`audit chain contention`)}async function Ui(e,t){let n=hr(e.input);if(!n.ok)return H(n.error);let{templateId:r,templateVersion:i}=n.value,{templates:a,envelopes:o,audit_events:s}=B(t),c=await a.getMany(i===void 0?[r]:[r,L(r,i)]),l=gr(c.get(r),i===void 0?void 0:c.get(L(r,i)),i);if(!l.ok)return U(`TEMPLATE_NOT_FOUND`);let u=jn(),d=br(n.value,l.value,{now:A(),piiSalt:u});if(!d.ok)return H(d.error);let f=crypto.randomUUID();return await o.put(f,d.value),await s.putMany(await Ln(f,[Nr(d.value,`admin`,Pi(e))],u)),{ok:!0,envelope:Bi(f,d.value)}}async function Wi(e,t){let n=Fi(e.input);if(!n)return H();let{envelopes:r,templates:i,snapshots:a,signers:o}=B(t),s=await r.get(n);if(!s)return U(`ENVELOPE_NOT_FOUND`);if(!Xn(s.status,`sent`))return U(`ENVELOPE_CLOSED`);let{templateId:c,templateVersion:l}=s,[u,d]=await Promise.all([i.getMany([c,L(c,l)]),t.settings.list()]),f=Object.fromEntries(d.map(e=>[e.key,e.value])),p=gr(u.get(c),u.get(L(c,l)),l);if(!p.ok)return U(`TEMPLATE_NOT_FOUND`);let m=ae(),h=await kr(n,{...s,...await void 0},p.value,{now:A(),tokenHash:await oe(m),expiryDays:Ii(f.expiryDays)});if(!h.ok)return Array.isArray(h.error)?H(h.error):U(`ENVELOPE_CLOSED`);await a.putMany(h.value.chunks);let g=await I(r,n,`draft`,`sent`,h.value.envelope);if(!g.ok)return U(`ENVELOPE_CLOSED`);let _=await zi(o,h.value.signer,m),v=await En(t,{signerId:h.value.signer.id,envelope:g.value,token:_,senderSetting:f.senderName,now:Date.now()});return await Hi(t,n,g.value,Pr(g.value,`admin`,Pi(e))),{ok:!0,envelope:Bi(n,g.value),...v?{}:{invitation:`SITE_URL_MISSING`}}}async function Gi(e,t){let n=Fi(e.input);if(!n)return H();let{envelopes:r,snapshots:i,signers:a}=B(t),o=await r.get(n);if(!o)return U(`ENVELOPE_NOT_FOUND`);let[s,c]=await Promise.all([o.snapshot?i.getMany(o.snapshot.ids):Promise.resolve(new Map),o.signerIds.length>0?a.getMany(o.signerIds):Promise.resolve(new Map)]),l=o.pdfSha256?await Ai(t,n,Date.now()):null;return{ok:!0,envelope:Bi(n,o),download:l,snapshot:o.snapshot?Or([...s.values()]):null,signers:[...c].map(([e,t])=>({id:e,order:t.order,name:t.name,email:t.email,status:t.status}))}}async function Ki(e,t){let n=Fi(e.input);if(!n)return H();let{envelopes:r,signers:i,outbox:a,audit_events:o}=B(t),s=await r.get(n);if(!s)return U(`ENVELOPE_NOT_FOUND`);let c=s.signerIds[0];if(s.status!==`sent`||c===void 0)return U(`ENVELOPE_CLOSED`);if(!Cn(t))return{ok:!1,error:{code:`SITE_URL_MISSING`,message:Tn}};let l=Nn(n,0),u=Nn(n,1),[d,f,p]=await Promise.all([t.settings.get(`senderName`),a.get(`invite-${c}`),o.getMany([l,u])]);if(f&&f.status!==`failed`)return{ok:!1,error:{code:`INVITATION_QUEUED`,message:`The invitation is already queued or sent.`}};let m=await Ri(ae(),void 0,e=>i.updateIf(c,{where:{status:`pending`},set:{tokenHash:e}}));if(!m.value.applied)return U(`ENVELOPE_CLOSED`);await En(t,{signerId:c,envelope:s,token:m.token,senderSetting:d,now:Date.now()});let h=!1;p.has(u)||(h=await Vn(o,await Rn(n,p.get(l)??null,[Pr(s,`admin`,Pi(e))],s.piiSalt)));let{name:g,email:_,status:v}=m.value.data;return{ok:!0,envelope:Bi(n,s),signers:[{id:c,order:m.value.data.order,name:g,email:_,status:v}],repaired:h}}async function qi(e,t){let n=Fi(e.input);if(!n)return H();let r=await B(t).envelopes.get(n);if(!r)return U(`ENVELOPE_NOT_FOUND`);let i=A(),a=await I(B(t).envelopes,n,r.status,`voided`,{closedAt:i,updatedAt:i});return a.ok?(await Hi(t,n,a.value,{type:`envelope.voided`,at:i,actor:`admin`,...Pi(e)?{data:{userId:Pi(e)}}:{}}),{ok:!0,envelope:Bi(n,a.value)}):U(`ENVELOPE_CLOSED`)}async function Ji(e,t){let{status:n,cursor:r}=V(e.input);if(n!==void 0&&!Yn(n)||r!==void 0&&!(typeof r==`string`&&r.length>0&&r.length<=500))return H();let i=await B(t).envelopes.query({...n===void 0?{}:{where:{status:n}},orderBy:{createdAt:`desc`},limit:100,...r===void 0?{}:{cursor:r}});return{ok:!0,envelopes:i.items.map(e=>Vi(e.id,e.data)),...i.hasMore&&i.cursor?{nextCursor:i.cursor}:{}}}const Yi={"envelopes/create":{handler:Ui},"envelopes/send":{handler:Wi},"envelopes/get":{handler:Gi},"envelopes/list":{handler:Ji},"envelopes/resend":{handler:Ki},"envelopes/void":{handler:qi},"outbox/status":{handler:(async(e,t)=>({ok:!0,...await kn(t)}))}},Xi=`completion-email-`,Zi=e=>`${Xi}${e}`;function Qi(e,t,n){return e?.schedule(Zi(t),{schedule:A(n),data:{envelopeId:t}})}async function $i(e,t,n){let[r,i,a]=await Promise.all([B(e).envelopes.get(t),e.settings.get(`senderName`),B(e).outbox.get(`complete-${t}`)]);if(!r||r.status!==`completed`||!r.pdfSha256||a)return!1;let o=r.signerIds[0];if(o===void 0||!Cn(e))return!1;let s=await Ri(ae(),void 0,t=>B(e).signers.updateIf(o,{where:{status:`signed`},set:{copyTokenHash:t}}));return s.value.applied?(await Dn(e,{envelopeId:t,envelope:r,token:s.token,senderSetting:i,now:n}),!0):!1}async function ea(e,t){if(!e.name.startsWith(Xi))return!1;let n=e.data?.envelopeId;return typeof n==`string`&&n.length>0&&await $i(t,n,Date.now()),!0}const ta=`expire`,na=`expire-more`;async function ra(e,t){if(e.name!==ta&&e.name!==na)return!1;let{envelopes:n}=B(t),r=A(),i=await n.query({where:{status:{in:[`sent`,`in_progress`]},expiresAt:{lt:r}},orderBy:{expiresAt:`asc`},limit:2});for(let{id:e,data:a}of i.items){let i=await I(n,e,a.status,`expired`,{closedAt:r,updatedAt:r});i.ok&&await Hi(t,e,i.value,{type:`envelope.expired`,at:r,actor:`system`})}return i.hasMore&&await t.cron?.schedule(na,{schedule:A(Date.now()+6e4)}),!0}function W(e){if(typeof e!=`string`)return null;let t=new TextEncoder().encode(e.trim());return t.length>=32?t:null}const ia=`intent-finish-`,aa=e=>`${ia}${e}`;function oa(e,t,n){return e?.schedule(aa(t),{schedule:A(n),data:{envelopeId:t}})}async function sa(e,t){let n=await C(e),r=await crypto.subtle.sign(`HMAC`,n,new TextEncoder().encode(`esign-invite/1.${t}`));return x(new Uint8Array(r))}async function ca(e,t,n){let{envelopes:r,templates:i,snapshots:a,signers:o,audit_events:s}=B(e),c=await r.get(t);if(!c||c.status!==`draft`||c.delivery!==`email`||!c.clientId)return`skipped`;let l=L(c.templateId,c.templateVersion),[u,d]=await Promise.all([i.getMany([c.templateId,l]),e.settings.list()]),f=Object.fromEntries(d.map(e=>[e.key,e.value])),p=gr(u.get(c.templateId),u.get(l),c.templateVersion);if(!p.ok)return`skipped`;let m=W(f.integrationMasterKey);if(!m)return`skipped`;let h=await sa(m,t),g=await kr(t,c,p.value,{now:A(n),tokenHash:await oe(h),expiryDays:Ii(f.expiryDays)});if(!g.ok)return`skipped`;await a.putMany(g.value.chunks);let _=await zi(o,g.value.signer,h);await En(e,{signerId:g.value.signer.id,envelope:g.value.envelope,token:_,senderSetting:f.senderName,now:n});let v=[Nr(c,`integration`),Pr(g.value.envelope,`integration`)];return await s.putMany(await Ln(t,v,c.piiSalt)),(await I(r,t,`draft`,`sent`,g.value.envelope)).ok?`sent`:`skipped`}async function la(e,t){if(!e.name.startsWith(ia))return!1;let n=e.data?.envelopeId;return typeof n==`string`&&n.length>0&&await ca(t,n,Date.now()),!0}const ua=`nonce-sweep`,da=`nonce-sweep-more`;async function fa(e){let{nonces:t,cron:n,now:r,page:i=100,pages:a=3}=e,o=A(r),s=0,c=!1;for(let e=0;e<a;e++){let e=await t.query({where:{expiresAt:{lt:o}},orderBy:{expiresAt:`asc`},limit:i});if(e.items.length===0||(s+=await t.deleteMany(e.items.map(e=>e.id)),c=e.hasMore===!0,!c))break}return c&&await n?.schedule(da,{schedule:A(r+6e4)}),{deleted:s,more:c}}async function pa(e,t){if(e.name!==ua&&e.name!==da)return!1;let n=t.storage.nonces;return await fa({nonces:n,cron:t.cron,now:Date.now()}),!0}const ma=`retention`,ha=`retention-more`,ga=`cron:retention`,_a=e=>e.status===`sent`||e.status===`in_progress`,va=e=>_a(e)?null:Date.parse(e.completedAt??e.closedAt??e.updatedAt),ya=(e,t,n,r)=>{let i=e.find(e=>e.key===t)?.value;return typeof i==`number`&&Number.isFinite(i)?Math.min(r,Math.max(1,Math.round(i))):n};function ba(e,t){let n=new Date(t);n.setUTCMonth(n.getUTCMonth()-ya(e,`retentionPersonalDataMonths`,12,120));let r=new Date(t);return r.setUTCFullYear(r.getUTCFullYear()-ya(e,`retentionSignedRecordsYears`,7,50)),{p:Math.max(n.getTime(),r.getTime()),r:r.getTime()}}function xa(e,t){let{name:n,email:r,ip:i,ua:a,signature:o,fieldValues:s,declineReason:c,copyTokenHash:l,participant:u,...d}=t;return{...d,name:``,email:``,tokenHash:`purged:${e}`,...o?{signature:{kind:o.kind,sha256:o.sha256}}:{}}}function Sa(e,t){let{piiSalt:n,returnUrl:r,signerEmail:i,...a}=e;return{...a,signer:{name:``,email:``,as:e.signer.as},fieldValues:{},personalPurgedAt:t}}async function Ca(e,t,n){let r=new Set(t.filter(e=>e.data.status===`draft`).map(e=>e.id)),i=await e.audit_events.query({where:{envelopeId:{in:t.map(e=>e.id)}},limit:100,...n?{cursor:n}:{}}),a=i.items.filter(e=>!r.has(e.data.envelopeId)&&e.data.personal!==null),o=i.items.filter(e=>r.has(e.data.envelopeId)).map(e=>e.id);return a.length>0&&await e.audit_events.putMany(a.map(e=>({id:e.id,data:Wn(e.data)}))),o.length>0&&await e.audit_events.deleteMany(o),i.hasMore?i.cursor:void 0}async function wa(e,t,n){let r=A(n),i=t.filter(e=>e.data.status!==`draft`),a=i.flatMap(e=>e.data.signerIds),o=a.length>0?await e.signers.getMany(a):new Map,s=a.flatMap(e=>{let t=o.get(e);return t?[{id:e,data:xa(e,t)}]:[]});s.length>0&&await e.signers.putMany(s),i.length>0&&await e.envelopes.putMany(i.map(e=>({id:e.id,data:Sa(e.data,r)})));let c=t.filter(e=>e.data.status===`draft`).map(e=>e.id);c.length>0&&await e.envelopes.deleteMany(c)}async function Ta(e,t){let n=B(e),r={...await e.kv.get(ga)},i=!1;if(!r.phase||r.phase===`rl`)(await Jt(e.kv,t,3)).more?r.phase=`rl`:Object.assign(r,ba(await e.settings.list(`retention`),t),{phase:`personal`});else if(r.phase===`outbox`){let e=await n.outbox.query({where:{status:{in:[`sent`,`failed`]},nextAttemptAt:{lt:r.p}},limit:100});e.items.length>0&&await n.outbox.deleteMany(e.items.map(e=>e.id)),i=!e.hasMore}else{let e=r.phase===`personal`,i=e?r.p:r.r,a=await n.envelopes.query({where:{createdAt:{gte:(e?r.pf:r.rf)??``,lt:A(i)}},limit:10,...r.cursor?{cursor:r.cursor}:{}}),o=t=>e?t.personalPurgedAt:t.recordsPurgedAt,s=a.items.filter(({data:e})=>!o(e)&&(va(e)??i)<i),c=s.length===0;if(!r.step&&s.length>0){if(e)r.acursor=await Ca(n,s,r.acursor);else{let e=await n.audit_events.query({where:{envelopeId:{in:s.map(e=>e.id)}},limit:100});if(e.items.length>0&&await n.audit_events.deleteMany(e.items.map(e=>e.id)),e.hasMore)r.acursor=`more`;else{delete r.acursor;let e=s.flatMap(e=>e.data.pdf?.ids??[]),t=s.flatMap(e=>e.data.snapshot?.ids??[]);e.length>0&&await n.artifacts.deleteMany(e),t.length>0&&await n.snapshots.deleteMany(t)}}r.acursor||(r.step=1)}else if(s.length>0){if(e)await wa(n,s,t);else{let e=s.flatMap(e=>e.data.signerIds);e.length>0&&await n.signers.deleteMany(e);let r=A(t);await n.envelopes.putMany(s.map(({id:e,data:t})=>({id:e,data:{...t,title:``,signerIds:[],snapshot:null,pdf:null,pdfSha256:null,recordsPurgedAt:r}})))}c=!0}if(c){delete r.step;for(let{data:e}of a.items)!o(e)&&!s.some(t=>t.data===e)&&(!r.keep||e.createdAt<r.keep)&&(r.keep=e.createdAt);a.hasMore&&a.cursor?r.cursor=a.cursor:(r[e?`pf`:`rf`]=r.keep??A(i),delete r.cursor,delete r.keep,r.phase=e?`records`:`outbox`)}}return i&&delete r.phase,await e.kv.set(ga,r),i||await e.cron?.schedule(ha,{schedule:A(t)}),i}async function Ea(e,t,n=Date.now()){return e.name!==ma&&e.name!==ha?!1:(await Ta(t,n),!0)}const Da=e=>_a(e)||e.status===`completed`&&!e.pdfSha256;async function Oa(e,t){let n=B(e),r;if(t.includes(`@`)){let e=t.toLowerCase(),[i,a]=await Promise.all([n.signers.query({where:{email:e},limit:10}),n.envelopes.query({where:{signerEmail:e},limit:10})]),o=new Map(a.items.map(e=>[e.id,e.data])),s=[...new Set(i.items.map(e=>e.data.envelopeId))].filter(e=>!o.has(e));if(s.length>0)for(let[e,t]of await n.envelopes.getMany(s))o.set(e,t);r=[...o].slice(0,10).map(([e,t])=>({id:e,data:t}))}else{let e=await n.envelopes.get(t);r=e?[{id:t,data:e}]:[]}return{due:r.filter(e=>!Da(e.data)&&!e.data.personalPurgedAt),open:r.filter(e=>Da(e.data)).length}}async function ka(e,t,n){let r=B(e),i=await Ca(r,t.due);if(i&&=await Ca(r,t.due,i),i)throw Error(`audit trail too long for one request`);await wa(r,t.due,n),await r.outbox.deleteMany(t.due.flatMap(e=>[`complete-${e.id}`,...e.data.signerIds.map(e=>`invite-${e}`)]))}const Aa=new Set([`localhost`,`127.0.0.1`,`[::1]`]);function ja(e=b){return x(e(32))}const Ma=e=>W(e)===null;function Na(e){let t=[];for(let n of e.split(/\r?\n/)){let e=n.trim();if(e===``)continue;let r;try{r=new URL(e)}catch{return{ok:!1,entry:e}}if(!(r.protocol===`https:`||r.protocol===`http:`&&Aa.has(r.hostname))||r.username||r.password||e.includes(`#`)||e.includes(`?`))return{ok:!1,entry:e};t.push(r.href)}return t.length>10?{ok:!1,entry:`too many entries`}:{ok:!0,entries:t}}async function Pa(e,t,n){let r=W(t.masterKey);if(!r)return{ok:!1,code:`MASTER_KEY_MISSING`};let i=t.name.trim();if(i===``||i.length>100)return{ok:!1,code:`NAME_REQUIRED`};let a=mt(n.random),o={name:i,clientId:a,createdAt:n.now,lastUsedAt:null,revokedAt:null,returnUrlAllowlist:t.returnUrlAllowlist};return await e.put(a,o),{ok:!0,client:o,pairing:ft(a,await pt(r,a))}}async function Fa(e,t,n){return(await e.updateIf(t,{where:{revokedAt:null},set:{revokedAt:n}})).applied}async function Ia(e){return(await e.query({orderBy:{createdAt:`desc`},limit:100})).items.map(e=>e.data)}function La(e){let t=(e??``).split(`,`).filter(e=>e.trim()!==``).length;return t===0?{state:`missing`,canSaveSecrets:!1,keyCount:0,banner:{tone:`error`,message:`EMDASH_ENCRYPTION_KEY is not set, so secret settings (the integration master key and the Turnstile secret) cannot be saved. Set it in the site environment and restart.`}}:{state:`ready`,canSaveSecrets:!0,keyCount:t,banner:null}}function Ra(e){let t=`PLUGIN_SETTING_ENCRYPTION_KEY_MISSING`,n=e=>e.includes(t)||e.includes(`PluginSettingEncryptionError`);return typeof e==`string`?n(e):e instanceof Error?n(e.message)||e.name===`PluginSettingEncryptionError`:typeof e==`object`&&e?e.code===t:!1}const za=e=>e.storage.templates,G=e=>({...D(`BAD_REQUEST`).body,...e?{issues:e}:{}}),Ba=()=>D(`TEMPLATE_NOT_FOUND`).body;function Va(e){let t=V(e).id;return typeof t==`string`&&t.length>0&&t.length<=200&&!t.includes(`:`)?t:null}const Ha=(e,t)=>({id:e,...t}),Ua=(e,{body:t,...n})=>({id:e,...n});async function Wa(e,t){let n=await za(e).get(t);return n&&n.status!==`version`?n:null}const Ga={"templates/create":{handler:(async(e,t)=>{let n=crypto.randomUUID(),r=er(e.input,{id:n,now:A()});if(!r.ok)return G(r.error);let{head:i,versions:a}=r.value;return await za(t).putMany([{id:n,data:i},...a]),{ok:!0,template:Ha(n,i)}})},"templates/update":{handler:(async(e,t)=>{let n=Va(e.input);if(!n)return G();let r=await Wa(t,n);if(!r)return Ba();let i=tr(r,e.input,{id:n,now:A()});return i.ok?(await za(t).putMany([{id:n,data:i.value.head},i.value.version]),{ok:!0,template:Ha(n,i.value.head)}):G(i.error)})},"templates/get":{handler:(async(e,t)=>{let n=Va(e.input);if(!n)return G();let r=V(e.input).version;if(r!==void 0&&!(Number.isSafeInteger(r)&&r>=1))return G();let i=r,a=await za(t).getMany(i===void 0?[n]:[n,L(n,i)]),o=a.get(n);if(!o||o.status===`version`)return Ba();let s=i===void 0?o:a.get(L(n,i));if(!s)return Ba();let c=Array.from({length:o.version},(e,t)=>t+1);return{ok:!0,template:Ha(n,{...s,status:o.status}),versions:c}})},"templates/list":{handler:(async(e,t)=>{let n=V(e.input).status??`active`;if(n!==`active`&&n!==`archived`)return G();let{items:r}=await za(t).query({where:{status:n},limit:200});return{ok:!0,templates:r.map(e=>Ua(e.id,e.data)).sort((e,t)=>e.name<t.name?-1:e.name>t.name?1:0)}})},"templates/archive":{handler:(async(e,t)=>{let n=Va(e.input);if(!n)return G();let r=await Wa(t,n);if(!r)return Ba();if(r.status===`archived`)return{ok:!0,template:Ha(n,r)};let i=nr(r,A());return await za(t).putMany([{id:n,data:i}]),{ok:!0,template:Ha(n,i)}})}},Ka=(e,t)=>({severity:`error`,title:e,...t?{message:t}:{}}),qa=e=>B(e.ctx).clients;async function Ja(e){return(await e.ctx.settings.list()).find(e=>e.key===`integrationMasterKey`)?.value}const Ya=e=>typeof e==`string`&&e.trim()!==``;function Xa(e,r,o=[]){let s=W(e)!==null,c=typeof e==`object`&&!!e,l=La(null).banner;return q([t(`Integrations`),...u([c&&l&&{severity:`error`,title:`Encryption key missing`,message:l.message},!s&&!c&&{severity:`warning`,title:Ya(e)?`Integration master key is too short`:`Integration master key not set`,message:`Clients are paired with secrets derived from the master key. Generate one here, or save one of at least 32 characters in Settings.`}]),...o,...s||c||Ya(e)?[]:[d([f(`integrations.generate-key`,`Generate master key`,{style:`primary`})])],t(`Clients`),a({columns:[i(`name`,`Name`),i(`clientId`,`Client id`),i(`created`,`Created`,`relative_time`),i(`status`,`Status`,`badge`),i(`revoke`,``,`element`)],rows:r.map(e=>({name:e.name,clientId:e.clientId,created:e.createdAt,status:e.revokedAt?`Revoked`:`Active`,...e.revokedAt?{}:{revoke:f(`client.revoke`,`Revoke`,{style:`danger`,value:e.clientId,confirm:{title:`Revoke this client?`,text:`Its intents and receipts are refused from now on. This cannot be undone; create a new client to pair again.`,confirm:`Revoke client`,deny:`Keep`,style:`danger`}})}})),pageActionId:`clients.page`,emptyText:`No clients yet.`}),n(`Events on this site: with the Events suite installed, an administrator pairs it in one click at /_events/pair (the client appears here as "Events on this site"; no string to copy).`),t(`Add a client`),n(`The pairing string is shown once, right after you create the client, and cannot be shown again. Paste it into the other plugin's settings. Return URLs: one per line, https (http only for localhost); leave blank to allow this site only.`),y({fields:[m(`name`,`Name`,{initialValue:``}),m(`returnUrlAllowlist`,`Allowed return URLs`,{multiline:!0,initialValue:``})],submit:{label:`Create client`,actionId:`client.create`}})])}async function K(e,t,n=[]){return Xa(t,await Ia(qa(e)),n)}async function Za(e){let[t,n]=await Promise.all([Ja(e),Ia(qa(e))]);return Xa(t,n)}async function Qa(e){let t=await Ja(e);if(Ya(t))return K(e,t,u([Ka(`Key already set`,`Changing it would re-pair every client.`)]));let n=ja();try{await e.ctx.settings.set(`integrationMasterKey`,n)}catch(n){if(!Ra(n))throw n;return K(e,t,u([Ka(`Encryption key missing`,La(null).banner?.message)]))}return K(e,n,u([{severity:`info`,title:`Master key generated`}]))}async function $a(e,t){let n=await Ja(e),r=(e,t)=>typeof e==`string`?e.slice(0,t):``,i=Na(r(t.returnUrlAllowlist,2e3));if(!i.ok)return K(e,n,u([Ka(`Not created`,`Return URL not allowed: ${i.entry.slice(0,200)}`)]));let a=await Pa(qa(e),{name:r(t.name,200),returnUrlAllowlist:i.entries,masterKey:n},{now:A(e.now)});return a.ok?K(e,n,[...u([{severity:`warning`,title:`Copy the pairing string now`,message:`It is shown only this once and cannot be recovered. Treat it like a password.`}]),o({code:a.pairing})]):K(e,n,u([Ka(`Not created`,a.code===`MASTER_KEY_MISSING`?`Set the integration master key first (at least 32 characters), or generate one.`:`Give the client a name of up to 100 characters.`)]))}async function eo(e,t){let n=await Fa(qa(e),t,A(e.now));return K(e,await Ja(e),u([n?{severity:`info`,title:`Client revoked`}:Ka(`Not revoked`,`Unknown or already revoked.`)]))}const q=e=>({blocks:e}),J=(e,t=200)=>typeof e==`string`?e.trim().slice(0,t):``,Y=(e,t,n)=>t.handler({input:n,user:e.user??null},e.ctx),to=e=>Yi[e],no=e=>Ga[e],ro={INVALID_NAME:`Give the template a name of up to 200 characters.`,INVALID_BODY:`The template text is required (up to 100,000 characters).`,INVALID_DESCRIPTION:`The description is too long (up to 1,000 characters).`,TEMPLATE_ARCHIVED:`This template is archived.`,INVALID_INTEGRATIONS:`Choose whether integrations may use the template.`,INVALID_TITLE:`The title is too long or has control characters.`,INVALID_SIGNER_NAME:`Enter the signer's name.`,INVALID_SIGNER_EMAIL:`Enter a valid email address for the signer.`,INVALID_FIELDS:`A field value is too long or not text.`,MISSING_FIELD:`A template field has no value.`,DOCUMENT_TOO_LARGE:`The document is too long to sign (up to 131,072 characters and 1,500 lines).`};function X(e,t=`The change was refused.`){let n=Array.isArray(e.issues)?e.issues:[];return n.length>0?n.map(e=>ro[e.code??``]??`${e.path??`input`} (${e.code??`invalid`})`).join(` `):e.error?.message??t}const io=(e,t,n)=>({severity:e,title:t,...n?{message:n}:{}}),Z=(e,t)=>io(`error`,e,t),ao=(e,t)=>io(`warning`,e,t),oo=(e,t)=>f(e,t,{style:`secondary`}),Q=(e,t)=>io(`info`,e,t),so=()=>oo(`envelopes.back`,`Back to envelopes`),co=()=>oo(`templates.back`,`Back to templates`),lo=e=>f(`envelope.open`,`Open envelope`,{value:e}),uo={"envelope.created":`Envelope created`,"envelope.sent":`Envelope sent`,"signer.viewed":`Signer opened the document`,"signer.consented":`Signer gave consent`,"signer.signed":`Signer signed`,"signer.declined":`Signer declined`,"envelope.completed":`Envelope completed`,"envelope.declined":`Envelope declined`,"envelope.voided":`Envelope voided`,"envelope.expired":`Envelope expired`},fo=e=>!Cn(e.ctx)&&ao(`Set the site URL`,Tn);async function po(e){let t=await kn(e.ctx);return[fo(e),t.state===`no_transport`&&ao(`No email transport`,`No email provider is configured, so signing invitations stay queued and are not delivered. Install an email provider plugin.`),t.failed>0&&ao(`${t.failed} email${t.failed===1?``:`s`} could not be delivered`,`Open the envelope and use Resend invitation if a signer never received theirs.`)]}async function mo(e,r,o=[],s){let c=Yn(r)?r:``,[l,d]=await Promise.all([Y(e,to(`envelopes/list`),{...c?{status:c}:{},...s?{cursor:s}:{}}),po(e)]),p=typeof l.nextCursor==`string`?l.nextCursor:void 0,h=(l.envelopes??[]).map(e=>{let t=e.signer;return{title:e.title,signer:t?`${t.name??``} <${t.email??``}>`:``,status:e.status,created:e.createdAt,open:f(`envelope.open`,`Open`,{value:e.id})}});return q([t(`Envelopes`),...u(d),...o,y({fields:[g(`status`,`Status`,[{label:`Any status`,value:``},...Kn.map(e=>({label:e.replaceAll(`_`,` `),value:e}))],{initialValue:c})],submit:{label:`Filter`,actionId:`envelopes.filter`}}),n(`Newest first, 100 a page. Create an envelope from a template on the Templates page.`),a({columns:[i(`title`,`Title`),i(`signer`,`Signer`),i(`status`,`Status`,`badge`),i(`created`,`Created`,`relative_time`),i(`open`,``,`element`)],rows:h,pageActionId:`envelopes.page:${c}`,...p?{nextCursor:p}:{},emptyText:`No envelopes match.`}),t(ho),y({fields:[m(`subject`,`Signer email or envelope id`)],submit:{label:`Find`,actionId:`retention.preview`}})])}const ho=`Delete personal data`;async function go(e,n,r){let i=await Oa(e.ctx,n),a=i.due.length;return r&&a>0&&await ka(e.ctx,i,e.now),q([t(ho),...u([{severity:r?`info`:`warning`,title:r&&a>0?`Personal data deleted`:a+i.open>0?`${a} envelope(s) to delete, ${i.open} kept for now`:`No envelopes found`,message:`Signed records stay for their own period; open envelopes and pending PDFs are skipped.`}]),d([...!r&&a>0?[f(`retention.erase`,ho,{style:`danger`,value:n,confirm:{title:`${ho}?`,text:`This cannot be undone.`,confirm:`Delete`,deny:`Keep`,style:`danger`}})]:[],so()])])}async function _o(e,t){if(!t)return`missing`;let n=await B(e.ctx).outbox.get(`invite-${t}`);return n?n.status===`failed`?`failed`:`queued`:`missing`}async function vo(e,o,s={}){let{envelopes:c,signers:l,audit_events:m}=B(e.ctx),h=s.envelope??await c.get(o);if(!h)return q([t(`Envelope`),...u([Z(`Envelope not found`,`It may have been removed.`)]),d([so()])]);let g=h.status===`sent`||h.status===`in_progress`,[_,v,y]=await Promise.all([m.query({where:{envelopeId:o},orderBy:{seq:`asc`},limit:200}),s.signers?Promise.resolve(s.signers):h.signerIds.length>0?l.getMany(h.signerIds).then(e=>[...e].map(([e,t])=>({id:e,name:t.name,email:t.email,status:t.status}))):Promise.resolve([]),s.invite??(h.status===`sent`?_o(e,h.signerIds[0]):Promise.resolve(`n/a`))]),b=v[0],x=h.status===`sent`&&(y===`missing`||y===`failed`),S=null;if(h.status===`completed`&&!h.recordsPurgedAt)if(h.pdfSha256){let t=await Ai(e.ctx,o,e.now);S=d([p(`Download signed PDF`,{kind:`external`,url:`${e.origin}${t.url}`},{appearance:`primary`})])}else S=n(`The signed PDF is still being prepared. Reload in a minute.`);let C=[h.status===`draft`&&f(`envelope.send`,`Send for signature`,{style:`primary`,value:o}),x&&f(`envelope.resend`,`Resend invitation`,{style:`primary`,value:o}),(h.status===`draft`||g)&&f(`envelope.void`,`Void`,{style:`danger`,value:o,confirm:{title:`Void this envelope?`,text:`The signer will no longer be able to sign it. This cannot be undone.`,confirm:`Void envelope`,deny:`Keep`,style:`danger`}}),so()].filter(e=>e!==!1);return q([t(h.title),...u([x&&{severity:`warning`,title:`The invitation was not delivered`,message:y===`failed`?`The email gave up after repeated failures. Resend invitation queues a fresh email with a new signing link.`:`The invitation was never queued. Resend invitation queues it with a new signing link.`},x&&fo(e)]),...s.extra??[],...h.personalPurgedAt?[n(`Personal data deleted ${h.personalPurgedAt}${h.recordsPurgedAt?`; signed records deleted`:``} (retention).`)]:[],r([{label:`Status`,value:h.status.replaceAll(`_`,` `)},{label:`Template`,value:`${h.templateId} v${h.templateVersion}`},{label:`Signer`,value:b?`${b.name} <${b.email}>`:h.signer.email},{label:`Signer status`,value:b?.status??`not sent yet`},{label:`Delivery`,value:h.delivery},{label:`Created`,value:h.createdAt},{label:`Sent`,value:h.sentAt??`Not sent`},{label:`Expires`,value:h.expiresAt??`Not set`},{label:`Completed`,value:h.completedAt??`Not completed`},{label:`Document SHA-256`,value:h.docSha256??`Set when sent`},{label:`Final hash`,value:h.finalHash??`Set when completed`}]),...S?[S]:[],d(C),t(`Audit timeline`),a({columns:[i(`seq`,`#`,`number`),i(`event`,`Event`),i(`at`,`When`,`text`),i(`actor`,`By`)],rows:_.items.map(({data:e})=>({seq:e.seq,event:uo[e.type]??e.type,at:e.at,actor:e.actor})),pageActionId:`audit.page:${o}`,emptyText:`No events yet.`})])}async function yo(e,n){let r;try{r=await Y(e,to(`envelopes/send`),{id:n})}catch{return q([t(`Envelope`),...u([Z(`The envelope was sent but the invitation could not be queued`,`Open the envelope and use Resend invitation.`)]),d([lo(n)])])}if(r.ok!==!0)return q([t(`Envelope`),...u([Z(`Not sent`,X(r))]),d([lo(n),so()])]);let i=r.invitation===`SITE_URL_MISSING`;return q([t(`Envelope`),...u([i?{severity:`warning`,title:`Envelope sent, but no invitation was queued`,message:Tn}:Q(`Envelope sent`,`The signer's invitation is queued.`)]),d([lo(n),so()])])}async function bo(e,t){let n=await Y(e,to(`envelopes/void`),{id:t});if(n.ok!==!0){let r=n.error?.code===`ENVELOPE_CLOSED`;return vo(e,t,{extra:u([Z(r?`This envelope cannot be voided`:`Not voided`,r?`It is already completed, declined, voided or expired.`:X(n))])})}return vo(e,t,{envelope:n.envelope,invite:`n/a`,extra:u([Q(`Voided`,`The signer can no longer sign this envelope.`)])})}async function xo(e,t){let n=await Y(e,to(`envelopes/resend`),{id:t});return n.ok===!0?vo(e,t,{envelope:n.envelope,invite:`queued`,signers:n.signers,extra:u([Q(`Invitation queued`,`A new email with a new signing link is on its way.`)])}):vo(e,t,{extra:u([n.error?.code===`INVITATION_QUEUED`?Q(`Already queued`,`The invitation is queued or was sent.`):Z(`Not resent`,X(n,`Only an envelope that is sent and unsigned can be resent.`))])})}const So=/^(signer|participant)\./;async function Co(e,r,i=[]){let a=await Y(e,no(`templates/get`),{id:r}),o=a.template;return a.ok!==!0||!o?q([t(`New envelope`),...u([Z(`Template not found`)]),...i]):q([t(`New envelope: ${o.name}`),...i,n(`Creates a draft you can check before sending it for signature. Signer fields: one per line as key: Label, ending in * when required.`),y({fields:[m(`title`,`Title`,{initialValue:o.name}),m(`signerName`,`Signer name`),m(`signerEmail`,`Signer email`),...o.fields.filter(e=>!So.test(e)).map(e=>m(`field:${e}`,e)),m(`signerFields`,`Fields the signer fills in (optional)`,{multiline:!0,placeholder:`phone: Phone number *`})],submit:{label:`Create draft`,actionId:`envelope.create`},blockId:`envelope-new:${r}`}),d([co()])])}function wo(e){return typeof e==`string`?e.slice(0,4e3).split(`
|
|
38
|
+
`).map(e=>e.trim()).filter(e=>e!==``).map(e=>{let t=e.indexOf(`:`),n=(t===-1?e:e.slice(0,t)).trim(),r=t===-1?``:e.slice(t+1).trim(),i=r.endsWith(`*`);return i&&(r=r.slice(0,-1).trim()),{key:n,label:r,...i?{required:!0}:{}}}):[]}async function To(e,t,n){let r=t?.startsWith(`envelope-new:`)?t.slice(13):``;if(!r)return q(u([Z(`Choose a template first`)]));let i={};for(let[e,t]of Object.entries(n))e.startsWith(`field:`)&&(i[e.slice(6)]=typeof t==`string`?t:``);let a=J(n.title),o=wo(n.signerFields),s=await Y(e,to(`envelopes/create`),{templateId:r,...a?{title:a}:{},signer:{name:J(n.signerName),email:J(n.signerEmail)},fields:i,...o.length>0?{signerFields:o}:{}});if(s.ok!==!0)return Co(e,r,u([Z(`Not saved`,X(s))]));let c=s.envelope.id;return vo(e,c,{extra:u([Q(`Draft created`,`Check the details, then send it.`)])})}async function Eo(e,r=[]){let o=((await Y(e,no(`templates/list`),{})).templates??[]).map(e=>({name:e.name,id:e.id,version:e.version,fields:(e.fields??[]).join(`, `),integrations:e.integrations===!0?`Yes`:`No`,updated:e.updatedAt,edit:f(`template.edit`,`Edit`,{value:e.id}),use:f(`envelope.new`,`New envelope`,{style:`primary`,value:e.id})}));return q([t(`Templates`),...r,a({columns:[i(`name`,`Name`),i(`id`,`ID`),i(`version`,`Version`,`number`),i(`fields`,`Fields`),i(`integrations`,`Integrations`),i(`updated`,`Updated`,`relative_time`),i(`edit`,``,`element`),i(`use`,``,`element`)],rows:o,pageActionId:`templates.page`,emptyText:`No templates yet. Add one below.`}),t(`New template`),n(`Write the document in Markdown. Use {{field}} for values filled in per envelope, and {{signer.name}} for the signer.`),y({fields:[m(`name`,`Name`),m(`description`,`Description (optional)`),m(`body`,`Template text`,{multiline:!0}),Do(!1)],submit:{label:`Create template`,actionId:`template.create`}})])}function Do(e){return _(`integrations`,`Available to integrations`,{description:`Paired sites (such as Events) may send this template for signing.`,initialValue:e})}function Oo(e){let t=Object.fromEntries(cn(e).map(e=>[e,`«${e}»`]));try{return ln(e,t)}catch{return e}}function ko(e,r,i=[]){let a=String(r.body??``),s=cn(a);return q([t(`Edit template: ${String(r.name??``)}`),...i,n(`Version ${String(r.version??1)}. Saving writes a new version; sent envelopes keep the text they were sent with.`),n(`Template id:`),o({code:e}),y({fields:[m(`name`,`Name`,{initialValue:String(r.name??``)}),m(`description`,`Description (optional)`,{initialValue:String(r.description??``)}),m(`body`,`Template text`,{initialValue:a,multiline:!0}),Do(r.integrations===!0)],submit:{label:`Save new version`,actionId:`template.save`},blockId:`template:${e}`}),t(`Preview`),n(s.length>0?`Fields: ${s.join(`, `)}. Placeholders show as «name».`:`This template has no fields.`),o({code:Oo(a)}),d([f(`envelope.new`,`New envelope from this template`,{style:`primary`,value:e}),f(`template.archive`,`Archive`,{style:`danger`,value:e,confirm:{title:`Archive this template?`,text:`It can no longer be used for new envelopes. Sent envelopes are not affected.`,confirm:`Archive`,deny:`Keep`,style:`danger`}}),co()])])}async function Ao(e,t,n=[]){let r=await Y(e,no(`templates/get`),{id:t});return r.ok!==!0||!r.template?Eo(e,u([Z(`Template not found`)])):ko(t,r.template,n)}async function jo(e,t){let n=await Y(e,no(`templates/create`),{name:J(t.name),body:typeof t.body==`string`?t.body:``,...J(t.description,1e3)?{description:J(t.description,1e3)}:{},integrations:t.integrations===!0});return n.ok===!0?Eo(e,u([Q(`Template created`)])):Eo(e,u([Z(`Not saved`,X(n))]))}async function Mo(e,t,n){let r=t?.startsWith(`template:`)?t.slice(9):``;if(!r)return q(u([Z(`Choose a template first`)]));let i={name:J(n.name),body:typeof n.body==`string`?n.body:``,description:J(n.description,1e3),integrations:n.integrations===!0},a=await Y(e,no(`templates/update`),{id:r,...i});return a.ok===!0?ko(r,a.template,u([Q(`Saved`)])):ko(r,{...i,version:`?`},u([Z(`Not saved`,X(a))]))}async function No(e,t){let n=await Y(e,no(`templates/archive`),{id:t});return Eo(e,u([n.ok===!0?Q(`Template archived`):Z(`Not archived`,X(n))]))}const Po=[{key:`senderName`,label:`Sender name`,kind:`text`},{key:`expiryDays`,label:`Envelope expiry (days)`,kind:`number`,min:1,max:365},{key:`consentVersion`,label:`Consent version`,kind:`text`},{key:`consentWording`,label:`Consent wording`,kind:`long`},{key:`retentionPersonalDataMonths`,label:`Keep personal data (months)`,kind:`number`,min:1,max:120},{key:`retentionSignedRecordsYears`,label:`Keep signed records (years)`,kind:`number`,min:1,max:50},{key:`turnstileSiteKey`,label:`Turnstile site key`,kind:`text`}],Fo=[{key:`turnstileSecretKey`,label:`Turnstile secret key`},{key:`integrationMasterKey`,label:`Integration master key`}],Io=e=>typeof e==`string`&&e!==``?`readable`:typeof e==`object`&&e?`unreadable`:`unset`;function Lo(e,r,i=[]){let a=Fo.some(e=>r[e.key]===`unreadable`),o=La(null).banner;return q([t(`Settings`),...u([a&&o&&{severity:`error`,title:`Encryption key missing`,message:o.message},r.integrationMasterKey===`unset`&&ao(`Integration master key not set`,`Other plugins cannot create envelopes through the integration protocol until it is saved.`)]),...i,y({fields:[...Po.map(t=>t.kind===`number`?h(t.key,t.label,{min:t.min,max:t.max,...typeof e[t.key]==`number`?{initialValue:e[t.key]}:{}}):m(t.key,t.label,{multiline:t.kind===`long`,initialValue:typeof e[t.key]==`string`?e[t.key]:``})),...Fo.map(e=>v(e.key,`${e.label} (leave blank to keep)`,{hasValue:r[e.key]===`readable`}))],submit:{label:`Save settings`,actionId:`settings.save`}}),n(`Reminder and one-time-code settings (Pro) are in the plugin's own settings panel.`)])}async function Ro(e){let t=await e.ctx.settings.list(),n=Object.fromEntries(t.map(e=>[e.key,e.value]));return{values:n,secrets:Object.fromEntries(Fo.map(e=>[e.key,Io(n[e.key])]))}}async function zo(e){let{values:t,secrets:n}=await Ro(e);return Lo(t,n)}async function Bo(e,t){let{values:n,secrets:r}=await Ro(e),i=[],a=[];for(let e of Po){let r=t[e.key];if(r==null||r===``)continue;let o;if(e.kind===`number`){if(o=Number(r),!Number.isInteger(o)||o<(e.min??0)||o>(e.max??2**53-1)){a.push(`${e.label} must be a whole number from ${e.min} to ${e.max}.`);continue}}else o=J(r,e.kind===`long`?2e3:200);o!==n[e.key]&&i.push([e.key,o])}let o=Fo.filter(e=>J(t[e.key],500)!==``);if(o.some(e=>e.key===`integrationMasterKey`&&Ma(J(t[e.key],500)))&&a.push(`The integration master key must be at least 32 characters, or use Generate on the Integrations page.`),a.length>0)return Lo(n,r,u([Z(`Not saved`,a.join(` `))]));if(i.length+o.length>6)return Lo(n,r,u([Z(`Too many changes at once`,`Save at most 6 settings at a time.`)]));if(i.length+o.length===0)return Lo(n,r,u([Q(`Nothing to save`)]));let s={...n},c={...r};try{for(let n of o)await e.ctx.settings.set(n.key,J(t[n.key],500)),c[n.key]=`readable`;for(let[t,n]of i)await e.ctx.settings.set(t,n),s[t]=n}catch(e){if(!Ra(e))throw e;let t=La(null).banner;return Lo(n,r,u([{severity:`error`,title:`Encryption key missing`,message:t?.message}]))}return Lo(s,c,u([Q(`Saved`)]))}const Vo=e=>J(e,200);async function Ho(e,t){if(t.type===`page_load`)switch(t.page){case`/envelopes`:return mo(e,``);case`/templates`:return Eo(e);case`/settings`:return zo(e);case`/integrations`:return Za(e);default:return q(u([Z(`Page not found`)]))}if(t.type===`form_submit`){let n=t.values;switch(t.action_id){case`envelopes.filter`:return mo(e,J(n.status));case`envelope.create`:return To(e,t.block_id,n);case`template.create`:return jo(e,n);case`template.save`:return Mo(e,t.block_id,n);case`settings.save`:return Bo(e,n);case`client.create`:return $a(e,n);case`retention.preview`:return go(e,J(n.subject),!1)}}else{let n=Vo(t.value);if(t.action_id.startsWith(`envelopes.page:`))return mo(e,t.action_id.slice(15),[],J(t.value,500)||void 0);if(t.action_id.startsWith(`audit.page:`))return vo(e,Vo(t.action_id.slice(11)));switch(t.action_id){case`envelopes.back`:case`envelopes.page`:return mo(e,``);case`envelope.open`:return vo(e,n);case`envelope.send`:return yo(e,n);case`envelope.void`:return bo(e,n);case`envelope.resend`:return xo(e,n);case`retention.erase`:return go(e,n,!0);case`envelope.new`:return Co(e,n);case`integrations.generate-key`:return Qa(e);case`client.revoke`:return eo(e,n);case`clients.page`:return Za(e);case`templates.back`:case`templates.page`:return Eo(e);case`template.edit`:return Ao(e,n);case`template.archive`:return No(e,n)}}return q(u([Z(`Unknown action`)]))}const Uo={admin:{handler:(async(e,t)=>{let n=`http://localhost`;try{n=new URL(e.request?.url??``).origin}catch{}return Ho({ctx:t,origin:n,now:Date.now(),user:e.user??null},e.input)})}},Wo=[`completed`,`declined`,`voided`,`expired`],Go=e=>{if(!e)return;let t=Date.parse(e);return Number.isNaN(t)?void 0:Math.floor(t/1e3)};function Ko(e,t){let{status:n,clientId:r,externalRef:i}=t;if(!Wo.includes(n)||!r||!i||t.docSha256===null)return;let a=n===`completed`,o=a?Go(t.completedAt):Go(t.closedAt)??Go(t.updatedAt);if(o===void 0)return;let s={v:1,typ:`receipt`,cid:r,envelopeId:e,ref:i,status:n,docSha256:t.docSha256,pdfSha256:a?t.pdfSha256??null:null,finalHash:a?t.finalHash:null,at:o};return He(`receipt`,s).ok?s:void 0}async function qo(e,t,n){let r=Ko(e,t);return r?it(`receipt`,r,n):void 0}function Jo(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):void 0}function Yo(e){let t={};return{settings:()=>t,async getClient(n){let[r,i]=await Promise.all([e.settings.list(),B(e).clients.get(n)]);t=Object.fromEntries(r.map(e=>[e.key,e.value]));let a=W(t.integrationMasterKey);if(!(!a||!i))return{secret:await pt(a,n),revoked:i.revokedAt!==void 0&&i.revokedAt!==null,returnUrlAllowlist:Jo(i.returnUrlAllowlist)}}}}async function Xo(e,t,n){let r=W(n);if(!(!r||!t.clientId))return qo(e,t,await pt(r,t.clientId))}async function Zo(e,t,n=Date.now()){let r=await rt({token:V(e).request,now:n,getClient:Yo(t).getClient});if(!r.ok)return U(r.error);let i=[],a;for(let e=0;e<3;e++){let e=await B(t).templates.query({where:{status:`active`},limit:200,...a===void 0?{}:{cursor:a}});if(i.push(...e.items),!e.hasMore||!e.cursor)break;a=e.cursor}return{ok:!0,templates:i.filter(e=>rr(e.data)).map(e=>({id:e.id,name:e.data.name,version:e.data.version})).sort((e,t)=>e.name<t.name?-1:e.name>t.name?1:e.id<t.id?-1:1)}}const Qo=(e,t)=>Zo(e.input,t),$o=/^[0-9a-f]{64}$/,es=/[\u0000-\u001F\u007F]/,ts=e=>Array.isArray(e)&&e.length===2&&e.every(e=>typeof e==`number`&&Number.isFinite(e)&&e>=0&&e<=1);function ns(e){let t=e=>T({path:`signature.strokes`,code:e});return!Array.isArray(e)||e.length===0||e.length>64?t(`INVALID_SIGNATURE`):JSON.stringify(e).length>32768?t(`STROKES_TOO_LARGE`):e.every(e=>Array.isArray(e)&&e.length>0&&e.every(ts))?w(e):t(`INVALID_SIGNATURE`)}function rs(e){let t=T({path:`signature`,code:`INVALID_SIGNATURE`});if(!lr(e)||e.kind!==`typed`&&e.kind!==`drawn`)return t;let n=e.typedName===void 0?void 0:dr(e.typedName);if(n===null)return t;if(e.kind===`typed`)return n===void 0?t:w({kind:`typed`,typedName:n});let r=ns(e.strokes);return r.ok?w({kind:`drawn`,...n===void 0?{}:{typedName:n},strokes:r.value}):r}function is(e){if(!lr(e))return T([{path:``,code:`INVALID_INPUT`}]);let t=[];e.consent!==!0&&t.push({path:`consent`,code:`CONSENT_REQUIRED`}),e.intent!==!0&&t.push({path:`intent`,code:`INTENT_REQUIRED`});let n=typeof e.docSha256==`string`&&$o.test(e.docSha256)?e.docSha256:null;n===null&&t.push({path:`docSha256`,code:`INVALID_DOC_HASH`});let r=typeof e.consentSha256==`string`&&$o.test(e.consentSha256)?e.consentSha256:null;r===null&&t.push({path:`consentSha256`,code:`INVALID_CONSENT_HASH`});let i=rs(e.signature);i.ok||t.push(i.error);let a=pr(e.fieldValues);return a===null&&t.push({path:`fieldValues`,code:`INVALID_FIELDS`}),t.length>0||n===null||r===null||!i.ok||a===null?T(t):w({docSha256:n,consentSha256:r,signature:i.value,fieldValues:a})}function as(e){if(e===void 0)return;let t=typeof e==`string`?e.trim():``;return t.length===0||[...t].length>500||es.test(t)?null:t}async function os(e,t,n){let r=Object.keys(n.fieldValues).sort().map(e=>[e,n.fieldValues[e]]),i=await F(n.salt+JSON.stringify([e,t.kind,t.typedName??null,t.strokes??null,r]));return{...t,sha256:i}}const ss=e=>({...e.ip===void 0?{}:{ip:e.ip},...e.ua===void 0?{}:{ua:e.ua}}),cs=e=>e===void 0?{}:{signer:e};function ls(e,t,n,r){return{type:`signer.viewed`,at:e,actor:`signer`,data:{docSha256:t,...cs(r)},personal:ss(n)}}function us(e){let{at:t,docSha256:n,signature:r}=e;return[{type:`signer.consented`,at:t,actor:`signer`,data:{docSha256:n,consentVersion:e.consentVersion,consentSha256:e.consentSha256,intent:!0},personal:ss(e.who)},{type:`signer.signed`,at:t,actor:`signer`,data:{docSha256:n,kind:r.kind,signatureSha256:r.sha256},personal:{name:r.typedName??e.signerName,...ss(e.who)}},{type:`envelope.completed`,at:t,actor:`system`,data:{docSha256:n}}]}function ds(e){let{at:t,docSha256:n,hasReason:r}=e;return[{type:`signer.declined`,at:t,actor:`signer`,data:{docSha256:n,hasReason:r,...cs(e.order)},personal:ss(e.who)},{type:`envelope.declined`,at:t,actor:`system`,data:{docSha256:n}}]}const fs=[`sent`,`in_progress`];function ps(e){let t=V(e).token;return typeof t==`string`&&t.length>0&&t.length<=200?t:null}const ms=e=>({...e.requestMeta?.ip?{ip:e.requestMeta.ip}:{},...e.requestMeta?.userAgent?{ua:e.requestMeta.userAgent}:{}});function hs(e){try{return e!==void 0&&new URL(e.url).searchParams.has(`token`)}catch{return!1}}function gs(e,t){let n=new Map,r,i={get:t=>{let r=n.get(t);return r||(r=e.kv.get(t),n.set(t,r)),r},set:async(e,t)=>{r={key:e,value:t}}},a=Date.now(),o=()=>qt(i,t.requestMeta?.ip??`unknown`,a,{scope:`ceremony`,limit:20,windowSeconds:600,salt:`esign-ceremony/1`});return{async blocked(){return!(await o()).ok},async fail(){let t=await o();return t.ok&&r&&await e.kv.set(r.key,r.value),U(t.ok?`SIGNING_TOKEN_INVALID`:`RATE_LIMITED`)}}}async function _s(e,t){let{items:n}=await B(e).signers.query({where:{tokenHash:await oe(t)},limit:1}),r=n[0];return r&&await ce(t,r.data.tokenHash)?r:null}async function vs(e,t){let{items:n}=await B(e).signers.query({where:{copyTokenHash:await oe(t)},limit:1}),r=n[0];return r?.data.copyTokenHash&&await ce(t,r.data.copyTokenHash)?r:null}const ys=e=>!!(e.returnUrl&&e.clientId),bs=(e,t)=>ys(t)?e.settings.get(`integrationMasterKey`):Promise.resolve(void 0);async function xs(e,t,n){if(!t.returnUrl)return{};let r=await Xo(e,t,n);return{returnUrl:t.returnUrl,...r?{receipt:r}:{}}}const Ss=(e,t)=>e.find(e=>e.key===t)?.value;async function Cs(e,t){let n=await(t?e.settings.list():e.settings.list(`consent`)),r=(e,t)=>{let r=Ss(n,e);return typeof r==`string`&&r.length>0?r:t},i=r(`consentWording`,`I agree to use electronic records and an electronic signature for this document.`);return{version:r(`consentVersion`,`1`),wording:i,sha256:await F(i),masterKey:Ss(n,`integrationMasterKey`)}}const ws=(e,t)=>e.expiresAt!==null&&e.expiresAt<=t;async function Ts(e,t,n,r){let i=await I(B(e).envelopes,t,n.status,`expired`,{closedAt:r,updatedAt:r});return i.ok&&await Hi(e,t,i.value,{type:`envelope.expired`,at:r,actor:`system`}),U(`SIGNING_TOKEN_EXPIRED`)}const Es=(e,t)=>e.signerIds.length>1?t.order:void 0;async function Ds(e,t,n,r,i){let a=B(e).audit_events,o=i;for(let e=0;e<2;e++){if(o??=await Rn(t,await Bn(a,t),r,n),await Vn(a,o))return o;o=void 0}throw Error(`audit chain contention`)}async function Os(e,t){if(hs(e.request))return U(`TOKEN_IN_QUERY`);let n=gs(t,e),r=ps(e.input);if(r===null)return n.fail();if(await n.blocked())return U(`RATE_LIMITED`);let i=V(e.input).open===!0,{envelopes:a,snapshots:o}=B(t),s=await _s(t,r),c=s?null:await vs(t,r),l=s??c;if(!l)return n.fail();let u=await a.get(l.data.envelopeId);if(!u)return U(`ENVELOPE_NOT_FOUND`);if(c&&u.status!==`completed`)return n.fail();if(!fs.includes(u.status)||l.data.status!==`pending`){let e={ok:!0,state:`closed`,status:u.status,title:u.title,...c?{}:await xs(l.data.envelopeId,u,await bs(t,u))};return u.status!==`completed`||l.data.status!==`signed`?e:u.pdfSha256?{...e,pdf:`ready`,download:await Ai(t,l.data.envelopeId,Date.now())}:{...e,pdf:`pending`}}let d=A();if(ws(u,d))return Ts(t,l.data.envelopeId,u,d);let f=u.document,[p,m]=await Promise.all([u.snapshot?o.getMany(u.snapshot.ids):Promise.resolve(new Map),Cs(t,!1)]),h=f&&!u.snapshot?``:Or([...p.values()]);if(h===null)return U(`INTERNAL`);let g=u.status,_=Es(u,l.data);if(i){let n=!1;if(u.status===`sent`&&(n=(await I(a,l.data.envelopeId,`sent`,`in_progress`,{updatedAt:d})).ok,n&&(g=`in_progress`)),_!==void 0&&(n=(await B(t).signers.updateIf(l.id,{where:{viewedAt:null},set:{viewedAt:d}})).applied),n){let n=ls(d,u.docSha256??``,ms(e),_);if(!(await zn(B(t).audit_events,l.data.envelopeId,n,{salt:u.piiSalt})).ok)throw Error(`audit chain contention`)}}let{participant:v}=l.data;return{ok:!0,state:`ready`,envelope:{id:l.data.envelopeId,title:u.title,status:g,docSha256:u.docSha256,expiresAt:u.expiresAt},signer:{name:l.data.name,as:l.data.as,...v?{participant:v.name}:{}},snapshot:h,...f?{document:{kind:f.kind,name:f.name,bytes:f.bytes,pages:f.pages}}:{},...u.otp?{otp:l.data.otpVerifiedAt?`verified`:`required`}:{},...u.signerFields?.length?{fields:u.signerFields}:{},consent:{version:m.version,wording:m.wording,sha256:m.sha256}}}async function ks(e,t,n){if(hs(e.request))return U(`TOKEN_IN_QUERY`);let r=gs(t,e),i=ps(e.input);if(i===null)return r.fail();let a=is(e.input);if(!a.ok)return H(a.error);let{envelopes:o,signers:s,audit_events:c}=B(t),l=await _s(t,i);if(!l||l.data.status!==`pending`)return r.fail();let u=l.data.envelopeId,d=await o.get(u);if(!d)return U(`ENVELOPE_NOT_FOUND`);if(d.status===`sent`)return U(`SESSION_REQUIRED`);if(d.status!==`in_progress`||d.document&&!n)return U(`ENVELOPE_CLOSED`);let f=A();if(ws(d,f))return Ts(t,u,d,f);if(d.otp&&!l.data.otpVerifiedAt)return U(`OTP_REQUIRED`);if(d.docSha256===null||a.value.docSha256!==d.docSha256)return H([{path:`docSha256`,code:`DOC_CHANGED`}]);let p=await Cs(t,ys(d));if(a.value.consentSha256!==p.sha256)return H([{path:`consentSha256`,code:`CONSENT_CHANGED`}]);let m=d.signerFields??[],h=a.value.fieldValues,g=[...Object.keys(h).filter(e=>!m.some(t=>t.key===e)).map(e=>({path:`fieldValues.${e}`,code:`INVALID_FIELDS`})),...m.filter(e=>e.required&&(h[e.key]??``).trim()===``).map(e=>({path:`fieldValues.${e.key}`,code:`INVALID_FIELDS`}))];if(g.length>0)return H(g);let _=await os(d.docSha256,a.value.signature,{fieldValues:h,salt:d.piiSalt}),v=ms(e),y={status:`signed`,signature:_,consentAt:f,consentVersion:p.version,consentSha256:p.sha256,signedAt:f,fieldValues:h,...v};if(d.signerIds.length>1)return n?n(t,{envelopeId:u,envelope:d,signer:l,set:y,now:f}):U(`ENVELOPE_CLOSED`);let b=us({at:f,docSha256:d.docSha256,consentVersion:p.version,consentSha256:p.sha256,signature:_,signerName:l.data.name,who:v}),x=await Rn(u,await Bn(c,u),b,d.piiSalt),S=await Gn(d.docSha256,x.at(-1)?.data.hash??``),C=await I(o,u,d.status,`completed`,{completedAt:f,finalHash:S,updatedAt:f});if(!C.ok)return U(`ENVELOPE_CLOSED`);if(await s.updateIf(l.id,{where:{status:`pending`},set:y}),!await Vn(c,x))throw Error(`audit chain contention`);return await xi(t.cron,u,Date.parse(f)),{ok:!0,status:`completed`,completedAt:f,...await xs(u,C.value,p.masterKey)}}async function As(e,t){if(hs(e.request))return U(`TOKEN_IN_QUERY`);let n=gs(t,e),r=ps(e.input);if(r===null)return n.fail();let i=as(V(e.input).reason);if(i===null)return H([{path:`reason`,code:`INVALID_INPUT`}]);let{envelopes:a,signers:o}=B(t),s=await _s(t,r);if(!s||s.data.status!==`pending`)return n.fail();let c=s.data.envelopeId,l=await a.get(c);if(!l)return U(`ENVELOPE_NOT_FOUND`);if(!Xn(l.status,`declined`))return U(`ENVELOPE_CLOSED`);let u=A();if(ws(l,u))return Ts(t,c,l,u);let d=await I(a,c,l.status,`declined`,{closedAt:u,updatedAt:u});if(!d.ok)return U(`ENVELOPE_CLOSED`);let f=ms(e);return await o.updateIf(s.id,{where:{status:`pending`},set:{status:`declined`,declinedAt:u,...i===void 0?{}:{declineReason:i},...f}}),await Ds(t,c,l.piiSalt,ds({at:u,docSha256:l.docSha256,hasReason:i!==void 0,who:f,order:Es(l,s.data)})),{ok:!0,status:`declined`,...await xs(c,d.value,await bs(t,d.value))}}const js=e=>(t,n)=>e(t,n),Ms=(e=>({"public/session":js(Os),"public/submit":js((t,n)=>ks(t,n,e)),"public/decline":js(As)}))(),Ns=[`sent`,`in_progress`];function Ps(e){try{return new URL(e.site.url).origin}catch{return}}async function Fs(e,t,n={}){let r=(n.now??Date.now)(),i=A(r),{envelopes:a,signers:o,snapshots:s,templates:c,nonces:l}=B(t),u=Yo(t),d=await et({token:V(e).intent,now:r,getClient:u.getClient,consumeNonce:async(e,t,n)=>{let r=`${e}.${t}`;try{let t={nonce:r,cid:e,expiresAt:A(n*1e3)};return(await l.compareAndSet(r,null,t)).applied}catch(e){if(Li(e))return!1;throw e}},siteOrigin:Ps(t)});if(!d.ok)return U(d.error);let f=d.value,p=u.settings();if(f.replace===!0)return zs(t,f,i);let m=f.tplVersion===void 0?void 0:L(f.tpl,f.tplVersion),h=await c.getMany(m===void 0?[f.tpl]:[f.tpl,m]),g=h.get(f.tpl);if(!rr(g))return U(`TEMPLATE_NOT_FOUND`);let _=gr(g,m===void 0?void 0:h.get(m),f.tplVersion);if(!_.ok)return U(`TEMPLATE_NOT_FOUND`);let v=jn(n.random),y=xr(f,_.value,{now:i,piiSalt:v});if(!y.ok)return H(y.error);let b={delivery:y.value.delivery,signer:y.value.signer},x=f.resend===!0?(e,n,i)=>En(t,{signerId:e,envelope:n,token:i,senderSetting:p.senderName,now:r}):void 0,S=Ii(p.expiryDays),C=Sr(f),w=async(e,t,r)=>Rs(o,e,await Ls(a,e,t,C,S,i),b,n.random,r),T=ae(n.random),ee=await oe(T),te=async e=>{let t=await Mr(f.cid,f.ref,e);return{id:t,sent:await kr(t,y.value,_.value,{now:i,tokenHash:ee,expiryDays:S})}},E=await te(1);if(!E.sent.ok)return Array.isArray(E.sent.error)?H(E.sent.error):U(`INTERNAL`);let ne=await a.compareAndSet(E.id,null,E.sent.value.envelope);if(!ne.applied){let e=await a.query({where:{clientId:f.cid,externalRef:f.ref},limit:100}),n=jr(e.items);if(n)return n.data.status===`draft`&&await oa(t.cron,n.id,r),w(n.id,n.data,x);let i=Math.max(e.items.length,1)+1;if(y.value.delivery===`email`){let e=await Mr(f.cid,f.ref,i);if(!(await a.compareAndSet(e,null,y.value)).applied){let t=await a.get(e);return t?w(e,t):U(`INTERNAL`)}return await oa(t.cron,e,r),$(e,y.value,void 0)}if(E=await te(i),!E.sent.ok)return Array.isArray(E.sent.error)?H(E.sent.error):U(`INTERNAL`);if(ne=await a.compareAndSet(E.id,null,E.sent.value.envelope),!ne.applied){let e=await a.get(E.id);return e?w(E.id,e):U(`INTERNAL`)}}let{id:D,sent:O}=E;if(!O.ok)return U(`INTERNAL`);await s.putMany(O.value.chunks);let re=await zi(o,O.value.signer,T,n.random);O.value.envelope.delivery===`email`&&await En(t,{signerId:O.value.signer.id,envelope:O.value.envelope,token:re,senderSetting:p.senderName,now:r});let ie=[Nr(y.value,`integration`),Pr(O.value.envelope,`integration`)];return await B(t).audit_events.putMany(await Ln(D,ie,v)),$(D,O.value.envelope,re)}function $(e,t,n,r=t.delivery===`inline`){return{ok:!0,envelopeId:e,status:t.status,...n!==void 0&&r?{signingToken:n}:{}}}function Is(e,t){let n=e.signer;return n.email===t.email&&n.as===t.as&&(n.participant?.name??null)===(t.participant?.name??null)}async function Ls(e,t,n,r,i,a){if(r===void 0)return n;let o={applied:!1};if(n.status===`draft`)n.signBy!==void 0&&n.signBy<r&&(o=await e.updateIf(t,{where:{status:`draft`,signBy:{lt:r}},set:{signBy:r,updatedAt:a}}));else if(Ns.includes(n.status)&&n.sentAt&&n.expiresAt){let s=Cr(n.sentAt,i,r);s>n.expiresAt&&(o=await e.updateIf(t,{where:{status:{in:Ns},expiresAt:{lt:s}},set:{expiresAt:s,signBy:r,updatedAt:a}}))}return o.applied?o.data:n}async function Rs(e,t,n,r,i,a){let o=n.signerIds[0],s=(n.status===`sent`||n.status===`in_progress`)&&Is(n,r.signer),c=r.delivery===`inline`&&s,l=a!==void 0&&r.delivery===`email`&&n.delivery===`email`&&s;if(!c&&!l||o===void 0)return $(t,n,void 0);let u=await Ri(ae(i),i,t=>e.updateIf(o,{where:{status:`pending`},set:{tokenHash:t}}));if(!u.value.applied)return $(t,n,void 0);if(c||!a)return $(t,n,u.token,!0);let d=await a(o,n,u.token);return{...$(t,n,void 0),...d?{resent:!0}:{}}}async function zs(e,t,n){let{envelopes:r}=B(e),i=jr((await r.query({where:{clientId:t.cid,externalRef:t.ref},limit:100})).items);if(!i)return{ok:!0,status:`none`};let a=i.data.signer;if(a.name===t.signer.name.trim()&&a.email===t.signer.email.trim().toLowerCase()&&a.as===(t.as??`self`)&&(a.participant?.name??null)===(t.participant?.name.trim()??null)||i.data.status===`completed`)return $(i.id,i.data,void 0);let o=await I(r,i.id,i.data.status,`voided`,{closedAt:n,updatedAt:n});return o.ok?(await Hi(e,i.id,o.value,{type:`envelope.voided`,at:n,actor:`integration`}),$(i.id,o.value,void 0)):U(`ENVELOPE_CLOSED`)}const Bs=(e,t)=>Fs(e.input,t),Vs=`integrations:site-client`,Hs=[`origin`,`sec-fetch-mode`,`sec-fetch-site`,`sec-fetch-dest`],Us={ADMIN_REQUIRED:`Only an administrator can pair plugins.`,SERVER_ONLY:`Pairing runs on the server only.`,BAD_REQUEST:`The request was not valid.`,MASTER_KEY_INVALID:`The integration master key is unreadable or shorter than 32 characters.`,ENCRYPTION_KEY_MISSING:`EMDASH_ENCRYPTION_KEY is not set, so the master key cannot be saved.`},Ws=e=>({ok:!1,error:{code:e,message:Us[e]}});function Gs(e,t){if(e)return typeof e.get==`function`?e.get(t)??void 0:e[t]}const Ks=e=>e!=null&&e!==``,qs={"integrations/pair":{handler:(async(e,t)=>{let n=e.user?.role;if(typeof n!=`number`||n<50)return Ws(`ADMIN_REQUIRED`);if(Hs.some(t=>Gs(e.request?.headers,t)!==void 0))return Ws(`SERVER_ONLY`);let r=V(e.input),i=r.action;if(i!==`status`&&i!==`pair`&&i!==`unpair`)return Ws(`BAD_REQUEST`);let a=r.clientId;if(a!==void 0&&(typeof a!=`string`||!ge.test(a)))return Ws(`BAD_REQUEST`);let o=B(t).clients,[s,c]=await Promise.all([t.settings.list(),t.kv.get(Vs)]),l=typeof c==`string`?c:null,u=typeof a==`string`?a:l,[d,f]=await Promise.all([u?o.get(u):null,l&&l!==u&&i!==`status`?o.get(l):null]),p=d!==null&&!d.revokedAt,m=f!==null&&!f.revokedAt,h=A();if(i===`status`)return d&&u?{ok:!0,client:p?`active`:`revoked`,clientId:u}:{ok:!0,client:`none`};if(i===`unpair`)return m&&l&&await Fa(o,l,h),{ok:!0,revoked:p&&u?await Fa(o,u,h):!1};let g=s.find(e=>e.key===`integrationMasterKey`)?.value;if(!Ks(g)){g=ja();try{await t.settings.set(`integrationMasterKey`,g)}catch(e){if(Ra(e))return Ws(`ENCRYPTION_KEY_MISSING`);throw e}}let _=W(g);if(!_)return Ws(`MASTER_KEY_INVALID`);let v=p&&u?u:m?l:null;if(v)return v!==l&&(await t.kv.set(Vs,v),m&&l&&await Fa(o,l,h)),{ok:!0,created:!1,clientId:v,pairing:ft(v,await pt(_,v))};let y=await Pa(o,{name:`Events on this site`,returnUrlAllowlist:[],masterKey:g},{now:h});return y.ok?(await t.kv.set(Vs,y.client.clientId),{ok:!0,created:!0,clientId:y.client.clientId,pairing:y.pairing}):Ws(`MASTER_KEY_INVALID`)})}},Js=64*1024,Ys=[{name:`public/envelopes/from-intent`,methods:[`POST`],body:`json`,maxBytes:16*1024},{name:`public/session`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/otp/send`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/otp/verify`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/submit`,methods:[`POST`],body:`json`,maxBytes:256*1024},{name:`public/decline`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/download`,methods:[`GET`],body:`none`,response:`raw`},{name:`public/verify`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/receipts/lookup`,methods:[`POST`],body:`json`,maxBytes:8*1024},{name:`public/templates/catalog`,methods:[`POST`],body:`json`,maxBytes:Js},{name:`public/self-serve/start`,methods:[`POST`],body:`json`,maxBytes:Js}];async function Xs(){return D({code:`NOT_FOUND`}).body}function Zs(e={}){let t={};for(let n of Ys)t[n.name]={public:!0,methods:[...n.methods],request:n.maxBytes===void 0?{body:n.body}:{body:n.body,maxBytes:n.maxBytes},...n.response?{response:n.response}:{},handler:e[n.name]??Xs};return t}const Qs=e=>Number(/_(\d+)$/.exec(e)?.[1]??0);function $s(e){let t;for(let n of e)(!t||Qs(n.id)>Qs(t.id)||Qs(n.id)===Qs(t.id)&&n.data.createdAt>t.data.createdAt)&&(t=n);return t}async function ec(e,t,n=Date.now()){let r=Yo(t),i=await nt({token:V(e).request,now:n,getClient:r.getClient});if(!i.ok)return U(i.error);let{cid:a,ref:o}=i.value,s=$s((await B(t).envelopes.query({where:{clientId:a,externalRef:o},limit:100})).items.filter(e=>e.data.clientId===a&&e.data.externalRef===o));if(!s)return{ok:!0,state:`none`,receipt:null};if(!Zn(s.data.status))return{ok:!0,state:`pending`,receipt:null};let c=await Xo(s.id,s.data,r.settings().integrationMasterKey);return c?{ok:!0,state:`terminal`,receipt:c}:U(`INTERNAL`)}const tc=(e,t)=>ec(e.input,t),nc=/^[0-9a-f]{64}$/,rc=async(e,t)=>{let n=V(e.input).sha256,r=typeof n==`string`?n.toLowerCase():``;if(!nc.test(r))return H([{path:`sha256`,code:`invalid`}]);if(!(await qt({get:e=>t.kv.get(e),set:(e,n)=>t.kv.set(e,n)},e.requestMeta?.ip??`unknown`,Date.now(),{scope:`esign-verify`,limit:20,windowSeconds:600,salt:`esign-verify/1`})).ok)return U(`RATE_LIMITED`);let{envelopes:i,audit_events:a}=B(t),o=(await i.query({where:{pdfSha256:r},limit:1})).items[0];if(!o||o.data.status!==`completed`)return{ok:!0,matched:!1};let s=o.data,{items:c}=await a.query({where:{envelopeId:o.id},orderBy:{seq:`asc`},limit:101}),l=null;if(c.length<=100){let e=c.map(e=>e.data),t=await Un(o.id,e);l=t.ok&&s.docSha256!==null&&e.at(-1)?.type===`envelope.completed`&&await Gn(s.docSha256,t.value.head)===s.finalHash}return{ok:!0,matched:!0,status:s.status,completedAt:s.completedAt,finalHash:s.finalHash,chainVerified:l}},ic=[{name:xn,schedule:`* * * * *`},{name:ua,schedule:`0 * * * *`},{name:ma,schedule:`23 3 * * *`},{name:ta,schedule:`17 * * * *`}],ac=Zs({"public/envelopes/from-intent":Bs,"public/download":Ni,"public/verify":rc,"public/receipts/lookup":tc,"public/templates/catalog":Qo,...Ms}),oc={hooks:{"plugin:activate":async(e,t)=>{await Qt(t,ic)},cron:async(e,t)=>{await en(e,t,ic,Date.now())||await On(e,t)||await ea(e,t)||await la(e,t)||await pa(e,t)||await Ea(e,t)||await ra(e,t)||await Ci(e,t)}},routes:{...ac,...Uo,...Ga,...Yi,...qs,admin:nn(Uo.admin,tn),"templates/create":nn(Ga[`templates/create`]),"public/verify":nn(ac[`public/verify`])}};export{oc as default};
|
package/package.json
CHANGED
package/src/astro/lib/csp.ts
CHANGED
|
@@ -17,24 +17,39 @@ export async function cspSource(text: string): Promise<string> {
|
|
|
17
17
|
|
|
18
18
|
let cached: Promise<string> | undefined;
|
|
19
19
|
|
|
20
|
-
/**
|
|
21
|
-
export
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
].join("; "),
|
|
34
|
-
);
|
|
20
|
+
/** What a host page adds to the ceremony's own: its exact inline stylesheets, and one linked stylesheet (absolute URL). */
|
|
21
|
+
export interface CeremonyCspExtras {
|
|
22
|
+
styles?: readonly string[];
|
|
23
|
+
stylesheet?: string | undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The header value for any page that renders <SigningCeremony> and nothing else inline but `extras`. A linked
|
|
28
|
+
* stylesheet is allowed by its exact URL, with `font-src 'self'` for the fonts it may name; scripts never change.
|
|
29
|
+
*/
|
|
30
|
+
export function ceremonyCsp(extras?: CeremonyCspExtras): Promise<string> {
|
|
31
|
+
if (extras) return ceremonyCspFor(extras);
|
|
32
|
+
cached ??= ceremonyCspFor({});
|
|
35
33
|
return cached;
|
|
36
34
|
}
|
|
37
35
|
|
|
36
|
+
async function ceremonyCspFor({ styles = [], stylesheet }: CeremonyCspExtras): Promise<string> {
|
|
37
|
+
const [script, pad, ...sources] = await Promise.all(
|
|
38
|
+
[CEREMONY_SCRIPT, PAD_SCRIPT, CEREMONY_CSS, ...styles].map(cspSource),
|
|
39
|
+
);
|
|
40
|
+
return [
|
|
41
|
+
"default-src 'none'",
|
|
42
|
+
`script-src ${script} ${pad}`,
|
|
43
|
+
`style-src ${[...sources, ...(stylesheet ? [stylesheet] : [])].join(" ")}`,
|
|
44
|
+
"img-src 'self' data:",
|
|
45
|
+
...(stylesheet ? ["font-src 'self'"] : []),
|
|
46
|
+
"connect-src 'self'",
|
|
47
|
+
"form-action 'self'",
|
|
48
|
+
"base-uri 'none'",
|
|
49
|
+
"frame-ancestors 'none'",
|
|
50
|
+
].join("; ");
|
|
51
|
+
}
|
|
52
|
+
|
|
38
53
|
let cachedVerify: Promise<string> | undefined;
|
|
39
54
|
|
|
40
55
|
/**
|