@semics-tech/emdash-esign 1.0.0-rc.1 → 1.0.0-rc.3
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 +3 -2
- package/dist/manifest.json +3 -2
- package/dist/plugin.mjs +15 -15
- package/package.json +2 -2
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.3",
|
|
11
11
|
"format": "standard",
|
|
12
12
|
"entrypoint": "@semics-tech/emdash-esign/sandbox",
|
|
13
13
|
"capabilities": [
|
|
@@ -235,7 +235,8 @@ const descriptor = Object.freeze({
|
|
|
235
235
|
"envelopes/list",
|
|
236
236
|
"envelopes/resend",
|
|
237
237
|
"envelopes/void",
|
|
238
|
-
"outbox/status"
|
|
238
|
+
"outbox/status",
|
|
239
|
+
"integrations/pair"
|
|
239
240
|
],
|
|
240
241
|
"adminPages": [
|
|
241
242
|
{
|
package/dist/manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "semics-esign",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.3",
|
|
4
4
|
"declaredAccess": {
|
|
5
5
|
"media": {
|
|
6
6
|
"read": {},
|
|
@@ -242,7 +242,8 @@
|
|
|
242
242
|
"envelopes/list",
|
|
243
243
|
"envelopes/resend",
|
|
244
244
|
"envelopes/void",
|
|
245
|
-
"outbox/status"
|
|
245
|
+
"outbox/status",
|
|
246
|
+
"integrations/pair"
|
|
246
247
|
],
|
|
247
248
|
"admin": {
|
|
248
249
|
"settingsSchema": {
|
package/dist/plugin.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
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
|
|
2
|
-
`)}async function pe(e,t){return x(new Uint8Array(await crypto.subtle.sign(`HMAC`,e,ae.encode(t))))}async function me(e){let{secret:t,purpose:n,params:r,now:i,ttlMs:a=9e5}=e,o=await de(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>=ie&&a<=re))throw Error(`Link ttl must be between ${ie} and ${re} ms.`);let s=Object.entries(r);if(s.some(([e])=>oe.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 pe(o,fe(n,c,s))),l}async function he(e){let{secret:t,purpose:n,query:r,now:i}=e,a=await de(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||!se.test(c)||!le(await pe(a,fe(n,c,s)),l)?T(`TOKEN_INVALID`):i>=Number(c)*1e3?T(`TOKEN_EXPIRED`):w(Object.fromEntries(s))}const ge=Object.freeze({intent:`esign-intent/1`,receipt:`esign-receipt/1`,lookup:`esign-lookup/1`,catalog:`esign-catalog/1`}),_e=Object.freeze({intent:8192,receipt:2048,lookup:1024,catalog:1024}),ve=/^[A-Za-z0-9_-]{4,64}$/,ye=/^[A-Za-z0-9_-]*$/,be=new TextEncoder;function xe(e){if(!ye.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 Se(e){if(e.length!==32)throw Error(`Client secret must be 32 bytes.`);return C(e)}async function Ce(e,t,n){let r=await crypto.subtle.sign(`HMAC`,await Se(e),be.encode(`${t}.${n}`));return x(new Uint8Array(r))}const we=/^[A-Za-z0-9_-]{1,64}$/,Te=/^[A-Za-z0-9._:-]{1,128}$/,Ee=/^[0-9a-f]{64}$/,De=/^[A-Za-z0-9_-]{16,64}$/,Oe=/^[A-Za-z0-9_]{1,64}$/,ke=/[\uD800-\uDFFF]/u,Ae=/[\u0000-\u001F\u007F]/,je=/[\u0000- \u007F]/;function Me(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Ne(e){let t=0;for(let n of e)t++;return t}function Pe(e,t,n){if(typeof e!=`string`||ke.test(e))return!1;let r=Ne(e);return r>=t&&r<=n}function k(e,t){return typeof e==`string`&&t.test(e)}function Fe(e){return Number.isSafeInteger(e)&&e>=0}function Ie(e){return Pe(e,1,200)&&!Ae.test(e)}function Le(e){if(!Pe(e,1,254)||je.test(e))return!1;let t=e.split(`@`);return t.length===2&&t[0]!==``&&t[1]!==``}function Re(e){if(!Me(e))return!1;let t=Object.entries(e);return t.length<=32&&t.every(([e,t])=>Oe.test(e)&&Pe(t,0,500))}function ze(e){return Me(e)&&Ie(e.name)}function Be(e){let t=e.as===`guardian`;return Fe(e.iat)&&Fe(e.exp)&&e.exp>e.iat&&k(e.nonce,De)&&k(e.tpl,we)&&(e.tplVersion===void 0||Number.isSafeInteger(e.tplVersion)&&e.tplVersion>=1)&&k(e.ref,Te)&&Me(e.signer)&&Ie(e.signer.name)&&Le(e.signer.email)&&(e.as===void 0||e.as===`self`||t||e.as===`buyer`)&&(t?ze(e.participant):!Object.hasOwn(e,`participant`))&&(e.delivery===void 0||e.delivery===`inline`||e.delivery===`email`)&&Re(e.prefill)&&Pe(e.returnUrl,1,2048)}const Ve=new Set([`completed`,`declined`,`voided`,`expired`]);function He(e){let t=e.status===`completed`;return k(e.envelopeId,we)&&k(e.ref,Te)&&Ve.has(e.status)&&k(e.docSha256,Ee)&&(t?e.pdfSha256===null||k(e.pdfSha256,Ee):e.pdfSha256===null)&&(t?k(e.finalHash,Ee):e.finalHash===null)&&Fe(e.at)}const Ue={intent:Be,receipt:He,lookup:e=>Fe(e.ts)&&k(e.ref,Te),catalog:e=>Fe(e.ts)};function We(e,t){return!Me(t)||t.v!==1||t.typ!==e||!k(t.cid,ve)||!Ue[e](t)?T(`PAYLOAD_INVALID`):e===`intent`&&t.exp-t.iat>1800?T(`TOKEN_LIFETIME_EXCEEDED`):w(t)}const Ge=new Set([`localhost`,`127.0.0.1`,`[::1]`]);function Ke(e){try{return new URL(e)}catch{return}}function qe(e){return e.username!==``||e.password!==``}function Je(e){let t=Ke(e);if(!(t===void 0||qe(t)||t.search!==``||e.includes(`#`)))return t.protocol===`https:`||t.protocol===`http:`&&Ge.has(t.hostname)?t:void 0}function Ye(e,t){return t.endsWith(`/`)?e.startsWith(t):e===t||e.startsWith(`${t}/`)}function Xe(e,t){let n=Ke(e);return n===void 0||n.protocol!==`https:`&&n.protocol!==`http:`||qe(n)||e.includes(`#`)?!1:t.some(e=>{let t=Je(e);return t!==void 0&&t.origin===n.origin&&Ye(n.pathname,t.pathname)})}async function Ze(e,t){let{token:n}=t;if(typeof n!=`string`)return T(`TOKEN_MALFORMED`);if(n.length>_e[e])return T(`TOKEN_TOO_LARGE`);let r=n.split(`.`);if(r.length!==2)return T(`TOKEN_MALFORMED`);let[i,a]=r,o=xe(i);if(o===void 0||o.length===0||a.length!==43||xe(a)===void 0)return T(`TOKEN_MALFORMED`);let s=Qe(o);if(s===void 0||!k(s.cid,ve))return T(`TOKEN_MALFORMED`);let c=await t.getClient(s.cid);return c===void 0?T(`CLIENT_UNKNOWN`):c.revoked?T(`CLIENT_REVOKED`):le(await Ce(c.secret,ge[e],i),a)?w({payload:s,client:c}):T(`TOKEN_INVALID`)}function Qe(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 Me(t)?t:void 0}catch{return}}function $e(e,t){return e===`intent`?t.iat:e===`receipt`?t.at:t.ts}function et(e,t){if(e===`intent`)return t.exp+60;if(e!==`receipt`)return t.ts+300+60}async function tt(e,t){let n=await Ze(e,t);if(!n.ok)return n;let r=We(e,n.value.payload);if(!r.ok)return r;let i=Math.floor(t.now/1e3);if($e(e,r.value)>i+60)return T(`TOKEN_NOT_YET_VALID`);let a=et(e,r.value);return a!==void 0&&i>a?T(`TOKEN_EXPIRED`):w({payload:r.value,client:n.value.client})}async function nt(e){let t=await tt(`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 Xe(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 rt(e,t){let n=await tt(e,t);return n.ok?w(n.value.payload):n}function it(e){return rt(`lookup`,e)}function at(e){return rt(`catalog`,e)}async function ot(e,t,n){let r=We(e,t);if(!r.ok)throw Error(`Cannot sign ${e} token: ${r.error}.`);let i=x(be.encode(JSON.stringify(t))),a=`${i}.${await Ce(n,ge[e],i)}`;if(a.length>_e[e])throw Error(`Cannot sign ${e} token: TOKEN_TOO_LARGE.`);return a}const A=(e=Date.now())=>new Date(e).toISOString();function st(e){let t=e.kind;return{to:e.to,subject:e.subject,...typeof t==`string`?{kind:t}:{}}}async function ct(e,t,n,r){let i=r();return await e.put(i,{message:t,status:`pending`,attempts:0,nextAttemptAt:n,createdAt:n}),i}function lt(e){return Math.min(6e4*2**(e-1),36e5)}async function ut(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=st(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:st(c.message),status:`failed`,attempts:n,lastError:a}})):(o++,i.push({id:t,data:{...c,attempts:n,lastError:a,nextAttemptAt:e.now+lt(n)}}))}}return await e.storage.putMany(i),{sent:a,failed:o,gaveUp:s,remainingHint:r.length>n}}async function dt(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 ft=new TextEncoder;function pt(e){if(!ve.test(e))throw Error(`Client id must match the esign-intent/1 clientId grammar.`)}function mt(e,t){if(pt(e),t.length!==32)throw Error(`Client secret must be 32 bytes.`);return`esign1.${e}.${x(t)}`}async function ht(e,t){if(e.length<32)throw Error(`Master key must be at least 32 bytes.`);pt(t);let n=await C(e);return new Uint8Array(await crypto.subtle.sign(`HMAC`,n,ft.encode(`esign-client/1.`+t)))}function gt(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 _t=[{font:`regular`,resource:`F1`,baseFont:`Helvetica`},{font:`bold`,resource:`F2`,baseFont:`Helvetica-Bold`},{font:`italic`,resource:`F3`,baseFont:`Helvetica-Oblique`}];function vt(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 yt=vt(`7q7q9vfgfgopij5b9999atg87q997q7qfgfgfgfgfgfgfgfgfgfg7q7qg8g8g8fgs7ijijk2k2ijgzlmk27qdwijfgn5k2lmijlmk2ijgzk2ijq8ijijgz7q7q7qd1fg99fgfgdwfgfg7qfgfg6666dw66n5fgfgfgfg99dw7qfgdwk2dwdwdw9a789ag800fg0066fg99rsfgfg99rsij99rs00gz0000666699999qfgrs99rsdw99q800dwij7q99fgfgfgfg78fg99khaafgg899kh99b4g8999999fgex7q9999a5fgn6n6n6gzijijijijijijrsk2ijijijij7q7q7q7qk2k2lmlmlmlmlmg8lmk2k2k2k2ijijgzfgfgfgfgfgfgopdwfgfgfgfg7q7q7q7qfgfgfgfgfgfgfgg8gzfgfgfgfgdwfgdw`),bt={regular:yt,bold:vt(`7q99d6fgfgopk26m9999atg87q997q7qfgfgfgfgfgfgfgfgfgfg9999g8g8g8gzr3k2k2k2k2ijgzlmk27qfgk2gzn5k2lmijlmk2ijgzk2ijq8ijijgz997q99g8fg99fggzfggzfg99gzgz7q7qfg7qopgzgzgzgzatfg99gzfglmfgfgdwat7satg800fg007qfgdwrsfgfg99rsij99rs00gz00007q7qdwdw9qfgrs99rsfg99q800dwij7q99fgfgfgfg7sfg99khaafgg899kh99b4g8999999gzfg7q9999a5fgn6n6n6gzk2k2k2k2k2k2rsk2ijijijij7q7q7q7qk2k2lmlmlmlmlmg8lmk2k2k2k2ijijgzfgfgfgfgfgfgopfgfgfgfgfg7q7q7q7qgzgzgzgzgzgzgzg8gzgzgzgzgzfggzfg`),italic:yt},xt=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]]:[])),St=/^[\x20-\x7e\xa0-\xff]*$/;function Ct(e){return e>=32&&e<=126||e>=160&&e<=255?e:e===9||e===10||e===13?32:xt.get(e)??63}function wt(e){if(St.test(e))return e;let t=``;for(let n of e)t+=String.fromCharCode(Ct(n.codePointAt(0)));return t}function Tt(e){return bt[e]}function Et(e,t){let n=bt[t],r=0;for(let t=0;t<e.length;t++)r+=n[e.charCodeAt(t)];return r}const Dt=1e7;function j(e){if(!Number.isFinite(e))return`0`;let t=Math.round(Math.min(Dt,Math.max(-Dt,e))*100)/100;return t===0?`0`:String(t)}function Ot(e){return`(${e.replace(/[\\()]/g,`\\$&`)})`}function kt(e){if(/^[\x20-\x7e]*$/.test(e))return Ot(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 At(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 jt(e){return`<< /Length ${e.length} >>\nstream\n${e}\nendstream`}function Mt(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=3600*1e3,re=1e3,ie=new TextEncoder,ae=new Set([`exp`,`sig`]),oe=/^\d{1,15}$/;function se(e=b){let t=e(32);if(t.length!==32)throw Error(`Random source must return 32 bytes.`);return x(t)}async function k(e){return S(new Uint8Array(await crypto.subtle.digest(`SHA-256`,ie.encode(e))))}function ce(e,t){let n=ie.encode(e),r=ie.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 le(e,t){return ce(await k(e),t??`0`.repeat(64))}async function ue(e){if(e.length<32)throw Error(`Link secret must be at least 32 bytes.`);return C(e)}function de(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 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
|
|
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 Kt(e){let t=[],n=(e,n)=>{typeof n==`string`&&n!==``&&t.push(`/${e} ${
|
|
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 Mt(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 Nt(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=Mt(n);e&&r>0&&(t.push(e),r--)}t.length>0&&n.push(t)}return n}function Pt(e,t){let n=Nt(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=>M(t.x+Math.min(i,Math.max(0,e))*o),l=e=>M(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 Ft=Ct(` `);function N(e,t,n,r){let i=n*1e3+1e-6,a=wt(r),o=Tt(Ft,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=Ct(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(Ft)}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 It={width:595.28,height:841.89},Lt=1.3,Rt={1:18,2:13,3:11},zt=Object.fromEntries(gt.map(e=>[e.font,e.resource])),P=(e,t)=>typeof e==`number`&&Number.isFinite(e)&&e>0?e:t,Bt=(e,t)=>typeof e==`number`&&Number.isFinite(e)&&e>=0?e:t,Vt=e=>typeof e==`string`?e:e==null?``:String(e),Ht=e=>e===`bold`||e===`italic`?e:`regular`;function Ut(e){let t=Math.round(P(e?.width,It.width)*100)/100,n=Math.round(P(e?.height,It.height)*100)/100,r=e?.margin,i=e=>Bt(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 Wt=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 M(this.g.height-e)}text(e,t,n,r,i){i.length!==0&&this.ops.push(`BT /${zt[r]} ${M(n)} Tf ${M(e)} ${this.pdfY(t+n)} Td ${Dt(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*Lt;for(let i of N(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=Rt[t],r=N(e,n,this.contentWidth,`bold`),i=this.atTop?0:n*.6;this.ensure(i+r.length*n*Lt+n*.4+20*Lt),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 ${M(this.left)} ${e} m ${M(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=>P(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*Lt,c=(e,t)=>o.map((r,i)=>N(Vt(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 ${M(this.left)} ${u} ${M(this.contentWidth)} ${M(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(`${M(a[e])} ${u} ${M(o[e])} ${M(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(P(e.width,220),this.contentWidth),n=P(e.height,70),r=N(Vt(e.label),9,this.contentWidth,`regular`).filter(e=>e.bytes),i=(Array.isArray(e.caption)?e.caption:[]).flatMap(e=>N(Vt(e),9,this.contentWidth,`regular`)).filter(e=>e.bytes),a=9*Lt;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=N(Vt(e.typedName),20,t,`italic`)[0];s?.bytes&&this.text(this.left+4,o+n-28,20,`italic`,s.bytes);let c=Pt(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 ${M(this.left)} ${l} m ${M(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(Vt(e.text),e.level===2||e.level===3?e.level:1);break;case`paragraph`:{let t=P(e.size,10),n=e.align===`center`||e.align===`right`?e.align:`left`;this.paragraph(Vt(e.text),t,Ht(e.font),n,t*.5);break}case`spacer`:this.spacer(Bt(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:[],P(e.size,9));break;case`signature`:this.signature(e);break}}footer(e){if(!e)return;let t=Vt(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]=N(a.join(` · `),8,this.contentWidth,`regular`),s=this.alignX(o,`center`),c=this.g.margin.bottom/2;r.push(`BT /F1 8 Tf ${M(s)} ${M(c)} Td ${Dt(o.bytes)} Tj ET`)})}};function Gt(e,t,n){let r=new Wt(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 Kt(e){let t=[],n=(e,n)=>{typeof n==`string`&&n!==``&&t.push(`/${e} ${Ot(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=kt(e.creationDate);n&&t.push(`/CreationDate (${n})`)}return`<< ${t.join(` `)} >>`}function qt(e){let t=Ut(e.page),n=Gt(t,e.blocks,e.footer),r=[`<< /Type /Catalog /Pages 2 0 R >>`,``,Kt(e.info)],i=gt.map(e=>(r.push(`<< /Type /Font /Subtype /Type1 /BaseFont /${e.baseFont} /Encoding /WinAnsiEncoding >>`),`/${e.resource} ${r.length} 0 R`)).join(` `),a=`[0 0 ${M(t.width)} ${M(t.height)}]`,o=[];for(let e of n){r.push(At(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} >>`,jt(r,1,3)}async function Jt(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 Yt(e,t,n,r){let i=Math.floor(n/(r.windowSeconds*1e3)),a=`rl:${r.scope}:${await Jt(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 Xt(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 Zt=`cron:scheduled:v11`,Qt=`ensure-schedules`;async function $t(e,t){try{if(await e.kv.get(Zt))return;await e.cron?.schedule(Qt,{schedule:new Date(t).toISOString()})}catch{}}async function en(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 tn(e,t,n){await en(e,t)&&await e.kv.set(Zt,{at:new Date(n).toISOString()})}async function nn(e,t,n,r){return e.name===Qt?(await tn(t,n,r),!0):!1}function rn(e){return typeof e==`object`&&!!e&&e.type===`page_load`}function an(e,t=()=>!0,n=Date.now){let r=e.handler,i=async(e,i)=>(t(e?.input)&&await $t(i,n()),r(e,i));return{...e,handler:i}}var on=class extends Error{code=`TEMPLATE_MISSING_FIELD`;constructor(e){super(`Template field "${e}" has no value`),this.field=e,this.name=`TemplateError`}};const sn=/\{\{\s*([A-Za-z_][A-Za-z0-9_.]*)\s*\}\}/g,cn={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`};function ln(e){return e.replace(/\s*[\r\n]+\s*/g,` `).replace(/[\\&<>"'#[\]()*_`~|{}+!-]/g,e=>cn[e]??`\\${e}`)}function un(e){return[...new Set([...e.matchAll(sn)].map(e=>e[1]))]}function dn(e,t){return e.replace(sn,(e,n)=>{let r=Object.hasOwn(t,n)?t[n]:void 0;if(r===void 0)throw new on(n);return ln(String(r))})}function fn(e){return`${e.replace(/^/,``).replace(/\r\n?/g,`
|
|
7
7
|
`).normalize(`NFC`).split(`
|
|
8
8
|
`).map(e=>e.replace(/[ \t]+$/,``)).join(`
|
|
9
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 pn={"&":`&`,"<":`<`,">":`>`,'"':`"`,"'":`'`},mn=e=>e.replace(/[&<>"']/g,e=>pn[e]),hn=e=>e.replace(/\s*[\r\n]+\s*/g,` `),gn=/\{\{(\w+)\}\}/g;function _n(e,t,n){return e.replace(gn,(e,r)=>n(t[r]??``))}const vn=`January February March April May June July August September October November December`.split(` `);function yn(e){let t=new Date(e);return`${t.getUTCDate()} ${vn[t.getUTCMonth()]} ${t.getUTCFullYear()}`}function bn(e,t,n){let r=Object.fromEntries(Object.entries(n).map(([e,t])=>[e,hn(t)]));return{to:e,subject:_n(t.subject,r,e=>e),text:_n(t.text,r,e=>e),html:_n(t.html,r,mn)}}function xn(e){let t=e.expiresAt?`This request expires on ${yn(e.expiresAt)}.`:``;return bn(e.to,{subject:`{{sender}} asks you to sign: {{title}}`,text:`Hello {{name}},
|
|
@@ -24,15 +24,15 @@ 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 Cn=`outbox-drain`;function wn(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 Tn(e){try{let{origin:t}=new URL(e.site.url);return t===`null`?``:t}catch{return``}}const En=(e,t)=>typeof t==`string`&&t.trim()!==``?t.trim():e.site.name,Dn=`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 On(e,t){let{signerId:n,envelope:r,token:i,now:a}=t,o=Tn(e);if(!o)return null;let s=xn({to:r.signer.email,signerName:r.signer.name,title:r.title,sender:En(e,t.senderSetting),link:`${o}/sign/${i}`,expiresAt:r.expiresAt});return
|
|
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 Cn=`outbox-drain`;function wn(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 Tn(e){try{let{origin:t}=new URL(e.site.url);return t===`null`?``:t}catch{return``}}const En=(e,t)=>typeof t==`string`&&t.trim()!==``?t.trim():e.site.name,Dn=`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 On(e,t){let{signerId:n,envelope:r,token:i,now:a}=t,o=Tn(e);if(!o)return null;let s=xn({to:r.signer.email,signerName:r.signer.name,title:r.title,sender:En(e,t.senderSetting),link:`${o}/sign/${i}`,expiresAt:r.expiresAt});return st(wn(e),s,a,()=>`invite-${n}`)}async function kn(e,t){let n=Tn(e);if(!n)return null;let r={to:t.envelope.signer.email,signerName:t.envelope.signer.name,title:t.envelope.title,sender:En(e,t.senderSetting),link:`${n}/signed/${t.token}`};return st(wn(e),Sn(r),t.now,()=>`complete-${t.envelopeId}`)}async function An(e,t,n=Date.now()){if(e.name!==Cn)return!1;let r=await lt({storage:wn(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 jn(e){return ut({storage:wn(e),email:e.email,now:Date.now()})}const Mn=`0`.repeat(64);function Nn(e=b){return S(e(32))}function Pn(e,t){return F(e+t)}function Fn(e,t){return`${e}:a${String(t).padStart(6,`0`)}`}const In=e=>Object.keys(e).sort().map(t=>[t,e[t]]);function Ln(e){let t=JSON.stringify([1,e.envelopeId,e.seq,e.type,e.at,e.actor,In(e.data),In(e.commitments)]);return F(e.prevHash+t)}async function Rn(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 Pn(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:Mn};return{...o,personal:i.length>0?Object.fromEntries(i):null,hash:await Ln(o)}}function zn(e,t,n){return Bn(e,null,t,n)}async function Bn(e,t,n,r){let i=[],a=t;for(let t of n){let n=await Rn(e,a,t,r);i.push({id:Fn(e,n.seq),data:n}),a=n}return i}async function Vn(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 Rn(t,i[0]?.data??null,n,r.salt);if((await e.compareAndSet(Fn(t,a.seq),null,a)).applied)return w(a)}return T(`CONFLICT`)}async function Hn(e,t){let{items:n}=await e.query({where:{envelopeId:t},orderBy:{seq:`desc`},limit:1});return n[0]?.data??null}async function Un(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 Wn(e,t){for(let[n,r]of Object.entries(e.personal??{}))if(e.commitments[n]!==await Pn(t,r))return!1;return!0}async function Gn(e,t,n={}){let r=Mn;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 Ln(a)!==a.hash)return t(`HASH`);if(a.prevHash!==r)return t(`PREV_HASH`);if(n.salt!==void 0&&!await Wn(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 Kn(e){return{...e,personal:null}}function qn(e,t){return F(`esign-final/1\n${e}\n${t}`)}const Jn=[`draft`,`sent`,`in_progress`,`completed`,`declined`,`voided`,`expired`],Yn=[`declined`,`voided`,`expired`],Xn=Object.freeze({draft:[`sent`,`voided`],sent:[`in_progress`,`completed`,...Yn],in_progress:[`completed`,...Yn],completed:[],declined:[],voided:[],expired:[]});function Zn(e){return typeof e==`string`&&Jn.includes(e)}function Qn(e,t){return Zn(e)&&Zn(t)&&Xn[e].includes(t)}function $n(e){return Xn[e].length===0}async function I(e,t,n,r,i={}){if(!Qn(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 er(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 tr(e,t){return{...e,status:`version`,templateId:t}}function nr(e,t){let n=er(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:un(n.value.body),createdAt:t.now,updatedAt:t.now};return w({head:r,versions:[{id:L(t.id,1),data:tr(r,t.id)}]})}function rr(e,t,n){if(e.status===`archived`)return T([{path:``,code:`TEMPLATE_ARCHIVED`}]);let r=er(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:un(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:tr(o,n.id)}})}function ir(e,t){return e.status===`archived`?e:{...e,status:`archived`,updatedAt:t}}function ar(e){return e?.status===`active`&&e.integrations===!0}function or(e){return e.status===`active`?w(e):T(`TEMPLATE_NOT_FOUND`)}const sr=/[\u0000-\u001F\u007F]/,cr=/^[^\s@]+@[^\s@]+\.[^\s@]+$/,lr=/^[A-Za-z0-9_]{1,64}$/,ur=(e,t)=>`${e}:s${t}`,dr=e=>typeof e==`object`&&!!e&&!Array.isArray(e),fr=e=>typeof e==`string`&&e.length>0&&e.length<=200&&!e.includes(`:`);function pr(e){let t=typeof e==`string`?e.trim():``;return t.length>0&&t.length<=200&&!sr.test(t)?t:null}function mr(e){let t=typeof e==`string`?e.trim().toLowerCase():``;return t.length<=254&&cr.test(t)?t:null}function hr(e){if(e===void 0)return{};if(!dr(e))return null;let t=Object.entries(e);if(t.length>32)return null;let n={};for(let[e,r]of t){if(!lr.test(e)||typeof r!=`string`||[...r].length>500)return null;n[e]=r}return n}function gr(e){if(e===void 0)return[];if(!Array.isArray(e)||e.length>16)return null;let t=[];for(let n of e){if(!dr(n)||typeof n.key!=`string`||!lr.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||sr.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 _r(e){if(!dr(e))return T([{path:``,code:`INVALID_INPUT`}]);let{templateId:t,templateVersion:n,title:r,signer:i,fields:a}=e,o=[];fr(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&&!sr.test(s))&&o.push({path:`title`,code:`INVALID_TITLE`});let c=dr(i)?i:{},l=pr(c.name),u=mr(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=hr(a);d===null&&o.push({path:`fields`,code:`INVALID_FIELDS`});let f=gr(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 vr(e,t,n){let r=e?or(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 yr(e){let{signer:t}=e;return{...e.fieldValues,"signer.name":t.name,"signer.email":t.email,...t.participant?{"participant.name":t.participant.name}:{}}}function br(e,t){let n=yr(e);return un(t).filter(e=>!Object.hasOwn(n,e)).map(e=>({path:`fields.${e}`,code:`MISSING_FIELD`}))}function xr(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=br(a,t.body);return o.length>0?T(o):w(a)}function Sr(e,t,n){return xr({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 Cr(e,t,n){let r=wr(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 xr({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 wr(e){let{signBy:t,iat:n}=e;return Number.isSafeInteger(t)&&t>n?t:void 0}function Tr(e,t,n){let r=Date.parse(e)+t*864e5;return j(n===void 0?r:Math.min(r,(n+60)*1e3))}function Er(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 Dr(e,t){let n;try{n=dn(t,yr(e))}catch(e){if(e instanceof on)return T([{path:`fields.${e.field}`,code:`MISSING_FIELD`}]);throw e}let r=fn(n);return r.length>131072||Er(r)>1500?T([{path:`body`,code:`DOCUMENT_TOO_LARGE`}]):w({text:r,docSha256:await F(r)})}const Or=e=>e>=55296&&e<=56319;function kr(e,t,n){let r=[];for(let e=0;e<t.length;){let n=Math.min(e+65536,t.length);n<t.length&&Or(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 Ar(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 jr(e,t,n,r){if(!Qn(t.status,`sent`))return T(`ILLEGAL_TRANSITION`);if(n.version!==t.templateVersion)return T(`TEMPLATE_MISMATCH`);let i=await Dr(t,n.body);if(!i.ok)return i;let{text:a,docSha256:o}=i.value,s=kr(e,a,o),c=ur(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:Tr(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 Mr=[`declined`,`voided`,`expired`];function Nr(e){return e.find(e=>!Mr.includes(e.data.status))}async function Pr(e,t,n){return`env_${(await F(`${e}\n${t}`)).slice(0,32)}_${n}`}function Fr(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 Ir(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 Lr(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 Rr={amp:`&`,lt:`<`,gt:`>`,quot:`"`,"#39":`'`},zr=/^&(amp|lt|gt|quot|#39);/,Br=/[!-/:-@[-`{-~]/,Vr=/[\p{L}\p{N}]/u,Hr=/[\s"'<>`\\\u0000-\u001F\u007F]/,Ur=/^(https?:\/\/|mailto:)/i,Wr=new Set([`\\`,`&`,`
|
|
30
|
+
`,"`",`*`,`_`,`[`,`!`,`<`]),Gr=/[\\&\n`*_[!<]/g;function Kr(e){if(!(e.length===0||Hr.test(e)||!Ur.test(e)))try{return new URL(e).href}catch{return}}function qr(e){return e.replace(/\\([!-/:-@[-`{-~])|&(amp|lt|gt|quot|#39);/g,(e,t,n)=>t===void 0?Rr[n]:t)}function Jr(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 Yr=class{partner;memo=new Map;constructor(e){this.src=e,this.partner=Jr(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(!Wr.has(e)){Gr.lastIndex=s;let e=Gr.exec(r),n=e&&e.index<t?e.index:t;a+=r.slice(s,n),s=n;continue}if(e===`\\`&&s+1<t&&Br.test(r[s+1])){a+=r[s+1],s+=2;continue}let c=e===`&`?zr.exec(r.slice(s,Math.min(t,s+6))):null;if(c){a+=Rr[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:qr(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&&Vr.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:qr(i.slice(e+1,o)),end:c};let l=Kr(qr(i.slice(o+2,s)));return l?{inline:{type:`link`,href:l,children:this.parse(e+1,o,n+1)},end:c}:{text:qr(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?Kr(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 Xr(e){return new Yr(e).parse(0,e.length,0)}const Zr=/^ {0,3}(`{3,}|~{3,})/,Qr=/^ {0,3}(#{1,6})(?:[ \t]+(.*?))?(?:[ \t]+#+)?[ \t]*$/,$r=/^ {0,3}([-*_])(?:[ \t]*\1){2,}[ \t]*$/,ei=/^ {0,3}> ?(.*)$/,ti=/^ {0,3}[-*+][ \t]+(.*)$/,ni=/^ {0,3}(\d{1,9})[.)][ \t]+(.*)$/,ri=e=>e.trim()===``,ii=e=>Zr.test(e)||Qr.test(e)||$r.test(e)||ei.test(e)||ti.test(e)||ni.test(e);function ai(e,t){let n=[],r=0;for(;r<e.length;){let i=e[r];if(ri(i)){r++;continue}let a=Zr.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:qr(o.join(`
|
|
32
|
+
`))});continue}if($r.test(i)){n.push({type:`rule`}),r++;continue}let o=Qr.exec(i);if(o){let e=Math.min(6,o[1].length+1);n.push({type:`heading`,level:e,children:Xr(o[2]??``)}),r++;continue}if(ei.test(i)&&t<4){let i=[];for(;r<e.length&&ei.test(e[r]);)i.push(ei.exec(e[r])[1]),r++;n.push({type:`quote`,children:ai(i,t+1)});continue}let s=ti.test(i),c=ni.exec(i);if(s||c){let t=s?ti:ni,i=[];for(;r<e.length;){let n=e[r],a=t.exec(n);if(a)i.push([s?a[1]:a[2]]);else if(!ri(n)&&/^ {2,}\S/.test(n)&&!ii(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=>Xr(e.join(`
|
|
33
|
+
`)))});continue}let l=[i.trim()];for(r++;r<e.length&&!ri(e[r])&&!ii(e[r]);)l.push(e[r].trim()),r++;n.push({type:`paragraph`,children:Xr(l.join(`
|
|
34
|
+
`))})}return n}function oi(e){return ai(e.replace(/\r\n?/g,`
|
|
35
35
|
`).split(`
|
|
36
|
-
`),0)}const
|
|
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=qt(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 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 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 me({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 he({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 O(r))}}catch(n){if(!Li(n)||e>=3)throw n;r=ce(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 Vn(B(e).audit_events,t,r,{salt:n.piiSalt})).ok)throw Error(`audit chain contention`)}async function Ui(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: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 zn(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(!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=ce(),h=await kr(n,{...s,...await void 0},p.value,{now:A(),tokenHash:await O(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 On(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(!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 Ri(ce(),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,[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&&!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=>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 jn(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||!Tn(e))return!1;let s=await Ri(ce(),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 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 ia(e){if(typeof e!=`string`)return null;let t=new TextEncoder().encode(e.trim());return t.length>=32?t:null}const aa=`intent-finish-`,oa=e=>`${aa}${e}`;function sa(e,t,n){return e?.schedule(oa(t),{schedule:A(n),data:{envelopeId:t}})}async function ca(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 la(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=ia(f.integrationMasterKey);if(!m)return`skipped`;let h=await ca(m,t),g=await kr(t,c,p.value,{now:A(n),tokenHash:await O(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 On(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 zn(t,v,c.piiSalt)),(await I(r,t,`draft`,`sent`,g.value.envelope)).ok?`sent`:`skipped`}async function ua(e,t){if(!e.name.startsWith(aa))return!1;let n=e.data?.envelopeId;return typeof n==`string`&&n.length>0&&await la(t,n,Date.now()),!0}const da=`nonce-sweep`,fa=`nonce-sweep-more`;async function pa(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(fa,{schedule:A(r+6e4)}),{deleted:s,more:c}}async function ma(e,t){if(e.name!==da&&e.name!==fa)return!1;let n=t.storage.nonces;return await pa({nonces:n,cron:t.cron,now:Date.now()}),!0}const ha=`retention`,ga=`retention-more`,_a=`cron:retention`,va=e=>e.status===`sent`||e.status===`in_progress`,ya=e=>va(e)?null:Date.parse(e.completedAt??e.closedAt??e.updatedAt),ba=(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 xa(e,t){let n=new Date(t);n.setUTCMonth(n.getUTCMonth()-ba(e,`retentionPersonalDataMonths`,12,120));let r=new Date(t);return r.setUTCFullYear(r.getUTCFullYear()-ba(e,`retentionSignedRecordsYears`,7,50)),{p:Math.max(n.getTime(),r.getTime()),r:r.getTime()}}function Sa(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 Ca(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 wa(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 Ta(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:Sa(e,t)}]:[]});s.length>0&&await e.signers.putMany(s),i.length>0&&await e.envelopes.putMany(i.map(e=>({id:e.id,data:Ca(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 Ea(e,t){let n=B(e),r={...await e.kv.get(_a)},i=!1;if(!r.phase||r.phase===`rl`)(await Xt(e.kv,t,3)).more?r.phase=`rl`:Object.assign(r,xa(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)&&(ya(e)??i)<i),c=s.length===0;if(!r.step&&s.length>0){if(e)r.acursor=await wa(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 Ta(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(_a,r),i||await e.cron?.schedule(ga,{schedule:A(t)}),i}async function Da(e,t,n=Date.now()){return e.name!==ha&&e.name!==ga?!1:(await Ea(t,n),!0)}const Oa=e=>va(e)||e.status===`completed`&&!e.pdfSha256;async function ka(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=>!Oa(e.data)&&!e.data.personalPurgedAt),open:r.filter(e=>Oa(e.data)).length}}async function Aa(e,t,n){let r=B(e),i=await wa(r,t.due);if(i&&=await wa(r,t.due,i),i)throw Error(`audit trail too long for one request`);await Ta(r,t.due,n),await r.outbox.deleteMany(t.due.flatMap(e=>[`complete-${e.id}`,...e.data.signerIds.map(e=>`invite-${e}`)]))}const ja=new Set([`localhost`,`127.0.0.1`,`[::1]`]);function Ma(e=b){return x(e(32))}const Na=e=>ia(e)===null;function Pa(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:`&&ja.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 Fa(e,t,n){let r=ia(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=gt(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:mt(a,await ht(r,a))}}async function Ia(e,t,n){return(await e.updateIf(t,{where:{revokedAt:null},set:{revokedAt:n}})).applied}async function La(e){return(await e.query({orderBy:{createdAt:`desc`},limit:100})).items.map(e=>e.data)}function Ra(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 za(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 Ba=e=>e.storage.templates,W=e=>({...D(`BAD_REQUEST`).body,...e?{issues:e}:{}}),Va=()=>D(`TEMPLATE_NOT_FOUND`).body;function Ha(e){let t=V(e).id;return typeof t==`string`&&t.length>0&&t.length<=200&&!t.includes(`:`)?t:null}const Ua=(e,t)=>({id:e,...t}),Wa=(e,{body:t,...n})=>({id:e,...n});async function Ga(e,t){let n=await Ba(e).get(t);return n&&n.status!==`version`?n:null}const Ka={"templates/create":{handler:(async(e,t)=>{let n=crypto.randomUUID(),r=nr(e.input,{id:n,now:A()});if(!r.ok)return W(r.error);let{head:i,versions:a}=r.value;return await Ba(t).putMany([{id:n,data:i},...a]),{ok:!0,template:Ua(n,i)}})},"templates/update":{handler:(async(e,t)=>{let n=Ha(e.input);if(!n)return W();let r=await Ga(t,n);if(!r)return Va();let i=rr(r,e.input,{id:n,now:A()});return i.ok?(await Ba(t).putMany([{id:n,data:i.value.head},i.value.version]),{ok:!0,template:Ua(n,i.value.head)}):W(i.error)})},"templates/get":{handler:(async(e,t)=>{let n=Ha(e.input);if(!n)return W();let r=V(e.input).version;if(r!==void 0&&!(Number.isSafeInteger(r)&&r>=1))return W();let i=r,a=await Ba(t).getMany(i===void 0?[n]:[n,L(n,i)]),o=a.get(n);if(!o||o.status===`version`)return Va();let s=i===void 0?o:a.get(L(n,i));if(!s)return Va();let c=Array.from({length:o.version},(e,t)=>t+1);return{ok:!0,template:Ua(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 W();let{items:r}=await Ba(t).query({where:{status:n},limit:200});return{ok:!0,templates:r.map(e=>Wa(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=Ha(e.input);if(!n)return W();let r=await Ga(t,n);if(!r)return Va();if(r.status===`archived`)return{ok:!0,template:Ua(n,r)};let i=ir(r,A());return await Ba(t).putMany([{id:n,data:i}]),{ok:!0,template:Ua(n,i)}})}},qa=(e,t)=>({severity:`error`,title:e,...t?{message:t}:{}}),Ja=e=>B(e.ctx).clients;async function Ya(e){return(await e.ctx.settings.list()).find(e=>e.key===`integrationMasterKey`)?.value}const Xa=e=>typeof e==`string`&&e.trim()!==``;function Za(e,r,o=[]){let s=ia(e)!==null,c=typeof e==`object`&&!!e,l=Ra(null).banner;return K([t(`Integrations`),...u([c&&l&&{severity:`error`,title:`Encryption key missing`,message:l.message},!s&&!c&&{severity:`warning`,title:Xa(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||Xa(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.`}),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 G(e,t,n=[]){return Za(t,await La(Ja(e)),n)}async function Qa(e){let[t,n]=await Promise.all([Ya(e),La(Ja(e))]);return Za(t,n)}async function $a(e){let t=await Ya(e);if(Xa(t))return G(e,t,u([qa(`Key already set`,`Changing it would re-pair every client.`)]));let n=Ma();try{await e.ctx.settings.set(`integrationMasterKey`,n)}catch(n){if(!za(n))throw n;return G(e,t,u([qa(`Encryption key missing`,Ra(null).banner?.message)]))}return G(e,n,u([{severity:`info`,title:`Master key generated`}]))}async function eo(e,t){let n=await Ya(e),r=(e,t)=>typeof e==`string`?e.slice(0,t):``,i=Pa(r(t.returnUrlAllowlist,2e3));if(!i.ok)return G(e,n,u([qa(`Not created`,`Return URL not allowed: ${i.entry.slice(0,200)}`)]));let a=await Fa(Ja(e),{name:r(t.name,200),returnUrlAllowlist:i.entries,masterKey:n},{now:A(e.now)});return a.ok?G(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})]):G(e,n,u([qa(`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 to(e,t){let n=await Ia(Ja(e),t,A(e.now));return G(e,await Ya(e),u([n?{severity:`info`,title:`Client revoked`}:qa(`Not revoked`,`Unknown or already revoked.`)]))}const K=e=>({blocks:e}),q=(e,t=200)=>typeof e==`string`?e.trim().slice(0,t):``,J=(e,t,n)=>t.handler({input:n,user:e.user??null},e.ctx),no=e=>Yi[e],ro=e=>Ka[e],io={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 Y(e,t=`The change was refused.`){let n=Array.isArray(e.issues)?e.issues:[];return n.length>0?n.map(e=>io[e.code??``]??`${e.path??`input`} (${e.code??`invalid`})`).join(` `):e.error?.message??t}const ao=(e,t,n)=>({severity:e,title:t,...n?{message:n}:{}}),X=(e,t)=>ao(`error`,e,t),oo=(e,t)=>ao(`warning`,e,t),so=(e,t)=>f(e,t,{style:`secondary`}),Z=(e,t)=>ao(`info`,e,t),co=()=>so(`envelopes.back`,`Back to envelopes`),lo=()=>so(`templates.back`,`Back to templates`),uo=e=>f(`envelope.open`,`Open envelope`,{value:e}),fo={"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`},po=e=>!Tn(e.ctx)&&oo(`Set the site URL`,Dn);async function mo(e){let t=await jn(e.ctx);return[po(e),t.state===`no_transport`&&oo(`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&&oo(`${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 ho(e,r,o=[],s){let c=Zn(r)?r:``,[l,d]=await Promise.all([J(e,no(`envelopes/list`),{...c?{status:c}:{},...s?{cursor:s}:{}}),mo(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 K([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(go),y({fields:[m(`subject`,`Signer email or envelope id`)],submit:{label:`Find`,actionId:`retention.preview`}})])}const go=`Delete personal data`;async function _o(e,n,r){let i=await ka(e.ctx,n),a=i.due.length;return r&&a>0&&await Aa(e.ctx,i,e.now),K([t(go),...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`,go,{style:`danger`,value:n,confirm:{title:`${go}?`,text:`This cannot be undone.`,confirm:`Delete`,deny:`Keep`,style:`danger`}})]:[],co()])])}async function vo(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 Q(e,o,s={}){let{envelopes:c,signers:l,audit_events:m}=B(e.ctx),h=s.envelope??await c.get(o);if(!h)return K([t(`Envelope`),...u([X(`Envelope not found`,`It may have been removed.`)]),d([co()])]);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`?vo(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`}}),co()].filter(e=>e!==!1);return K([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&&po(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:fo[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 J(e,no(`envelopes/send`),{id:n})}catch{return K([t(`Envelope`),...u([X(`The envelope was sent but the invitation could not be queued`,`Open the envelope and use Resend invitation.`)]),d([uo(n)])])}if(r.ok!==!0)return K([t(`Envelope`),...u([X(`Not sent`,Y(r))]),d([uo(n),co()])]);let i=r.invitation===`SITE_URL_MISSING`;return K([t(`Envelope`),...u([i?{severity:`warning`,title:`Envelope sent, but no invitation was queued`,message:Dn}:Z(`Envelope sent`,`The signer's invitation is queued.`)]),d([uo(n),co()])])}async function bo(e,t){let n=await J(e,no(`envelopes/void`),{id:t});if(n.ok!==!0){let r=n.error?.code===`ENVELOPE_CLOSED`;return Q(e,t,{extra:u([X(r?`This envelope cannot be voided`:`Not voided`,r?`It is already completed, declined, voided or expired.`:Y(n))])})}return Q(e,t,{envelope:n.envelope,invite:`n/a`,extra:u([Z(`Voided`,`The signer can no longer sign this envelope.`)])})}async function xo(e,t){let n=await J(e,no(`envelopes/resend`),{id:t});return n.ok===!0?Q(e,t,{envelope:n.envelope,invite:`queued`,signers:n.signers,extra:u([Z(`Invitation queued`,`A new email with a new signing link is on its way.`)])}):Q(e,t,{extra:u([n.error?.code===`INVITATION_QUEUED`?Z(`Already queued`,`The invitation is queued or was sent.`):X(`Not resent`,Y(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 J(e,ro(`templates/get`),{id:r}),o=a.template;return a.ok!==!0||!o?K([t(`New envelope`),...u([X(`Template not found`)]),...i]):K([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([lo()])])}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 K(u([X(`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=q(n.title),o=wo(n.signerFields),s=await J(e,no(`envelopes/create`),{templateId:r,...a?{title:a}:{},signer:{name:q(n.signerName),email:q(n.signerEmail)},fields:i,...o.length>0?{signerFields:o}:{}});if(s.ok!==!0)return Co(e,r,u([X(`Not saved`,Y(s))]));let c=s.envelope.id;return Q(e,c,{extra:u([Z(`Draft created`,`Check the details, then send it.`)])})}async function Eo(e,r=[]){let o=((await J(e,ro(`templates/list`),{})).templates??[]).map(e=>({name:e.name,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 K([t(`Templates`),...r,a({columns:[i(`name`,`Name`),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(un(e).map(e=>[e,`«${e}»`]));try{return dn(e,t)}catch{return e}}function ko(e,r,i=[]){let a=String(r.body??``),s=un(a);return K([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.`),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`}}),lo()])])}async function Ao(e,t,n=[]){let r=await J(e,ro(`templates/get`),{id:t});return r.ok!==!0||!r.template?Eo(e,u([X(`Template not found`)])):ko(t,r.template,n)}async function jo(e,t){let n=await J(e,ro(`templates/create`),{name:q(t.name),body:typeof t.body==`string`?t.body:``,...q(t.description,1e3)?{description:q(t.description,1e3)}:{},integrations:t.integrations===!0});return n.ok===!0?Eo(e,u([Z(`Template created`)])):Eo(e,u([X(`Not saved`,Y(n))]))}async function Mo(e,t,n){let r=t?.startsWith(`template:`)?t.slice(9):``;if(!r)return K(u([X(`Choose a template first`)]));let i={name:q(n.name),body:typeof n.body==`string`?n.body:``,description:q(n.description,1e3),integrations:n.integrations===!0},a=await J(e,ro(`templates/update`),{id:r,...i});return a.ok===!0?ko(r,a.template,u([Z(`Saved`)])):ko(r,{...i,version:`?`},u([X(`Not saved`,Y(a))]))}async function No(e,t){let n=await J(e,ro(`templates/archive`),{id:t});return Eo(e,u([n.ok===!0?Z(`Template archived`):X(`Not archived`,Y(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=Ra(null).banner;return K([t(`Settings`),...u([a&&o&&{severity:`error`,title:`Encryption key missing`,message:o.message},r.integrationMasterKey===`unset`&&oo(`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=q(r,e.kind===`long`?2e3:200);o!==n[e.key]&&i.push([e.key,o])}let o=Fo.filter(e=>q(t[e.key],500)!==``);if(o.some(e=>e.key===`integrationMasterKey`&&Na(q(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([X(`Not saved`,a.join(` `))]));if(i.length+o.length>6)return Lo(n,r,u([X(`Too many changes at once`,`Save at most 6 settings at a time.`)]));if(i.length+o.length===0)return Lo(n,r,u([Z(`Nothing to save`)]));let s={...n},c={...r};try{for(let n of o)await e.ctx.settings.set(n.key,q(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(!za(e))throw e;let t=Ra(null).banner;return Lo(n,r,u([{severity:`error`,title:`Encryption key missing`,message:t?.message}]))}return Lo(s,c,u([Z(`Saved`)]))}const Vo=e=>q(e,200);async function Ho(e,t){if(t.type===`page_load`)switch(t.page){case`/envelopes`:return ho(e,``);case`/templates`:return Eo(e);case`/settings`:return zo(e);case`/integrations`:return Qa(e);default:return K(u([X(`Page not found`)]))}if(t.type===`form_submit`){let n=t.values;switch(t.action_id){case`envelopes.filter`:return ho(e,q(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 eo(e,n);case`retention.preview`:return _o(e,q(n.subject),!1)}}else{let n=Vo(t.value);if(t.action_id.startsWith(`envelopes.page:`))return ho(e,t.action_id.slice(15),[],q(t.value,500)||void 0);if(t.action_id.startsWith(`audit.page:`))return Q(e,Vo(t.action_id.slice(11)));switch(t.action_id){case`envelopes.back`:case`envelopes.page`:return ho(e,``);case`envelope.open`:return Q(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 _o(e,n,!0);case`envelope.new`:return Co(e,n);case`integrations.generate-key`:return $a(e);case`client.revoke`:return to(e,n);case`clients.page`:return Qa(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 K(u([X(`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 We(`receipt`,s).ok?s:void 0}async function qo(e,t,n){let r=Ko(e,t);return r?ot(`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=ia(t.integrationMasterKey);if(!(!a||!i))return{secret:await ht(a,n),revoked:i.revokedAt!==void 0&&i.revokedAt!==null,returnUrlAllowlist:Jo(i.returnUrlAllowlist)}}}}async function Xo(e,t,n){let r=ia(n);if(!(!r||!t.clientId))return qo(e,t,await ht(r,t.clientId))}async function Zo(e,t,n=Date.now()){let r=await at({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=>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 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(!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=ns(e.strokes);return r.ok?w({kind:`drawn`,...n===void 0?{}:{typedName:n},strokes:r.value}):r}function is(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`&&$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=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 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=()=>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 _s(e,t){let{items:n}=await B(e).signers.query({where:{tokenHash:await O(t)},limit:1}),r=n[0];return r&&await ue(t,r.data.tokenHash)?r:null}async function vs(e,t){let{items:n}=await B(e).signers.query({where:{copyTokenHash:await O(t)},limit:1}),r=n[0];return r?.data.copyTokenHash&&await ue(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,Ts=(e,t)=>e.signerIds.length>1?t.order:void 0;async function Es(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 Ds(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 U(`SIGNING_TOKEN_EXPIRED`);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,_=Ts(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 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 Os(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 U(`SIGNING_TOKEN_EXPIRED`);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 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 xi(t.cron,u,Date.parse(f)),{ok:!0,status:`completed`,completedAt:f,...await xs(u,C.value,p.masterKey)}}async function ks(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(!Qn(l.status,`declined`))return U(`ENVELOPE_CLOSED`);let u=A();if(ws(l,u))return U(`SIGNING_TOKEN_EXPIRED`);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 Es(t,c,l.piiSalt,ds({at:u,docSha256:l.docSha256,hasReason:i!==void 0,who:f,order:Ts(l,s.data)})),{ok:!0,status:`declined`,...await xs(c,d.value,await bs(t,d.value))}}const As=e=>(t,n)=>e(t,n),js=(e=>({"public/session":As(Ds),"public/submit":As((t,n)=>Os(t,n,e)),"public/decline":As(ks)}))();function Ms(e){try{return new URL(e.site.url).origin}catch{return}}async function Ns(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 nt({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:Ms(t)});if(!d.ok)return U(d.error);let f=d.value,p=u.settings();if(f.replace===!0)return Is(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=ce(n.random),C=await O(S),w=async e=>{let t=await Mr(f.cid,f.ref,e);return{id:t,sent:await kr(t,y.value,_.value,{now:i,tokenHash:C,expiryDays:Ii(p.expiryDays)})}},T=await w(1);if(!T.sent.ok)return Array.isArray(T.sent.error)?H(T.sent.error):U(`INTERNAL`);let ee=await a.compareAndSet(T.id,null,T.sent.value.envelope);if(!ee.applied){let e=await a.query({where:{clientId:f.cid,externalRef:f.ref},limit:100}),i=jr(e.items);if(i)return i.data.status===`draft`&&await sa(t.cron,i.id,r),Fs(o,i.id,i.data,b,n.random,x);let s=Math.max(e.items.length,1)+1;if(y.value.delivery===`email`){let e=await Mr(f.cid,f.ref,s);if(!(await a.compareAndSet(e,null,y.value)).applied){let t=await a.get(e);return t?Fs(o,e,t,b,n.random):U(`INTERNAL`)}return await sa(t.cron,e,r),$(e,y.value,void 0)}if(T=await w(s),!T.sent.ok)return Array.isArray(T.sent.error)?H(T.sent.error):U(`INTERNAL`);if(ee=await a.compareAndSet(T.id,null,T.sent.value.envelope),!ee.applied){let e=await a.get(T.id);return e?Fs(o,T.id,e,b,n.random):U(`INTERNAL`)}}let{id:te,sent:E}=T;if(!E.ok)return U(`INTERNAL`);await s.putMany(E.value.chunks);let ne=await zi(o,E.value.signer,S,n.random);E.value.envelope.delivery===`email`&&await On(t,{signerId:E.value.signer.id,envelope:E.value.envelope,token:ne,senderSetting:p.senderName,now:r});let D=[Nr(y.value,`integration`),Pr(E.value.envelope,`integration`)];return await B(t).audit_events.putMany(await zn(te,D,v)),$(te,E.value.envelope,ne)}function $(e,t,n,r=t.delivery===`inline`){return{ok:!0,envelopeId:e,status:t.status,...n!==void 0&&r?{signingToken:n}:{}}}function Ps(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 Fs(e,t,n,r,i,a){let o=n.signerIds[0],s=(n.status===`sent`||n.status===`in_progress`)&&Ps(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(ce(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 Is(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 Ls=(e,t)=>Ns(e.input,t),Rs=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:Rs},{name:`public/self-serve/start`,methods:[`POST`],body:`json`,maxBytes:Rs}];async function Bs(){return D({code:`NOT_FOUND`}).body}function Vs(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]??Bs};return t}const Hs=e=>Number(/_(\d+)$/.exec(e)?.[1]??0);function Us(e){let t;for(let n of e)(!t||Hs(n.id)>Hs(t.id)||Hs(n.id)===Hs(t.id)&&n.data.createdAt>t.data.createdAt)&&(t=n);return t}async function Ws(e,t,n=Date.now()){let r=Yo(t),i=await it({token:V(e).request,now:n,getClient:r.getClient});if(!i.ok)return U(i.error);let{cid:a,ref:o}=i.value,s=Us((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 Xo(s.id,s.data,r.settings().integrationMasterKey);return c?{ok:!0,state:`terminal`,receipt:c}:U(`INTERNAL`)}const Gs=(e,t)=>Ws(e.input,t),Ks=/^[0-9a-f]{64}$/,qs=async(e,t)=>{let n=V(e.input).sha256,r=typeof n==`string`?n.toLowerCase():``;if(!Ks.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}},Js=[{name:Cn,schedule:`* * * * *`},{name:da,schedule:`0 * * * *`},{name:ha,schedule:`23 3 * * *`},{name:ta,schedule:`17 * * * *`}],Ys=Vs({"public/envelopes/from-intent":Ls,"public/download":Ni,"public/verify":qs,"public/receipts/lookup":Gs,"public/templates/catalog":Qo,...js}),Xs={hooks:{"plugin:activate":async(e,t)=>{await en(t,Js)},cron:async(e,t)=>{await nn(e,t,Js,Date.now())||await An(e,t)||await ea(e,t)||await ua(e,t)||await ma(e,t)||await Da(e,t)||await ra(e,t)||await Ci(e,t)}},routes:{...Ys,...Uo,...Ka,...Yi,admin:an(Uo.admin,rn),"templates/create":an(Ka[`templates/create`]),"public/verify":an(Ys[`public/verify`])}};export{Xs as default};
|
|
36
|
+
`),0)}const si=262144/4*3,ci={self:`Self`,guardian:`Parent or guardian`,buyer:`Buyer`},li=e=>e?`${e.slice(0,10)} ${e.slice(11,19)} UTC`:``;function ui(e){return e.map(e=>{switch(e.type){case`text`:case`code`:return e.text;case`break`:return`
|
|
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};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@semics-tech/emdash-esign",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.mjs",
|
|
6
6
|
"exports": {
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"emdash": "1.2.0",
|
|
47
47
|
"typescript": "^5.9.0",
|
|
48
48
|
"vitest": "^4.1.12",
|
|
49
|
-
"@semics-tech/shared": "0.1.0-rc.
|
|
49
|
+
"@semics-tech/shared": "0.1.0-rc.2"
|
|
50
50
|
},
|
|
51
51
|
"description": "Simple electronic signatures for EmDash",
|
|
52
52
|
"license": "MIT",
|